NGINX WAFを試してみよう!(セキュリティポリシーの設定)
NGINX App Protect WAFのセキュリティポリシーの設定について丁寧に解説します。
NGINX WAFを試してみよう!~セキュリティポリシー設定編~です。
以前、NGINX WAF(NGINX App Protect WAF)の導入に関して、ブログ「 NGINX WAFを試してみよう! 」で紹介させていただきました。
今回は、その続きで以下のことを確認していきます。
1) 検知ログの確認
2) セキュリティポリシーの設定
おさらい と 設定
まずはおさらいです。前回までで、NGINX App Protect WAFをインストールし、有効化するところまでは実施しました。有効化は、confファイルに数行の設定追加で実施しましたが、今回は WAFとしての検知ログの設定やセキュリティポリシーの設定をやってみます。
環境は、前回と同様で Ubuntu 20.04上にNGINX App Protect WAF Release 3.11 がインストールされています。
ubuntu@nap-test:~$ nginx -v
nginx version: nginx/1.21.6 (nginx-plus-r27)
ubuntu@nap-test:~$ cat /opt/app_protect/VERSION
3.954.0
また、改めて今回のテスト用として以下のconfを作成しました。(upstreamも設定していますが、割愛しています)
ファイル名:/etc/nginx/conf.d/demo.conf
serverディレクティブで、WAFの有効化とログファイルの出力を設定し、テスト用に複数用意したlocationディレクティブで、WAFの有効・無効の切り替えやカスタムセキュリティポリシーの適用などを記述しています。また、どのlocationディレクティブで動作したかを明示的に知るために、X-demo-name
というヘッダーを挿入しています。
少し詳細を見ていきましょう。
・WAFの有効化とログ・ファイルへの出力を serverディレクティブで設定しています。
・最初のlocationディレクティブでは、WAFの設定を無効にしています。
・次のlocationディレクティブでは uri が /app1
の場合、プリセットされているデフォルトのWAFのセキュリティポリシーを明示的に設定しています。
・次のlocationディレクティブでは uri が /app2
の場合、カスタムしたセキュリティポリシーを設定しています。
実は、「/app1
」のlocationディレクティブで app_protect_policy_file をインプリメントされている NginxDefaultPolicy.json を指定していましたが、明示的に設定しなくとも、この デフォルトポリシー(テンプレート)が適用されていました。
ログにどのテンプレートが適用されて検知したかが出力されますので、そこで確認することができます。
セキュリティポリシーのファイルの内容を見ていきましょう。
・プリセットされているデフォルトのセキュリティポリシー( /etc/app_protect/conf/NginxDefaultPolicy.json )
ポリシー名:app_protect_default_policy は、プリセットされたそのままの名称です。この名称は重複して利用することが出来ません。
テンプレート名: POLICY_TEMPLATE_NGINX_BASE は、プリセットされている2つのポリシーのうちの1つの default policy になります。
このテンプレートは、ベーシックテンプレートであり、名前のとおり基本的なポリシーが設定されています。NGINX App Protect が計算したリスク評価の結果次第で、ブロック=通信遮断するか、アラートとしてログに記録されますが実際の通信はブロックをしない、という内容になっています。これは、誤検知を最小限に抑える内容です。
もう1つのポリシーである strict policy のテンプレートは、より高いレベルのセキュリティを必要とするアプリケーションのために用意されているテンプレートです。ログに記録されるのみで実際の通信はブロックはしませんが、以下の機能も有効にしています。
・Data Guard
・HTTP response data leakage signatures
・More restrictive limitations
・Cookie attribute insertion
どちらのポリシーを利用するかは状況次第ですが、まずはベーシックテンプレートの default policy を使用し、なるべく誤検知を減らし、利用結果に応じてポリシーチューニングで攻撃になりうる通信をブロックしていく方法か、最初から strict policy を使い、誤検知と思われる通信に対しては除外ルールを作成していく方法などが考えられるかと思います。
・カスタムテンプレートの作成
/app2
に対するlocationディレクティブのポリシーは、ベーシックテンプレートを基にした custom_app2_Policy.json を作成しました。本来、ブロックする通信も全て透過する内容です。透過する設定は "enforcementMode": "transparent"
です。
1) 検知ログの確認
環境が整ったところで、リクエストを投げて反応を見ていきます。
1つ目のlocationディレクティブ(/
)に curl で通常(攻撃ではない)通信を投げます。200 OKです。想定どおりです。
続いて、XSS攻撃のリクエストを投げます。WAF機能をOFFに設定していますので、当然、通信としてはブロックされません。ログにも記録されません。こちらも想定どおりです。
2つ目のlocationディレクティブ(/app1
)に同様に通信を投げます。通常通信の結果は1つ目と同じなので結果の表示は割愛します。XSS攻撃のリクエストを投げてみます。通信は、WAFによってブロックされました。support ID で表示されている 1558257481112134932 はログで検索する際に必要になりますのでメモっておきます。
検知ログは、/var/log/app_protect/security_demo.log に記録されるように設定しています。
では、早速ログを見てみましょう。support ID を grep の検索対象に設定します。
$ cat /var/log/app_protect/security_demo.log | grep 1558257481112134932
1行に沢山の情報が羅列していますので見難いため、少し頑張って整形してみました。(catで表示、grepで検索、jqで整形、sedで余計な表示の削除)
ざっくりですが、以下のことが分かります。これら以外にも uri や リスク評価結果などの情報を基にポリシーチューニングをおこなっていくことになります。
・attack_type : 攻撃種類
・policy_name : ポリシー名(app_protect_default_policyはインプリされているデフォルトポリシー)
・request_status : リクエストの結果、ブロックしたのか、アラートだけだったかの表示(blocked、alerted)
・sig_ids : 検知した際のシグネチャID
・sig_names : 検知した際のシグネチャの名前
・support_id : レスポンスデータに含まれているsupport ID
実際には ELK stack、 Prometheus + Grafana や Datadogなどのサードパーティ製のツール類を使ってログを確認していくのが良いでしょう。
2) セキュリティポリシーの設定
検知ログの確認が出来ましたので、セキュリティポリシーについて、もう少し見ていきましょう。
詳細はメーカーのサイトを参照していただき、ここではざっくりとしておきます。
サポートしているデフォルトポリシーの一覧などもメーカーのサイトに載っています。
今回は default policy をベースにカスタムセキュリティポリシーを作成します。このカスタムしたセキュリティポリシーを作成・適用することで、ポリシーチューニングを実施していくことになります。default policy のテンプレート名は POLICY_TEMPLATE_NGINX_BASE ですので、これはそのまま流用します。
記述の仕方は以下です。JSON形式で記述します。
例えば、以下は signatureId=200000098(「 <script 」を検知)と 同200001475(「 script> 」を検知)を除外するルールです。
ファイル名:/etc/app_protect/conf/custom_app2_Policy_test.json
NGINX Plus の /etc/nginx/conf.d/demo.conf の locationディレクティブの /app2
の設定を変更します。
NGINX Plus をリロードします。
$ sudo nginx -t
$ sudo nginx -s reload
先程までは、前述していたカスタムポリシーが適用されており、全ての通信をブロックしないで透過する設定でした。今度は 特定の通信だけブロックしない設定に変更になりました。以下はリクエストを投げた結果です。
・除外ルールにより検知されなかった通信
・除外ルールで設定されているsignatureId以外でブロックされた通信
なお、この通信は sig_ids=”200001088,200101609″ で検知されていました。
ここでは signatureId をキーに除外ルールを作成しましたが、パラメータのviolation に対するルールを作成したり、色々な観点でルールを作成することが可能です。また、ブロック時のレスポンスページ(ソーリーページ)も変更することが可能です。
レスポンスページを変更した出力例は以下になります。
まとめ
NGINX App Protect WAFのセキュリティポリシーの変更は、テキストベースでありシンプルな設定となっています。そのため、NGINX App Protect WAFのバージョンをアップグレードした際にも、以前のバージョンのポリシーを参照することが容易になります。
このブログでは載せていませんが、Bot Signatureによる通信制限の実現、IPアドレスによる制御だったり、多くの機能を持っています。なによりも、F5製WAFの機能を移植していますので実績豊富であり、さらにメーカーサポートもありますので、試してみる価値はあるかと思います。
このブログ記事を参考にNGINXのWAFを試してみてはいかがでしょうか。