Nginx Webサーバーのパフォーマンスを保護、強化、改善するための究極のガイド


Nginxについて聞いた素晴らしいことを踏まえて、おそらく試してみることにしました。このサイトで公開しているトピックに関するいくつかの記事を読んだ後、ApacheインストールをNginxに置き換えることを検討していることをとても気に入っているかもしれません。

もしそうなら、Nginxサーバーのセキュリティを強化するための12のヒント(Nginxを最新の状態に保つことから、TLSを使用してHTTPをリダイレクトすることまで)をカバーするので、このガイドを両手を広げて歓迎すると確信しています。 HTTPS)、そしてそれらのいくつかはあなたがApacheで行うことと非常に似ていることに気付くでしょう。

お見逃しなく:

このガイドでは、次の環境を使用します。

  1. Debian GNU/Linux 8.1 (jessie).
  2. IP address: 192.168.0.25 (tecmintlovesnginx.com) and 192.168.0.26 (nginxmeanspower.com), as described in the IP-based virtual hosts section at
    1. “How to Setup Name-based and IP-based Virtual Hosts (Server Blocks) with Nginx“

    それを念頭に置いて、始めましょう。

    ヒント#1:Nginxを最新の状態に保つ

    この記事の執筆時点では、CentOS(EPEL内)およびDebianリポジトリの最新のNginxバージョンはそれぞれ1.6.3および1.6.2-5です。

    リポジトリからソフトウェアをインストールするのはソースコードからプログラムをコンパイルするよりも簡単ですが、この最後のオプションには2つの利点があります:1)追加のモジュールをNginxにビルドできる(mod_securityなど)2)常に新しいバージョンを提供するリポジトリよりも(今日の時点で1.9.9)。リリースノートは、NginxWebサイトでいつでも入手できます。

    お見逃しなく:

    ヒント#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 {
        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;
    

    10 の合計接続が 2 の同時リクエストで行われる、Apache Benchmark(Perform Nginx Load)を使用した簡単なテストは、私たちのポイントを示すのに役立ちます。

    # 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
    

    同様に、次のような関心のある情報についてアクセスログをフィルタリングできます。

    1. Client IP
    2. Browser type
    3. HTTP request type
    4. Resource requested
    5. Server block answering the request (useful if several virtual hosts are logging to the same file).

    また、異常または望ましくないアクティビティを検出した場合は、適切なアクションを実行してください。

    ヒント#9:Nginxでの画像のホットリンクを防止する

    画像のホットリンクは、ユーザーが自分のサイトでホストされている画像を別のサイトに表示したときに発生します。これにより、(あなたが支払う)帯域幅の使用量が増加し、他の人は自分の所有物であるかのように画像を喜んで表示します。言い換えれば、それはあなたにとって二重の損失です。

    たとえば、サーバーブロック内に img という名前のサブディレクトリがあり、その仮想ホストで使用されるすべてのイメージを保存するとします。他のサイトがイメージを使用しないようにするには、仮想ホスト定義内に次のロケーションブロックを挿入する必要があります。

    location /img/ {
      valid_referers none blocked 192.168.0.25;
       if ($invalid_referer) {
         return   403;
       }
    }
    

    次に、各仮想ホストの index.html ファイルを次のように変更します。

    次に、各サイトを参照します。ご覧のとおり、画像は192.168.0.25で正しく表示されますが、192.168.0.26では403応答に置き換えられます。

    このヒントは、リファラーフィールドを送信するリモートブラウザによって異なることに注意してください。

    ヒント#10:SSLを無効にし、Nginxで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:HTTPトラフィックをNginxのHTTPSにリダイレクトする

    次の行を最初のサーバーブロックに追加します。

    return 301 https://$server_name$request_uri;
    

    上記のディレクティブは301(永続的に移動)応答を返します。これは、仮想ホストのポート80に要求が行われるたびに永続的なURLリダイレクトに使用され、前のヒントで追加したサーバーブロックに要求をリダイレクトします。

    以下の画像はリダイレクトを示しており、暗号化にTLS1.2とAES-256を使用していることを確認しています。

    概要

    この記事では、NginxWebサーバーを保護するためのいくつかのヒントを共有しました。ご意見をお聞かせください。コミュニティの他のメンバーと共有したい他のヒントがあれば、下のコメントフォームを使用してメモを送信してお知らせください。