Ubuntu14.04でNginxを保護する方法
Nginxは、デフォルト設定でも非常に安全で信頼性の高いWebサーバーです。 ただし、Nginxをさらに保護する方法はたくさんあります。
この記事では、いくつかの一般的なWebサーバー強化アプローチとセキュリティ標準に従うことを試みながら、オープンソースソフトウェアのみを使用します。 つまり、情報開示の防止、暗号化の実施、監査の実行、およびアクセスの制限について話します。
前提条件
このチュートリアルを実行する前に、次の前提条件を満たしていることを確認してください。
-
Ubuntu 14.04ドロップレット(詳細については、( Ubuntu 14.04 を使用した初期サーバーセットアップを参照)
-
Ubuntu14.04LTSにNginxをインストールする方法で説明されているようにインストールおよび構成されたNginxWebサーバー
-
ドロップレットのIPを指す登録済みドメインまたはサブドメイン。 SSL設定をテストするためにこれが必要になります。 詳細については、共通ドメインレジストラからDigitalOceanネームサーバーを指定する方法に関するこの記事をお読みください。
-
root以外のsudoユーザー(詳細については、 Ubuntu 14.04 を使用した初期サーバーセットアップを確認してください)
特に明記されていない限り、このチュートリアルでroot権限を必要とするすべてのコマンドは、sudo権限を持つroot以外のユーザーとして実行する必要があります。
ステップ1—すべてのソフトウェアを更新する
ソフトウェアを最新バージョンに更新することは、Nginxだけでなく、システム全体を保護するための優れた最初のステップです。
警告:システム上のすべてのパッケージを更新する前に、これによってNginx以外のシステムで実行されているものに問題が発生するかどうかを確認してください。 一度に非常に多くのパッケージに影響を与える操作を実行する前に、システム全体のバックアップを作成することをお勧めします。 すべてのパッケージを更新した後に問題が発生した場合は、バックアップに戻すことができます。 リポジトリパッケージリストを更新してから、Ubuntuサーバーでapt-get
で管理されている現在インストールされているすべてのパッケージを更新するには、次のコマンドを実行します。
- sudo apt-get update && sudo apt-get upgrade
または、UbuntuリポジトリでNginxを最新バージョンにアップグレードすることもできます。 これにより、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
Server: nginx/1.4.6 (Ubuntu)
...
ご覧のとおり、上記の出力にはNginxのバージョンとオペレーティングシステムの名前が表示されています。 これは必ずしも深刻な問題ではなく、攻撃者がNginxサーバーを危険にさらすために解決しようとするパズルの一部です。 そのため、Nginxのメイン構成ファイル/etc/nginx/nginx.conf
をnanoで次のように開いて、この情報を非表示にします。
- sudo nano /etc/nginx/nginx.conf
次に、http
構成パーツ内に、次のようにserver_tokens off;
という行を追加します。
http {
##
# Basic Settings
##
server_tokens off;
...
その後、ファイルを保存して終了し、変更を有効にするためにNginxをリロードします。
- sudo service nginx reload
ここで、同じcurlコマンドを再試行すると、次のようになります。
- curl -I http://localhost
表示される情報は少なくなります。
Output of curl -I http://localhostHTTP/1.1 200 OK
Server: nginx
...
上記の出力は、これが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-1ubuntu4.14
...
上記のX-Powered-By
ヘッダーは、サーバーがPHPバージョン5.5.9を実行しているUbuntu14であることを示しています。 この情報を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
構成部分の内部で、以下を指定します。
server {
...
error_page 401 403 404 /404.html;
...
ファイルへの変更を保存した後、コマンドで有効になるようにNginxをリロードしてください。
- sudo service nginx reload
上記のヒントは、情報の開示を防ぐためのアイデアを提供します—本質的でないWebコンテンツをできるだけ少なく表示します。 Nginxだけでなく、バックエンドエンジン(PHP、Tomcatなど)、そしてもちろんWebアプリケーションでも、サービスとデバッグの情報を非表示にする必要があります。
ステップ2—SSLの構成
NginxでSSLを使用して安全なHTTPSプロトコルを実行することは、ユーザーの資格情報や個人データなどの機密情報を処理するすべてのサイトにとって必須です。 SSLは、サイトユーザーがどこにいても、どのインターネット接続を使用していても、ユーザーが送受信する情報を確実に保護するための唯一の手段です。
記事Ubuntu14.04のNginxでSSL証明書を作成する方法では、デフォルトの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ビット長のDHパラメータを生成する必要があります。 ドロップレットによっては、30分ほどかかる場合があります。 次のコマンドを実行します。
- sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 4096
これで、サーバーブロックのSSL部分を構成できます。 例として、デフォルトのサーバーブロックを構成しましょう。 nanoで編集するために構成ファイルを開きます。
sudo nano /etc/nginx/sites-enabled/default
このファイルで、次のようにserver_name
ディレクティブの後にSSL部分を追加してサーバー構成部分を編集します。
server {
...
server_name localhost;
### SSL Part
listen 443 ssl;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
...
上記のディレクティブで指定した命令は次のとおりです。
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構成をテストするには、 SSLLabsが提供するような外部ツールを使用するのが最善です。 そこで、SSLが信頼されていないという警告を無視する必要があります。 自己署名証明書であるため、これは当然のことです。 このサイトは、登録されたドメイン名を持つサイトのみをテストすることに注意してください。 DropletのIPアドレスだけでSSL接続をテストすることはできません。
全体的な結果は「テスト」のように「T」になるはずですが、本質的にはA(可能な限り最高)であり、次のように"If trust issues are ignored: A"
と表示されます。
後で、SSL警告を削除し、SSLテストをクリーンな「A」にすることをお勧めします。 1つのオプションは、記事 Ubuntu14.04でLet’sEncryptを使用してNginxを保護する方法で説明されているようにLet’sEncryptを使用することです。 これは無料で、最大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
構成パーツ内に、以下を追加します。
server {
...
location /wp-admin/ {
allow 192.168.1.1/24;
allow 10.0.0.1/24;
deny all;
}
...
...
上記では、必ず192.168.1.1
と10.0.0.1
をIPに置き換えてください。 同様に、ネットワークマスク(/24
)を変更することで、他のIPやネットワークへのアクセスを許可できます。
このような設定を有効にするには、次のコマンドを使用してNginxを再度リロードする必要があります。
- sudo service nginx reload
これで、許可されたIPアドレス範囲外のブラウザを使用してサイトの/wp-admin/
部分にアクセスしようとすると、エラーが発生します。 このエラーは403Forbiddenになります(前に説明したように、このエラーを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 access forbidden by rule, client: X.X.X.X, server: localhost, request: "GET /wp-admin/ HTTP/1.1", host: "Y.Y.Y.Y"
...
エラーページの変更やIPによるアクセスの制限など、セキュリティに複数のアプローチを適用することの組み合わせは、Nginxを強化することの累積的な効果を示しています。 例のように、通常のWordPress管理ページの代わりに、攻撃者と攻撃者が使用する自動ツールには404notfoundページが表示されます。 これは混乱を招き、WordPressを危険にさらす他のアプローチを試みることを思いとどまらせる可能性があります。
ステップ4—セキュリティ監査の実行
自分の意見から独立したセキュリティチェックを行うことは常に良い考えです。 この目的のために、Webの脆弱性をスキャンするセキュリティ監査ツールを使用できます。 そのようなツールは商用のものも含めてたくさんあり、最初は無料でオープンソースのwapitiを使うことができます。 Wapitiには、より高度なツールの機能の一部が欠けている可能性がありますが、セキュリティ監査とは何かを理解することができます。
aptを介してUbuntuにwapitiをインストールできます。
- sudo apt-get install wapiti
次に、次のコマンドを使用してwapitiを使用してサイトのスキャンを開始します。
wapiti http://example.org -n 10 -b folder
必ずexample.org
をサイトの名前に置き換えてください。 コマンドに2つの追加の引数を指定しました。 最初の-n 10
は、同じパターンのURLの数を10に制限して、無限ループが防止されるようにします。 2番目の引数-b folder
は、スキャンの範囲を指定されたドメインにのみ設定します。
スキャンが完了すると、スキャンを実行したディレクトリ内のgenerated_report
というディレクトリ内に結果が表示されます。 見やすくするために、このディレクトリをローカルコンピュータにダウンロードし、Webブラウザでindex.html
ファイルを開きます。
レポート内には、SQLインジェクション、ブラインドSQLインジェクション、ファイル処理、クロスサイトスクリプティング、CRLF、コマンド実行、リソース消費、Htaccessバイパス、バックアップファイル、潜在的に危険なファイルの10の異なるカテゴリに分類された脆弱性が表示されます。
理想的には、レポートは次のようになり、脆弱性は見つかりませんでした。
脆弱性がある場合は、スキャンの対応する部分を展開して詳細を確認できます。
NginxとWebサイトの最も完全で徹底的な監査を確実にするために、このようなスキャンを頻繁にさまざまなツールで実行するようにしてください。
ステップ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用に特別に書かれたものではありません。 ただし、簡単に適応させて、Ubuntu14.04にも適用できるはずです。 AIDEまたは他の同様のツールを構成するときは、WebログおよびWebキャッシュなどの一時ファイルを監視対象から除外してください。
結論
この記事を読んだ後は、Nginxのセキュリティについてより自信を持って感じるはずです。 Web環境が設計どおりに安全に動作することを安心できるように、機能とセキュリティのバランスを確認してください。 また、Nginxのセキュリティ保護は継続的なタスクであり、定期的な更新、再構成、スキャンなどが必要になることに注意してください。