はじめに
Webサーバをサイバー攻撃から守るため、強固なセキュリティ設定が求められています。
NGINXセキュリティ設定に必要な項目を、脆弱性診断ツールなどを利用し検証しました。
関連用語のおさらい
NGINX(エンジンエックス)とは
Wikipediaから抜粋
- フリーかつオープンソースなWebサーバである
- 処理性能・高い並行性・メモリ使用量の小ささに焦点を当てて開発されている
- HTTP, HTTPS, SMTP, POP3, IMAPのリバースプロキシの機能を持つ
- ロードバランサ、HTTPキャッシュなどの機能も持つ
脆弱性診断ツール(Vulnerability Scanner、略してVS)とは
Wikipediaから抜粋
- コンピュータの安全性を試すためのプログラム群である
- コンピュータセキュリティ上で、様々な侵入に用いられる攻撃手段をシミュレーションする
- 大抵の場合はパッケージ化され、製品や試作ソフトウェアの評価に用いられる
まず、NGINXのデフォルト設定のまま、脆弱性診断を行ってみます
今回はWeb脆弱性診断ツールとして、OWASP ZAPを使用します。
-
OWASP ZAPをインストール
- 前提として、Java 8以降が必要です
- 以下からダウンロードし、インストールします
-
OWASP ZAPを起動します
-
検証対象のWebサイトに向けて、スキャン実施します(
攻撃
ボタンをクリック)
つぎに、NGINXのセキュリティ設定を行います(nginx.conf
)
Red Hat Enterprise LinuxセキュリティガイドのNGINXのセキュリティ保護
など参考にしながら、
nginx.conf
にセキュリティ項目を追加していきます(設定後は、nginx.conf
のリロードが必要)。
対策1. セキュリティ関連HTTPヘッダーを追加します
既知のWebアプリ脆弱性を緩和するためのヘッダーを追加します。
-
X-Frame-Options SAMEORIGIN
- 目的
- クリックジャッキング攻撃を効果的に軽減します
- 設定
-
server
ブロックにadd_header X-Frame-Options SAMEORIGIN;
を追加します
-
- 目的
-
X-Content-Type-Options nosniff
- 目的
- 特定の古いブラウザーで MIME タイプのスニッフィングを防ぎます
- 設定
-
server
ブロックにadd_header X-Content-Type-Options nosniff;
を追加します
-
- 目的
-
X-XSS-Protection
- 目的
- クロスサイトスクリプティング(XSS)フィルタリングを有効にします
- 設定
-
server
ブロックにadd_header X-XSS-Protection "1; mode=block";
を追加します
-
- 目的
-
Content-Security-Policy
- 目的
- クロスサイトスクリプティング(XSS)やデータインジェクションなどの攻撃を軽減します
- 設定
-
server
ブロックにadd_header Content-Security-Policy "default-src 'self'; frame-ancestors 'none'; form-action 'none'; " always;
を追加します
-
- 目的
設定が効いたか、再度脆弱性診断ツールOWASP ZAP
でスキャンしてみます
今度は、アラートが発生せず、脆弱性診断結果OKになりました。
対策2. NGINXバージョンを隠蔽します
- 目的
- 攻撃者がNGINXバージョンを検知し、バージョン特有の脆弱性を悪用することを防ぎます
- 設定
-
http
ブロックにserver_tokens off;
を追加します
-
- 確認
- バージョン情報が表示されなくなります(設定前:
Server: nginx/1.23.1
)
- バージョン情報が表示されなくなります(設定前:
# curl -sI http://172.20.218.208 | grep Server
Server: nginx
対策3. Etag
を隠蔽します
- 目的
- キャッシュの有効性確認をするために使われる
Etag
値が悪用されることを防ぎます
- キャッシュの有効性確認をするために使われる
- 設定
-
http
ブロックにetag off;
を追加します
-
- 確認
- レスポンスに
Etag
の値が含まれなくなります
- レスポンスに
対策4. 不要なHTTPメソッドを無効にします
- 目的
- HTTPメソッドが攻撃者に悪用されることを防ぐ
- 設定(GET、POSTメソッドのみ許可する例)
if ( $request_method !~ ^(GET|POST)$ ) {
return 403;
}
- 確認
- 許可されていないPUTメソッドでリクエストを発行すると拒否されます
# curl -XPUT http://172.20.218.208
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.23.1</center>
</body>
</html>
対策5. 使用しないNGINXモジュールを削除します
- 目的
- 攻撃者による悪用を防ぐため、使用しないモジュールを削除します
- 設定(例: 使用しない
ngx_http_xxx.so
モジュールをコメントアウトするか削除)
# load_module modules/ngx_http_xxx.so;
- 確認
- 当該モジュールの機能が使用できないことを確認
対策6. 特定ヘッダーが含まれているリクエストのみ許可します
- 目的
- 特定のヘッダーが含まれていないリクエストを拒否し、セキュリティを向上します
- 設定(例: カスタムヘッダー
X-My-Header
を含まないリクエストを拒否)
if ($http_x_my_header = "") {
return 403;
}
- 確認
- カスタムヘッダーX-My-Header
を含まないリクエストは拒否されます
# curl http://172.20.218.208
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.23.1</center>
</body>
</html>
- カスタムヘッダーX-My-Header
を含むリクエストは許可されます
# curl -H "X-My-Header: test" http://172.20.218.208
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
</head>
... ...
<body>
<h1>Welcome to nginx!</h1>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
対策7. クライアントバッファサイズを制限します
- 目的
- バッファオーバーフロー攻撃を防ぐため、クライアントバッファサイズを制限します
- 設定(例: ボディサイズが4KBを超えたら拒否)
client_body_buffer_size 1K;
client_header_buffer_size 1k;
client_max_body_size 4k;
large_client_header_buffers 2 1k;
- 確認
- 準備1: NGINXでは、スタティックページでPOSTが使用できません
-
server
ブロックにerror_page 405 =200 $uri;
を追加し、一時的にPOSTを許可します
-
- 準備2: POSTボディに使用するJSONファイルを二つ用意します
-
small.json
: 1KB -
large.json
: 8KB
-
- 準備1: NGINXでは、スタティックページでPOSTが使用できません
- 4KB未満のJSONファイルをPOSTすると許可されます
# curl -XPOST -H "X-My-Header: test" -H "accept: application/json" -H "Content-
Type: application/json" -d @small.json http://172.20.218.208
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
</head>
... ...
<body>
<h1>Welcome to nginx!</h1>
</body>
</html>
- 4KBを超えるJSONファイルをPOSTすると拒否されます
# curl -XPOST -H "X-My-Header: test" -H "accept: application/json" -H "Content-
Type: application/json" -d @body.json http://172.20.218.208
<html>
<head><title>413 Request Entity Too Large</title></head>
<body>
<center><h1>413 Request Entity Too Large</h1></center>
<hr><center>nginx/1.23.1</center>
</body>
</html>
対策8. 特定のユーザエージェントのみ許可します
- 目的
- 特定のユーザエージェントからのリクエストのみ許可します
- 設定(例:
curl
コマンド経由のリクエストのみ許可)
if ($http_user_agent !~ ^curl.*) {
return 403;
}
- 確認
- curl
コマンドで発行したリクエストは許可されます
# curl -H "X-My-Header: test" http://172.20.218.208
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
</head>
... ...
<body>
<h1>Welcome to nginx!</h1>
</body>
</html>
- ブラウザからWebサイトにアクセスすると403 Forbidden
が発生します
対策9. HTTPSプロトコル(SSL通信)を使用します
- 目的
- NGINX Webサーバが提供するデータおよびその通信経路を保護します
- 設定
- SSL設定を行います
- 確認
- https接続が可能か確認します
おわりに
NGINXのセキュリティ設定を検証してみました。
セキュリティチェックに、脆弱性診断ツールなど使用しました。
ご参考になりましたら幸いです。