nginxでWAF(Web Application Firewall) を作る(第四回:最終回)
こんにちは。SIOS OSSエバンジェリスト/セキュリティ担当の面です。
数回に分けて、nginxでWAFをつくる方法を紹介しています。
前回、nginxとmod_securityのインストールしと設定を行いました。
今回は、実際にWebサイトに攻撃テストを行い、どのくらいnginxのWAFによって攻撃が防げているかを見ていきます。
ImpervaのWAF Testing Frameworkについて
WAFのテストツールは色々なものがありますが、今回はImpervaの「Waf Testing Framework」を使用します。
(※)このツールはダウンロード時に情報登録が必要です。
このツールですが、開発者の「Amichai Shulman」による説明のVideoがこちらから見ることが出来ます。こちらの@ITの記事にわかりやすく紹介されていますが、このツールのコンセプトは、WAFの防御性能を測るために攻撃リクエストの他に、紛らわしい正常なリクエストを出し
False Positive(問題のない正常なリクエストを間違ってブロック)
False Negative(異常なリクエストを検知できずに通過させる)
の二つの割合を測定することで、より正確な防御性能を測定するというものです。
このツールは、ざっくり言うと
攻撃対象Webサーバ(WebGoat)
スキャンツール(Windows上で動作します)
から構成されています。
そのため、前回の「ネットワーク構成」での
192.168.56.101(Target): WebGoat
192.168.56.103(外部): Windowsマシン
がそれぞれ対応します。
Imperva WAF Testing Frameworkのインストール
Imperva WAF Testing Frameworkのサイトに情報を入力すると、ダウンロード先がメールで送られてきます。このダウンロード先から
waf-testing-framework-software.zip
が入手できます。このzipファイルの中に、必要な攻撃対象Webサーバ(WebGoat)とWindows用スキャナのインストーラが同梱されています。
また、この中に「WAF Testing Framework – Instructions.pdf」がありますので、基本的なインストール方法はそちらに記載されています。
1. Targetのインストール
JAVA 1.6以上が動作する環境のLinuxであれば問題ありません。今回、テストではdebianを使用しており、openjdk-8-jreを使用しています。
一般ユーザの.bashrc等で、JAVA_HOMEを
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
として設定します。また、下記のようにWebGoat-5.2/webgoat.shの中のJAVAバージョン確認部分をごっそり削ります。
--- webgoat.sh.org 2016-06-05 00:55:09.743777003 +0900 +++ webgoat.sh 2016-03-04 09:38:20.996000000 +0900 @@ -15,13 +15,6 @@ is_java_1dot5() { if [ "X$JAVA_HOME" != "X" -a -d $JAVA_HOME ]; then $JAVA_HOME/bin/java -version 2>&1 | grep 'version \"1.5' >/dev/null - if [ $? -ne 0 ]; then - echo "The JVM in \$JAVA_HOME isn't version 1.5." - exit 1 - fi - else - echo "Please set JAVA_HOME to a Java 1.5 JDK install" - exit 1 fi }
その後、一般ユーザで、展開されたディレクトリ中のWebGoat-5.2に移動して
user@target:~/waf/WebGoat-5.2$ ./webgoat.sh start8080
とPort 8080(1024以上のポート)を指定して引数として与えてあげれば、Webサーバが起動します。
Virtualboxを使って検証環境を作成しているためにこのようなネットワークになっていますが、実運用環境では負荷分散のための複数NICなど、別途環境に合わせて下さい。
今回の検証環境では、nginx+WAFにPort80で接続すると、適切にフィルタリングを行い、tomcatがPort8080で動作しているマシンにフォワードします。
2. Windows用スキャナのインストール
展開したzipファイルの中に、「WAFTesting.exe」がありますので、これをWindows上で実行すればOKです。
スキャンテスト
それでは、実際にWAFのテストをしてみましょう。
Windows上でWAFTesting.exeを実行します。
ここで、必要な情報を入力します。まず、攻撃対象Webサーバ(192.168.56.101)をHOSTに、Portを8080に指定し、結果のレポート(PDF)のファイル名を指定し、「Run」を押して実行します。
図のようなPDFファイルが表示されます。False Positive:誤検知が100%失敗(0%成功)、False Negative:見逃しが0%失敗(100%成功)ということで、フィルタリングが全然かかっていない状態だとわかります。
次に、nginxで作ったWAF(nginx.localdomain)をHOSTに、Portを80に指定し、結果のレポート(PDF)のファイル名を指定し、「Run」を押して実行します。
図のようなPDFファイルが表示されます。nginxのWAFにより、False Positive:誤検知が25%失敗(75%成功)、False Negative:見逃しが74%失敗(26%成功)ということで、攻撃がWAFにより、ある程度防がれていることがわかります。
modsecurityのルール調整
modsecurityのルールとしては、/etc/nginx/mod_security.confファイルを見てわかる通り
# Load all Rule Include modsecurity.d/*.conf Include modsecurity.d/activated_rules/*.conf Include modsecurity.d/local_rules/*.conf
と、/etc/nginx/modsecurity.d以下の.confファイルをロードしています。
この中で、modsecurity.d/activated_rulesは、/usr/lib/modsecurity.d/base_rules/以下のルールのシンボリックリンクとなっています。
例えば、modsecurity_crs_41_sql_injection_attacks.confを見てみると
SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "(^[\"'`´’‘;]+|[\"'`´’‘;]+$)" "phase:2,rev:'2',ver:'OWASP_CRS/2.2.9',maturity:'9',accuracy:'8',capture,t:none,t:urlDecodeUni,block,msg:'SQL Injection Attack: Common Injection Testing Detected',id:'981318',logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',severity:'2',tag:'OWASP_CRS/WEB_ATTACK/SQL_INJECTION',tag:'WASCTC/WASC-19',tag:'OWASP_TOP_10/A1',tag:'OWASP_AppSensor/CIE1',tag:'PCI/6.5.2',setvar:'tx.msg=%{rule.msg}',setvar:tx.sql_injection_score=+%{tx.critical_anomaly_score},setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/SQL_INJECTION-%{matched_var_name}=%{tx.0}"
となっていて、正規表現でマッチングデータが記載されていることがわかります。
ModSecurityのマニュアル:https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual
に詳しい内容が載っていますので、正規表現の調整や、新しくルールを作成する場合にはマニュアルを見ながら行って下さい。
#長くなってしまうので、ここではマニュアルへのリンクだけにとどめておきます。
例えば、先ほどのmodsecurity_crs_41_sql_injection_attacks.confファイルを、/etc/nginx/modsecurity.d/activated.rules以下のリンクを消すことで、nginxで読み込まないようにすると、以下のようにWAF Testing Frameworkのスキャン結果が変化します。
・変更前
・変更後
(※)results_disabled_sqlinjection.pdfはここからダウンロードできます。
まとめ
今回までで、nginx+WAFの導入方法とテスト方法を一通り紹介しました。実際には、組織でインストールした後に細かな調整が必要になると思いますが、こちらで紹介した記事が参考になれば幸いです。
今後はまたnginxのセキュリティの新機能などを紹介していく予定です。
6/15に「OSSセキュリティナイター vol.1」と題して、セキュリティのセミナーを行います。この回では「急増するランサムウェア その脅威とOSSの対策」として、ランサムウェアのリスクとOSSでの対策方法などをお話します。
また、LinuxFoundationでのセキュリティに対する取り組みや、Rapid7(株)による脆弱性リスク管理も併せてご紹介します。
http://mkt-i.actonservice.com/acton/fs/blocks/showLandingPage/a/15078/p/p-0035/t/page/fm/0がプログラム内容と申し込みの詳細になりますので、是非お申し込み下さい。