序章
Naxsiは、Webアプリケーションファイアウォール機能を提供するサードパーティのNginxモジュールです。 Webサーバーに追加のセキュリティをもたらし、XSSやSQLインジェクションなどのさまざまなWeb攻撃からユーザーを保護します。
Naxsiは柔軟で強力です。 WordPressなどの一般的なWebアプリケーションですぐに利用できるルールを使用できます。 同時に、Naxsiの学習モードを使用して、独自のルールを作成し、それらを微調整することもできます。
Naxsiは、 ModSecurity forApacheに似ています。 したがって、すでにModSecurityに精通している場合や、Nginxで同様の機能を探している場合は、Naxsiに関心があります。 ただし、NaxsiにModSecurityのすべての機能が含まれているとは限りません。
このチュートリアルでは、Naxsiをインストールする方法、ルールを理解する方法、ホワイトリストを作成する方法、および一般的に使用されるWebアプリケーション用に既に作成されているルールを見つける方法を示します。
前提条件
このチュートリアルを実行する前に、次の前提条件を満たしていることを確認してください。
- Ubuntu14.04ドロップレット
- 非rootsudoユーザー。 詳細については、 Ubuntu14.04を使用した初期サーバーセットアップを確認してください。
特に明記されていない限り、このチュートリアルでroot権限を必要とするすべてのコマンドは、sudo権限を持つroot以外のユーザーとして実行する必要があります。
ステップ1—Naxsiをインストールする
Naxsiをインストールするには、NaxsiでコンパイルされたNginxサーバーをインストールする必要があります。 この目的のために、パッケージnginx-naxsi
が必要になります。 apt-get
コマンドを使用して、通常のUbuntuの方法でインストールできます。
- sudo apt-get update
- sudo apt-get install nginx-naxsi
これにより、NxsiとNginxおよびそのすべての依存関係がインストールされます。 また、Dropletでサービスが自動的に開始および停止することも確認します。
注: NaxsiなしでNginxを既にインストールしている場合は、パッケージnginx-core
またはNginxの別のフレーバーをパッケージnginx-naxsi
に置き換える必要があります。 他のNginxパッケージはロード可能なモジュールをサポートしておらず、Naxsiを既存のNginxサーバーにロードすることはできません。
ほとんどの場合、nginx-core
をnginx-naxsi
に置き換えることは問題ではなく、以前の構成を引き続き使用できます。 それでも、このようなアップグレードでは、既存の/etc/nginx/
ディレクトリのバックアップを最初に作成することをお勧めします。 その後、新規インストールの手順に従い、システム上の既存のNginxパッケージを削除することに同意することを確認します。
Nginxのデフォルトのインストールは、Naxsiに精通するのに十分な、基本的な動作するNginx環境を提供します。 Nginxのカスタマイズに時間を費やすことはありませんが、代わりにNaxsiの構成に直接進みます。 ただし、Nginxの経験がない場合は、 Ubuntu 14.04 LTSにNginxをインストールする方法とその関連記事、特に Nginxサーバーブロック(仮想ホスト)を設定する方法を確認することをお勧めします。 Ubuntu 14.04LTSで。
ステップ2—Naxsiを有効にする
まず、Naxsiを有効にするには、ファイル/etc/nginx/naxsi_core.rules
にあるコアルールをロードする必要があります。 このファイルには、悪意のある攻撃を検出するための一般的なシグネチャが含まれています。 これらのルールについては、後で詳しく説明します。 今のところ、HTTPリスナー部分のNginxのメイン構成ファイル/etc/nginx/nginx.conf
にルールを含めるだけです。 したがって、nanoで編集するために後者のファイルを開きます。
- sudo nano /etc/nginx/nginx.conf
次に、http
セクションを見つけ、行の先頭にある#
文字を削除して、Naxsiのルールのインクルード部分のコメントを解除します。 これで、次のようになります。
http {
...
# nginx-naxsi config
##
# Uncomment it if you installed nginx-naxsi
##
include /etc/nginx/naxsi_core.rules;
...
ファイルを保存して、エディターを終了します。
次に、前のルールを有効にして、Naxsiのいくつかの基本的なオプションを構成する必要があります。 デフォルトでは、基本的なNaxsi構成はファイル/etc/nginx/naxsi.rules
にあります。 このファイルを開きます。
- sudo nano /etc/nginx/naxsi.rules
DeniedUrl
の値のみをデフォルトですでに存在するエラーファイルに変更し、残りは変更しないでください。
# Sample rules file for default vhost.
LearningMode;
SecRulesEnabled;
#SecRulesDisabled;
DeniedUrl "/50x.html";
## check rules
CheckRule "$SQL >= 8" BLOCK;
CheckRule "$RFI >= 8" BLOCK;
CheckRule "$TRAVERSAL >= 4" BLOCK;
CheckRule "$EVADE >= 4" BLOCK;
CheckRule "$XSS >= 8" BLOCK;
ファイルを保存して終了します。
上記の構成ディレクティブとその意味は次のとおりです。
LearningMode
-学習モードでNaxsiを起動します。 これは、リクエストが実際にブロックされないことを意味します。 Nginxエラーログではセキュリティ例外のみが発生します。 デフォルトのルールはかなり積極的であるため、このような非ブロッキングの初期動作は重要です。 後で、これらの例外に基づいて、正当なトラフィックのホワイトリストを作成します。SecRulesEnabled
-サーバーブロック/場所に対してNaxsiを有効にします。 同様に、SecRulesDisabled
のコメントを解除することで、サイトまたはサイトの一部のNaxsiを無効にできます。DeniedUrl
-拒否されたリクエストが内部的に送信されるURL。 これは、変更する必要がある唯一の設定です。 デフォルトのドキュメントルート(/usr/share/nginx/html/50x.html
)内にあるすぐに利用できる50x.html
エラーページを使用するか、独自のカスタムエラーページを作成できます。CheckRule
-さまざまなカウンターのしきい値を設定します。 このしきい値を超えると(例: SQLカウンターの場合は8ポイント)要求はブロックされます。 これらのルールをより積極的にするには、値を減らし、その逆も同様です。
ファイルnaxsi.rules
は、サーバーブロックの場所ごとにロードする必要があります。 デフォルトのサーバーブロックのルートロケーション(/
)にロードしましょう。 まず、サーバーブロックの構成ファイル/etc/nginx/sites-enabled/default
を開きます。
- sudo nano /etc/nginx/sites-enabled/default
次に、ルートの場所/
を見つけて、次のようになっていることを確認します。
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
# Uncomment to enable naxsi on this location
include /etc/nginx/naxsi.rules;
}
警告:デフォルトではnaxsi.rules
にはセミコロンがないため、include
ステートメントの最後にセミコロンを追加してください。 したがって、ステートメントのコメントを外すだけでは、構成に構文エラーが発生します。
上記の変更を行ったら、変更を有効にするためにNginxをリロードできます。
- sudo service nginx reload
次のステップでは、変更が成功したかどうかを確認する方法と、ログを読み取る方法について説明します。
ステップ3—ログを確認する
Naxsiが機能することを確認するために、学習モードであっても、例外をスローするURLにアクセスして、エラーログで例外を確認しましょう。
このルールが正確にどのように機能するかは後で説明します。 今のところ、例外を見つけるためにNginxのエラーログをテールします(-f
オプションは出力を開いたままにし、それに新しいコンテンツを追加します:
- sudo tail -f /var/log/nginx/error.log
URLhttp://Your_Droplet_IP/index.html?asd=----
でドロップレットにアクセスしてみてください。 これは、SQLのコメントに使用されるダッシュが原因で、Naxsiセキュリティ例外をトリガーする必要があります。ダッシュはSQLインジェクションの一部と見なされます。
sudo tail -f /var/log/nginx/error.log
の出力に、次の新しいコンテンツが表示されます。
Output of nginx's error log2015/11/14 03:58:35 [error] 4088#0: *1 NAXSI_FMT: ip=X.X.X.X&server=Y.Y.Y.Y&uri=/index.html&learning=1&total_processed=24&total_blocked=1&zone0=ARGS&id0=1007&var_name0=asd, client: X.X.X.X, server: localhost, request: "GET /index.html?asd=---- HTTP/1.1", host: "Y.Y.Y.Y"
上記の行の最も重要な部分が強調表示されています:zone0=ARGS&id0=1007&var_name0=asd
。 ゾーン(リクエストの一部)、トリガーされたルールのID、および疑わしいリクエストの変数名が表示されます。
さらに、X.X.X.X
はローカルコンピューターのIPであり、Y.Y.Y.Y
はドロップレットのIPです。 URIには、リクエストのファイル名(index.htm
)、Naxsiがまだ学習モードで動作しているという事実(learning=1
)、および処理されたすべてのリクエストの総数( [ X182X])。
また、上記の行の直後に、DeniedUrl
へのリダイレクトに関するメッセージが続くはずです。
Output of nginx's error log2015/11/14 03:58:35 [error] 4088#0: *1 rewrite or internal redirection cycle while internally redirecting to "/50x.html" while sending response to client, client: X.X.X.X, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "Y.Y.Y.Y", referrer: "http://Y.Y.Y.Y/index.html?asd=----"
Naxsiが学習モードの場合、このリダイレクトはログにのみ表示されますが、実際には発生しません。
CTRL-C
を押してtail
を終了し、エラーログファイルの出力を停止します。
後で、Naxsiのルールについて詳しく学習します。次に、ログについてこの基本的な知識を持っていることが重要になります。
ステップ4—Naxsiルールの構成
Naxsiの構成の最も重要な部分は、そのルールです。 ルールには、メインルールと基本ルールの2種類があります。 メインルール(MainRule
で識別)はサーバーにグローバルに適用されるため、メインNginxの構成のhttp
ブロックの一部です。 これらには、悪意のあるアクティビティを検出するための一般的なシグネチャが含まれています。
基本的なルール(BasicRule
で識別)は、主に誤検知のシグネチャとルールをホワイトリストに登録するために使用されます。 これらは場所ごとに適用されるため、サーバーブロック(vhost)構成の一部である必要があります。
主なルールから始めて、ファイル/etc/nginx/naxsi_core.rules
のnginx-naxsi
パッケージによって提供されるデフォルトのルールを見てみましょう。 サンプルラインは次のとおりです。
...
MainRule "str:--" "msg:mysql comment (--)" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:4" id:1007;
...
上記のルールから、普遍的ですべてのルールに存在する次の部分の概要を説明できます。
MainRule
は、すべてのルールを開始するためのディレクティブです。 同様に、すべてのルールはルールのID番号で終わります。str:
はルールの2番目の部分にあります。str:
の場合は、上記の例のように、署名がプレーンな文字列になることを意味します。 正規表現は、ディレクティブrx:
と一致させることもできます。msg:
は、ルールについての説明を提供します。mz:
はマッチゾーン、またはリクエストのどの部分が検査されるかを表します。 これは、本文、URL、引数などである可能性があります。s:
は、署名が見つかったときに割り当てられるスコアを決定します。 スコアは、SQL
(SQL攻撃)、RFI
(リモートファイルインクルード攻撃)などのさまざまなカウンターに追加されます。
基本的に、コメントmysql comments
を含む上記のルール(id 1007
)は、文字列--
がリクエストのいずれかの部分(本文、引数など)で見つかった場合、4ポイントはSQLカウンターに追加されます。
ログでSQL例外をトリガーしたURIの例(http://Your_Droplet_IP/index.html?asd=----
)に戻ると、ルール1007をトリガーするには、2組のダッシュ(--
)が必要であることがわかります。 これは、ペアごとに4ポイントを取得し、SQLチェーンが要求をブロックするために8ポイントを必要とするためです。 したがって、ダッシュの1つのペアだけが問題になることはなく、ほとんどの場合、正当なトラフィックが影響を受けることはありません。
特別なルールディレクティブの1つは、negative
です。 署名が一致しない場合、つまりスコアが適用されます リクエストに何かが欠けている場合、悪意のあるアクティビティが疑われます。
たとえば、同じファイル/etc/nginx/naxsi_core.rules
のid 1402
のルールを見てみましょう。
...
MainRule negative "rx:multipart/form-data|application/x-www-form-urlencoded" "msg:Content is neither mulipart/x-www-form.." "mz:$HEADERS_VAR:Content-type" "s:$EVADE:4" id:1402;
...
上記のルールは、Content-type
リクエストヘッダーにmultipart/form-data
もapplication/x-www-form-urlencoded
も含まれていない場合、4ポイントがEVADEカウンターに追加されることを意味します。 このルールは、正規表現(rx:
)を署名の説明に使用する方法の例でもあります。
ステップ5—ホワイトリストのルール
デフォルトのNaxsiルールは、サイト上の正当なトラフィックをほぼ確実にブロックします。特に、さまざまなユーザー操作をサポートする複雑なWebアプリケーションがある場合はそうです。 そのため、このような問題を解決するためのホワイトリストがあります。
ホワイトリストは、2番目のタイプのルールであるNaxsiの基本ルールを使用して作成されます。 基本ルールを使用すると、ルール全体またはルールの一部をホワイトリストに登録できます。
基本的なルールがどのように機能するかを示すために、SQLコメントルール(id 1007)に戻りましょう。 ファイル名にダッシュが2つあるファイルがあるとします。例: あなたのサイトのsome--file.html
。 ルール1007を設定すると、このファイルはSQLカウンターを4ポイント増やします。 このファイル名だけで、結果のスコアはリクエストをブロックするのに十分ではありませんが、それでも誤検知であり、問題を引き起こす可能性があります。 たとえば、ダッシュが2つある引数もある場合、リクエストはルール1007をトリガーします。
それをテストするには、前のようにエラーログを追跡します。
- sudo tail -f /var/log/nginx/error.log
http://Your_Droplet_IP/some--file.html?asd=--
にアクセスしてみてください。 テストのためにこのファイルをWebサイトに置く必要はありません。
エラーログの出力には、次のようなおなじみの例外が表示されます。
Output of nginx's error log2015/11/14 14:43:36 [error] 5182#0: *10 NAXSI_FMT: ip=X.X.X.X&server=Y.Y.Y.Y&uri=/some--file.html&learning=1&total_processed=10&total_blocked=6&zone0=URL&id0=1007&var_name0=&zone1=ARGS&id1=1007&var_name1=asd, client: X.X.X.X, server: localhost, request: "GET /some--file.html?asd=-- HTTP/1.1", host: "Y.Y.Y.Y"
CTRL-C
を押して、エラーログ出力の表示を停止します。
この誤検知のトリガーに対処するには、次のようなホワイトリストが必要です。
BasicRule wl:1007 "mz:URL";
重要なキーワードは、ホワイトリストのwl
で、その後にルールIDが続きます。 ホワイトリストに登録する内容をより正確にするために、一致ゾーン(URL)も指定しました。
このホワイトリストを適用するには、最初にホワイトリスト用の新しいファイルを作成します。
- sudo nano /etc/nginx/naxsi_whitelist.rules
次に、ルールをファイルに貼り付けます。
BasicRule wl:1007 "mz:URL";
他のホワイトリストがある場合は、それらもこのファイルに入れて、それぞれを新しい行に配置できます。
ホワイトリストを含むファイルは、サーバーブロックに含まれている必要があります。 デフォルトのサーバーブロックに含めるには、nanoを再度使用します。
- sudo nano /etc/nginx/sites-enabled/default
次に、次のように、Naxsiの前のインクルードの直後に新しいインクルードを追加します。
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
# Uncomment to enable naxsi on this location
include /etc/nginx/naxsi.rules;
include /etc/nginx/naxsi_whitelist.rules;
}
この変更を有効にするには、Nginxをリロードします。
- sudo service nginx reload
これで、ブラウザでYour_Droplet_IP/some--file.html?asd=--
に対して同じリクエストを再試行すると、2つのダッシュに等しいasd
パラメータのみがSQLカウンターに対して4ポイントをトリガーしますが、一般的でないファイル名はトリガーしません。 したがって、このリクエストは例外としてエラーログに表示されません。
必要なすべてのホワイトリストを作成することは、面倒な作業であり、それ自体が科学である可能性があります。 そのため、最初はすぐに利用できるNaxsiホワイトリストを使用できます。 最も人気のあるWebアプリケーションにはそのようなものがあります。 それらをダウンロードして、先ほど行ったようにサーバーブロックに含める必要があります。
エラーログに正当なリクエストの例外が表示されていないことを確認したら、Naxsiの学習モードを無効にすることができます。 この目的のために、nanoでファイル/etc/nginx/naxsi.rules
を開きます。
- sudo nano /etc/nginx/naxsi.rules
次のように、その前に#
文字を追加して、LearningMode
ディレクティブをコメントアウトします。
...
#LearningMode;
SecRulesEnabled;
#SecRulesDisabled;
...
最後に、変更を有効にするためにNginxをリロードします。
- sudo service nginx reload
これで、Naxsiは疑わしいリクエストをブロックし、サイトの安全性が高まります。
結論
これは、NginxとNaxsiを備えたWebアプリケーションファイアウォールを使用するのがいかに簡単かです。 最初はこれで十分です。強力なNaxsiモジュールが提供するものについてもっと学びたいと思うことを願っています。 これで、Nginxサーバーを高速にするだけでなく、安全にすることができます。