Nginx Web サーバーのセキュリティを確保、強化し、パフォーマンスを向上させるための究極のガイド
Nginx について聞いた素晴らしいことに基づいて、おそらくあなたはそれを試してみることにしました。このサイトで公開したこのトピックに関する記事をいくつか読んだ後、Apache インストールを Nginx に置き換えることを検討している方もいるかもしれません。
もしそうなら、このガイドでは、Nginx サーバーのセキュリティを強化するための 12 のヒント (Nginx を最新の状態に保つことから、 TLS の使用と HTTP から HTTPS へのリダイレクト)、それらのいくつかは Apache で行うことと非常によく似ていることに気づくでしょう。
お見逃しなく:
13 Apache Web サーバーのセキュリティと強化のヒント
Apache Web サーバーを保護するための 25 の Apache Htaccess トリック
Nginx テスト環境
このガイドでは次の環境を使用します。
- Debian GNU/Linux 8.1 (ジェシー)。
-
IP アドレス: 192.168.0.25 (tecmintlovesnginx.com) および 192.168.0.26 (nginxmeanspower.com) (IP ベースの仮想で説明)ホストセクション
- 「Nginx で名前ベースおよび IP ベースの仮想ホスト (サーバー ブロック) をセットアップする方法」
それを念頭に置いて、始めましょう。
ヒント #1: Nginx を最新の状態に保つ
この記事の執筆時点で、CentOS (EPEL 内) および Debian リポジトリの最新の Nginx バージョンは 1.6.3 および 1.6.2-5 です。strong>、それぞれ。
お見逃しなく: リポジトリとソースから Nginx の最新の安定バージョンをインストールします
リポジトリからソフトウェアをインストールするのは、ソース コードからプログラムをコンパイルするよりも簡単ですが、この最後のオプションには 2 つの利点があります。1) Nginx に追加のモジュール (mod_security など) を構築できる、2) 常に新しいバージョンが提供されるリポジトリ (今日現在1.9.9) よりも優れています。リリース ノートは、Nginx Web サイトでいつでも入手できます。
お見逃しなく:
Mod_Security と Mod_Evasive を使用して Apache をブルート フォース攻撃と DDoS 攻撃から保護する
ヒント #2: Nginx で不要なモジュールを削除する
ソースからインストールするときに Nginx からモジュールを明示的に削除するには、次の手順を実行します。
./configure --without-module1 --without-module2 --without-module3
例えば:
./configure --without-http_dav_module --withouthttp_spdy_module
おそらくご想像のとおり、以前の Nginx インストールからモジュールをソースから削除するには、コンパイルを再度実行する必要があります。
注意: 構成ディレクティブはモジュールによって提供されます。将来必要になるディレクティブを含むモジュールを無効にしないように注意してください。モジュールを無効にする決定を下す前に、nginx ドキュメントで各モジュールで使用可能なディレクティブのリストを確認する必要があります。
ヒント#3: Nginxでserver_tokensディレクティブを無効にする
server_tokens
ディレクティブは、Nginx に現在のバージョンをエラー ページに表示するように指示します。特定のバージョンの既知の脆弱性によって引き起こされる Web サーバーへの攻撃を防ぐためにその情報を世界と共有したくないため、これは望ましくありません。
server_tokens
ディレクティブを無効にするには、server ブロック内で if を off に設定します。
server {
listen 192.168.0.25:80;
server_tokens off;
server_name tecmintlovesnginx.com www.tecmintlovesnginx.com;
access_log /var/www/logs/tecmintlovesnginx.access.log;
error_log /var/www/logs/tecmintlovesnginx.error.log error;
root /var/www/tecmintlovesnginx.com/public_html;
index index.html index.htm;
}
nginx を再起動し、変更を確認します。
ヒント #4: Nginx で HTTP ユーザー エージェントを拒否する
HTTP ユーザー エージェントは、Web サーバーに対するコンテンツ ネゴシエーションに使用されるソフトウェアです。これには、システム リソースを浪費して Web サーバーのパフォーマンスに影響を与える可能性のあるマルウェア ボットやクローラーも含まれます。
不要なユーザー エージェントのリストをより簡単に管理するには、次の内容のファイル (/etc/nginx/blockuseragents.rules
など) を作成します。
map $http_user_agent $blockedagent {
default 0;
~*malicious 1;
~*bot 1;
~*backdoor 1;
~*crawler 1;
~*bandit 1;
}
次に、サーバー ブロック定義の前に次の行を配置します。
include /etc/nginx/blockuseragents.rules;
ユーザー エージェント文字列が上で定義したブラック リストに含まれる場合に 403 応答を返す if ステートメント:
nginx を再起動すると、上記の文字列と一致するすべてのユーザー エージェントは Web サーバーへのアクセスをブロックされます。 192.168.0.25 をサーバーの IP に置き換え、wget の --user-agent
スイッチに別の文字列を自由に選択してください。
wget http://192.168.0.25/index.html
wget --user-agent "I am a bandit haha" http://192.168.0.25/index.html
ヒント #5: Nginx で不要な HTTP メソッドを無効にする
動詞としても知られる HTTP メソッドは、Nginx によって提供されるリソースに対して実行される必要なアクションを示します。一般的な Web サイトとアプリケーションの場合は、GET、POST、HEAD のみを許可し、その他はすべて無効にする必要があります。
これを行うには、次の行をサーバー ブロック内に配置します。 444 HTTP 応答は空の応答を意味し、Nginx でマルウェア攻撃を欺くためによく使用されます。
if ($request_method !~ ^(GET|HEAD|POST)$) {
return 444;
}
テストするには、curl を使用して DELETE リクエストを送信し、通常の GET を送信したときの出力と比較します。
curl -X DELETE http://192.168.0.25/index.html
curl -X POST http://192.168.0.25/index.html
ヒント #6: Nginx でバッファ サイズ制限を設定する
Nginx Web サーバーに対するバッファ オーバーフロー攻撃を防ぐには、別のファイルに次のディレクティブを設定します (たとえば、/etc/nginx/conf.d/buffer.conf
という名前の新しいファイルを作成します)。
client_body_buffer_size 1k;
client_header_buffer_size 1k;
client_max_body_size 1k;
large_client_header_buffers 2 1k;
上記のディレクティブにより、Web サーバーに対するリクエストによってシステムでバッファ オーバーフローが発生しないことが保証されます。それぞれの機能の詳細については、もう一度ドキュメントを参照してください。
次に、構成ファイルに include ディレクティブを追加します。
include /etc/nginx/conf.d/*.conf;
ヒント #7: Nginx で IP ごとに接続数を制限する
IP によって接続を制限するには、limit_conn_zone
(http コンテキスト内、または少なくともサーバー ブロックの外側) および limit_conn (http、サーバー ブロック、またはロケーション コンテキスト内) ディレクティブを使用します。
ただし、すべての接続がカウントされるわけではなく、サーバーによってリクエストが処理され、そのリクエスト ヘッダー全体が読み取られた接続のみがカウントされることに注意してください。
たとえば、addr という名前のゾーンで最大接続数を 1
に設定してみましょう (はい、大げさですが、この場合は問題なく機能します) (これは任意に設定できます)ご希望の名前):
limit_conn_zone $binary_remote_addr zone=addr:5m;
limit_conn addr 1;
Apache Benchmark を使用した簡単なテスト (Nginx Load の実行) で、合計 10
個の接続が 2
個の同時リクエストで行われると、この点を実証するのに役立ちます。
ab -n 10 -c 2 http://192.168.0.25/index.html
詳細については、次のヒントを参照してください。
ヒント #8: Nginx のセットアップ モニター ログ
前のヒントで説明したテストを実行したら、サーバー ブロックに定義されているエラー ログを確認します。
grep を使用して、ヒント #7 で定義されている addr ゾーンに対して行われた失敗したリクエストのログをフィルタリングすることもできます。
grep addr /var/www/logs/tecmintlovesnginx.error.log --color=auto
同様に、アクセス ログをフィルタリングして、次のような関心のある情報を見つけることができます。
- クライアントIP
- ブラウザの種類
- HTTPリクエストタイプ
- 要求されたリソース
- リクエストに応答するサーバー ブロック (複数の仮想ホストが同じファイルにログを記録している場合に便利)。
また、異常なアクティビティや望ましくないアクティビティを検出した場合は、適切な措置を講じてください。
ヒント #9: Nginx での画像のホットリンクを防止する
画像のホットリンクは、あなたのサイトでホストされている画像を別のサイトで表示するときに発生します。これにより、他の人は画像をあたかも自分の所有物であるかのように喜んで表示する一方で、帯域幅の使用量 (料金を支払う) が増加します。言い換えれば、それはあなたにとって二重の損失です。
たとえば、サーバー ブロック内に img
という名前のサブディレクトリがあり、そこに仮想ホストで使用されるすべてのイメージが保存されているとします。他のサイトがイメージを使用しないようにするには、仮想ホスト定義内に次の場所ブロックを挿入する必要があります。
location /img/ {
valid_referers none blocked 192.168.0.25;
if ($invalid_referer) {
return 403;
}
}
次に、各仮想ホストの index.html
ファイルを次のように変更します。
192.168.0.26
192.168.0.25
<!DOCTYPE html>
<html>
<head>
<meta charset=”utf-8″>
<title>Nginx means power</title>
</head>
<body>
<h1>Nginx means power!</h1>
<img src=”http://192.168.0.25/img/nginx.png” />
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset=”utf-8″>
<title>Tecmint loves Nginx</title>
</head>
<body>
<h1>Tecmint loves Nginx!</h1>
<img src=”img/nginx.png” />
</body>
</html>
各サイトを参照すると、ご覧のとおり、192.168.0.25 では画像が正しく表示されますが、192.168.0.26 では 403 応答に置き換えられます。strong>:
このヒントは、Referer フィールドを送信するリモート ブラウザーに依存することに注意してください。
ヒント #10: Nginx では SSL を無効にし、TLS のみを有効にする
可能な限り、どのバージョンでも SSL を回避し、代わりに TLS を使用するようにしてください。次の ssl_protocols
は、仮想ホスト ファイルのサーバーまたは http コンテキストに配置するか、include ディレクティブを介して別のファイルとして配置する必要があります (ssl.conf
という名前のファイルを使用する人もいます)。ただし、それは完全にあなた次第です):
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
例えば:
ヒント #11: Nginx で証明書を作成する
まず、キーと証明書を生成します。必要に応じて、別のタイプの暗号化を自由に使用してください。
openssl genrsa -aes256 -out tecmintlovesnginx.key 1024
openssl req -new -key tecmintlovesnginx.key -out tecmintlovesnginx.csr
cp tecmintlovesnginx.key tecmintlovesnginx.key.org
openssl rsa -in tecmintlovesnginx.key.org -out tecmintlovesnginx.key
openssl x509 -req -days 365 -in tecmintlovesnginx.csr -signkey tecmintlovesnginx.key -out tecmintlovesnginx.crt
次に、次のヒント (http --> https
リダイレクト) に備えて別のサーバー ブロック内に次の行を追加し、SSL 関連のディレクティブも新しいブロックに移動します。
server {
listen 192.168.0.25:443 ssl;
server_tokens off;
server_name tecmintlovesnginx.com www.tecmintlovesnginx.com;
root /var/www/tecmintlovesnginx.com/public_html;
ssl_certificate /etc/nginx/sites-enabled/certs/tecmintlovesnginx.crt;
ssl_certificate_key /etc/nginx/sites-enabled/certs/tecmintlovesnginx.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
}
次のヒントでは、サイトで自己署名証明書と TLS がどのように使用されているかを確認します。
ヒント #12: Nginx で HTTP トラフィックを HTTPS にリダイレクトする
次の行を最初のサーバー ブロックに追加します。
return 301 https://$server_name$request_uri;
上記のディレクティブは、301 (永久に移動) 応答を返します。これは、仮想ホストのポート 80 に対してリクエストが行われるたびに永続的な URL リダイレクトに使用され、リクエストをサーバー ブロックにリダイレクトします。前のヒントに追加されました。
下の画像はリダイレクトを示しており、 暗号化にTLS 1.2 と AES-256 を使用していることを確認しています。
まとめ
この記事では、Nginx Web サーバーを保護するためのいくつかのヒントを共有しました。ぜひご意見をお聞かせください。また、コミュニティの他のメンバーと共有したいその他のヒントがある場合は、以下のコメント フォームを使用してメモを送信してお気軽にお知らせください。