Nginxは、デフォルト設定でも非常に安全で信頼できるWebサーバーです。 ただし、Nginxをさらに保護するには多くの方法があります。
この記事では、一般的なWebサーバー強化アプローチとセキュリティ標準に準拠するために、オープンソースソフトウェアのみを使用します。 つまり、情報漏えいの防止、暗号化の強制、監査の実行、アクセスの制限について話します。
前提条件
このチュートリアルを実行する前に、次の前提条件を満たしていることを確認してください。
-
Ubuntu 14.04ドロップレット(詳細については(https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-14-04[Ubuntu 14.04での初期サーバー設定]を参照)
-
Ubuntu 14.04 LTSにNginxをインストールする方法の説明に従ってインストールおよび構成されたNginx Webサーバー
-
DropletのIPを指す登録済みドメインまたはサブドメイン。 これは、SSL設定をテストするために必要になります。 詳細については、https://www.digitalocean.com/community/tutorials/how-to-point-to-digitalocean-nameservers-from-common-domain-registrars [共通ドメインからDigitalOceanネームサーバーをポイントする方法]のこの記事を参照してください。レジストラ]。
-
非ルートsudoユーザー(詳細については、https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-14-04 [Ubuntu 14.04での初期サーバーセットアップ]をご覧ください)
特に断りのない限り、このチュートリアルでルート権限を必要とするすべてのコマンドは、sudo権限を持つ非ルートユーザーとして実行する必要があります。
ステップ1-すべてのソフトウェアの更新
ソフトウェアを最新バージョンに更新することは、Nginxだけでなく、システム全体を保護するための素晴らしい第一歩です。
警告:システム上のすべてのパッケージを更新する前に、これがNginx以外のシステムで実行中の問題で問題を引き起こすかどうかを確認してください。 一度に非常に多くのパッケージに影響する操作を実行する前に、システム全体のバックアップを作成することをお勧めします。 すべてのパッケージを更新した後に問題が発生した場合、バックアップに戻すことができます。 リポジトリパッケージリストを更新し、Ubuntuサーバーで `+ apt-get +`で管理されている現在インストールされているすべてのパッケージを更新するには、次のコマンドを実行します。
sudo apt-get update && sudo apt-get upgrade
または、NginxをUbuntuリポジトリの最新バージョンにアップグレードすることもできます。 これにより、Nginxパッケージと必要な依存関係がアップグレードされます。
sudo apt-get upgrade nginx
ステップ2-情報漏えいの防止
Nginx Webサーバーの強化を開始するには、公開する情報を制限することから始めましょう。 貴重な情報は、HTTPサーバーヘッダーからアプリケーションエラーレポートまで、あらゆるレベルで漏洩します。
それでは、HTTPヘッダーから始めましょう。 デフォルトでは、NginxはHTTPヘッダーに名前とバージョンを表示します。 この情報は、次のように `+ curl +`で確認できます。
curl -I http://localhost
出力は次のようになります。
Output of curl -I http://localhostHTTP/1.1 200 OK
...
ご覧のとおり、Nginxのバージョンとオペレーティングシステムの名前は上記の出力で確認できます。 これは必ずしも深刻な問題ではなく、攻撃者がNginxサーバーを侵害するために解決しようとするパズルの一部です。 そのため、Nginxのメイン設定ファイル「+ / etc / nginx / nginx.conf +」をnanoで次のように開いて、この情報を非表示にします。
sudo nano /etc/nginx/nginx.conf
それから、 `+ http `設定部分の中に ` server_tokens off; +`の行を次のように追加します:
/etc/nginx/nginx.conf
http {
##
# Basic Settings
##
...
その後、ファイルを保存して終了し、Nginxをリロードして変更を有効にします。
sudo service nginx reload
ここで、同じcurlコマンドを再試行すると:
curl -I http://localhost
以下の情報が表示されます。
Output of curl -I http://localhostHTTP/1.1 200 OK
...
上記の出力は、これがNginxサーバーであるという事実のみを開示しています。 これも削除できるのではないかと思うかもしれません。 残念ながら、設定オプションがないため、これは簡単に達成できません。 代わりに、ソースからNginxを再コンパイルする必要がありますが、努力する価値はありません。
+ Server`ヘッダーの他に、機密情報を含む別のヘッダー-
+ X-Powered-By`があります。 このヘッダーは通常、PHP、Tomcat、またはNginxの背後にあるサーバー側エンジンのバージョンを示します。 PHPでNginxを実行すると、 `+ curl +`の出力は次のようになります。
Output of curl -I http://localhost on nginx with phpHTTP/1.1 200 OK
Server: nginx
...
...
上記の「+ X-Powered-By 」ヘッダーは、サーバーがPHPバージョン5.5.9を実行しているUbuntu 14であることを示しています。 ` X-Powered-By `ヘッダーからこの情報を隠すことは非常に重要です。 Nginxでこれを行うことはできませんが、代わりにバックエンドエンジンで対応するオプションを見つける必要があります。 例えば、PHPの場合、メインの ` php.ini `設定ファイルでオプション ` expose_php = Off `を設定する必要があります。 デフォルトでは、このオプションは「 On +」に設定されています。
次に行うことは、4xx(クライアント側)エラーページを変更することです。このページからの情報は、攻撃者によって使用される可能性があります。 通常、これらは「+ Unauthorized 401+」および「+ Forbidden 403+」エラーページです。 問題をデバッグしているのでない限り、通常、通常の訪問者にこれらのエラーを表示する必要はありません。 これらのエラーについて知る必要がある場合、Nginxエラーログ( + / var / log / nginx / error.log +
)でそれらを見つけることができます。
これらの2つのエラーページを変更するには、サーバーブロックの構成ファイルを開きます。たとえば、デフォルトのファイルです。
sudo nano /etc/nginx/sites-enabled/default
メインサーバーの「+ server +」設定部分内で次を指定します。
/ etc / nginx / sites-enabled / default
server {
...
...
ファイルへの変更を保存した後、コマンドで有効になるようにNginxをリロードしてください。
sudo service nginx reload
上記のヒントは、情報漏えいを防ぐアイデアを提供します-重要でないWebコンテンツをできるだけ少なく表示します。 Nginxだけでなく、バックエンドエンジン(PHP、Tomcatなど)、そしてもちろんWebアプリケーションでもサービスとデバッグ情報を非表示にする必要があります。
ステップ2-SSLの構成
NginxでSSLを使用して安全なHTTPSプロトコルを実行することは、ユーザーの資格情報、プライベートデータなどの機密情報を処理するサイトにとって必須です。 SSLは、サイトユーザーがどこにいて、どのインターネット接続を使用していても、ユーザーが送受信する情報が保護されるようにする唯一の手段です。
記事https://www.digitalocean.com/community/tutorials/how-to-create-an-ssl-certificate-on-nginx-for-ubuntu-14-04[NginxでUbuntuのSSL証明書を作成する方法14.04]は、デフォルトのHTTPS設定で無料のSSLを簡単にセットアップする方法を説明しています。 この記事は良い出発点ですが、データを効率的に保護するものではありません。 現在、デフォルトのSSL設定とアルゴリズムは、攻撃者によるトラフィックの復号化を防ぐほど強力ではありません。
そのため、より強力な暗号化アルゴリズムと設定でNginxのSSL証明書を構成します。 これにより、データの保護レベルが高くなり、HTTPSサービスが最高のセキュリティ標準とプラクティスに準拠するようになります。
次のコマンドを使用して、SSL証明書用のディレクトリを作成することから始めましょう。
sudo mkdir /etc/nginx/ssl/
SSLには、強力な署名アルゴリズムSHA256を使用した証明書が必要です。 テスト目的または非実稼働環境では、自己署名証明書を使用して、SSL警告を無視できます。 次のコマンドで作成してみましょう。
sudo openssl req -x509 -nodes -sha256 -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt
このコマンドは、サイトとビジネスの詳細に関するいくつかの簡単な質問をします。 その後、ファイル「+ / etc / nginx / ssl / nginx.key 」に2048ビットのRSA暗号化キーを作成し、ファイル「 / etc / nginx / ssl / nginx.crt +」にSHA256証明書を作成します。
次に、より強力な4096ビット長のhttps://wiki.openssl.org/index.php/Diffie-Hellman_parameters[DH parameters]を生成する必要があります。 しばらく待機する準備をしてください。ドロップレットによっては、最大30分かかる場合があります。 コマンドを実行します。
sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 4096
これで、サーバーブロックのSSL部分を構成できます。 例として、デフォルトのサーバーブロックを設定しましょう。 nanoで編集するためにその構成ファイルを開きます。
sudo nano /etc/nginx/sites-enabled/default
このファイルで、サーバー構成部分を編集して、次のように `+ server_name +`ディレクティブの後にSSL部分を追加します。
/ etc / nginx / sites-enabled / default
server {
...
server_name localhost;
...
上記のディレクティブで指定した命令は次のとおりです。
-
+ listen +
-ポート443でSSLリスナーを有効にします。 HTTPSポート。 -
+ ssl_protocols +
-現在安全なプロトコルであると考えられるこれら3つのみを有効にします-+ TLSv1 TLSv1.1 TLSv1.2 +
。 -
+ ssl_ciphers +
-これらの安全なSSL暗号のみを有効にします:+ EECDH + AESGCM:EDH + AESGCM:AES256 + EECDH:AES256 + EDH +
-
+ ssl_prefer_server_ciphers +
-クライアントがサーバーの暗号設定を尊重していることを確認します。 -
+ ssl_dhparam +
-以前に生成した強力なカスタムDHパラメーターを使用します。 -
+ ssl_certificate +
-自己署名SSL証明書を使用します。 別の証明書を使用している場合は、必ず変更してください。 -
+ ssl_certificate_key +
-以前に生成したSSLプライベートキーを使用します。
上記の設定を有効にするには、次のコマンドでnginxを再度リロードする必要があります。
sudo service nginx reload
新しいSSL構成をテストするには、https://www.ssllabs.com/ssltest/analyze.html [SSL Labs]が提供するような外部ツールを使用するのが最適です。 そこで、SSLが信頼されていないという警告を無視する必要があります。 これは自己署名証明書であるため、当然です。 このサイトは、登録されたドメイン名を持つサイトのみをテストすることに注意してください。 DropletのIPアドレスだけでSSL接続をテストすることはできません。
全体的な結果は「テスト」のように「T」になるはずですが、本質的にはA(可能な限り最高)であり、「」「信頼の問題が無視される場合:A」
image:https://assets.digitalocean.com/articles/nginx_security_1404/ssltest.png [SSL Check]
後で、SSL警告を削除し、SSLテストをクリーンな「A」にすることをお勧めします。 1つのオプションは、記事https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-14-で説明されているように* Let’s Encrypt *を使用することです04 [Ubuntu 14.04でLet’s Encryptを使用してNginxを保護する方法]。 無料で、最大4096のRSAキーサイズを指定できます。また、自己署名に関する警告は表示されません。 それ以外の場合は、市販のSSLプロバイダーを選択できます。 いずれかを選択するときは、SHA256証明書を選択するようにしてください。
ステップ3-IPによるアクセスの制限
パスワード認証は、サイトコントロールパネル、phpmyadminなど、サイトの機密領域のセキュリティを確保するのに必ずしも十分ではありません。 攻撃者は、そのような領域の弱いパスワードやソフトウェアの脆弱性を悪用して不正アクセスを取得することがあります。 正当なユーザーのIPを特定できる場合は、IPの制限を追加することを強くお勧めします。
たとえば、WordPressサイトがあり、その管理領域が `+ / wp-admin / `にある場合、そのアクセスを自分のIPまたはすべての管理者のIPに制限する必要があります。 この目的のために、対応するサーバーブロックを開きます-Nginxのデフォルトサーバーブロックは ` / etc / nginx / sites-enabled / default +`です:
sudo nano /etc/nginx/sites-enabled/default
`+ server +`設定パート内に以下を追加します:
/ etc / nginx / sites-enabled / default
server {
...
location /wp-admin/ {
allow /24;
allow /24;
deny all;
}
...
...
上記で、 + 192.168.1.1 +`と `+ 10.0.0.1 +`をIPに置き換えてください。 同様に、ネットワークマスク( `+ / 24 +
)を変更することにより、他のIPまたはネットワークへのアクセスを許可できます。
このような設定を有効にするには、次のコマンドでNginxを再度リロードする必要があります。
sudo service nginx reload
許可されたIPアドレス範囲外のブラウザでサイトの「+ / wp-admin / +」部分にアクセスしようとすると、エラーが発生します。 このエラーは403 Forbiddenになります(以前に説明したようにこのエラーを404 Not foundに変更していない限り)。 同時に、次のコマンドを使用してエラーログに真のエラーコードが表示されます。
sudo tail /var/log/nginx/error.log
`+ access forbidden +`エラーは次のように表示されます。
Output of sudo tail -f /var/log/nginx/error.log...
2016/01/02 04:16:12 [error] 4767#0: *13 by rule, client: X.X.X.X, server: localhost, request: "GET /wp-admin/ HTTP/1.1", host: "Y.Y.Y.Y"
...
エラーページの変更やIPによるアクセスの制限など、セキュリティへの複数のアプローチの適用の組み合わせは、Nginxを強化する累積効果を示しています。 例に従って、通常のWordPress管理ページの代わりに、攻撃者と彼らが使用する自動化ツールには404 not foundページが表示されます。 これは混乱を招き、WordPressを侵害する他のアプローチを試みることを思いとどまらせる可能性があります。
[[step-4-- performing-a-security-audit]] === ステップ4-Securityセキュリティ監査の実行
自分の意見とは無関係にセキュリティチェックを行うことは常に良い考えです。 この目的のために、Web脆弱性をスキャンするセキュリティ監査ツールを使用できます。 市販のツールを含むこのようなツールは数多くあり、最初は無料でオープンソースのwapitiを使用できます。 Wapitiには、より高度なツールの機能の一部が欠けている場合がありますが、セキュリティ監査とは何かを知ることができます。
Ubuntuにapt経由でwapitiをインストールできます。
sudo apt-get install wapiti
次に、コマンドでwapitiを使用してサイトのスキャンを開始します。
wapiti http:// -n 10 -b folder
`+ example.org `をサイトの名前に置き換えてください。 コマンドに2つの追加の引数を指定しました。 最初の「 -n 10+」は、同じパターンのURLの数を10に制限するため、無限ループが防止されます。 2番目の引数 `+ -b folder +`は、スキャンの範囲を指定されたドメインのみに設定します。
スキャンが完了すると、スキャンを実行したディレクトリ内の「+ generated_report 」というディレクトリ内に結果が表示されます。 最適に表示するには、このディレクトリをローカルコンピューターにダウンロードし、Webブラウザーで ` index.html`ファイルを開きます。
レポート内では、SQLインジェクション、ブラインドSQLインジェクション、ファイル処理、クロスサイトスクリプティング、CRLF、コマンド実行、リソース消費、Htaccessバイパス、バックアップファイル、潜在的に危険なファイルの10のカテゴリに分類された脆弱性が表示されます。
理想的には、レポートはこのように見えるはずで、脆弱性は見つかりません。
image:https://assets.digitalocean.com/articles/nginx_security_1404/wapiti_report.png [Wapiti Report]
脆弱性がある場合は、スキャンの対応する部分を展開して詳細を確認できます。
NginxおよびWebサイトの最も完全かつ徹底的な監査を保証するために、このようなスキャンを頻繁にさまざまなツールで実行してください。
[[step-5-- taking-additional-security-measures]] === ステップ5-追加のセキュリティ対策を講じる
Nginxのセキュリティに関するいくつかのトピックは、それらに関する優れた記事が既にあるため、この記事では取り上げません。 次のことを理解してください。
Naxsiは、Nginx用のWebアプリケーションファイアウォールです。 悪意のあるシグニチャのコンパイルを使用して、既知および未知のWeb脆弱性から保護します。
Naxsiは複雑なソフトウェアであり、その調整にはある程度の時間と労力がかかることを知っておく必要があります。 幸いなことに、ほとんどの一般的なWebアプリケーションには、必要に応じてさらにカスタマイズできる構成が用意されています。
Fail2banは、Webセキュリティを次のレベルに引き上げ、nginxサーバーを予防的に保護するための優れたツールです。 これまでのところ、ユーザーが特定の情報を見つけてサイトの一部にアクセスすることを制限しています。 fail2banを使用すると、悪意のあるアクティビティを実行していることを検出した場合、攻撃者を一定期間さらにブロックできます。
監視はセキュリティに不可欠であり、MonitはNginxを適切にサポートするこの目的に最適なツールです。 Webログには悪意のあるアクティビティのトレースが表示されるだけでなく、CPU負荷とメモリ使用量のスパイクも表示されます。
この記事では、ステップ5-エラーとキーワードのログを監視することに特に注意してください。 そこで、誰かがサイトの重要な部分にアクセスしたり、アクセスしようとしたときなど、セキュリティイベントが発生したときにカスタムアラートを送信するように設定できます。
ファイアウォールを持つことは、nginxとドロップレット全体のセキュリティにとって非常に重要です。 標準のhttp(tcp 80)ポートに加えて、許可された着信接続にhttps(tcp 443)ポートを追加してください。
AIDEなどのファイルとディレクトリの整合性チェッカーは、ファイルとディレクトリの変更を警告します。 これは、Webファイルの場合に特に便利です。サイトの一部が変更され、新しいファイル/ディレクトリが追加されるときに注意する必要があるためです。 AIDEの詳細については、この記事から始めてください。
上記の記事は少し時代遅れで、Ubuntu向けに特別に書かれたものではありません。 ただし、Ubuntu 14.04にも簡単に適用して適用できるはずです。 AIDE、または他の同様のツールを構成するときは、WebログやWebキャッシュなどの一時ファイルを監視対象から除外してください。
結論
この記事を読んだ後は、Nginxのセキュリティについてより自信を持つはずです。 あなたのウェブ環境が安全に設計された通りに動作するという安心感を得るために、機能とセキュリティのバランスを必ず確認してください。 また、Nginxの保護は継続的なタスクであり、定期的な更新、再構成、スキャンなどが必要であることに注意してください。