2012年1月23日月曜日

ModSecurityをソースからビルドしてhashdos対策に活用する

このエントリではModSecurityをソースからビルドする方法を説明した後、hashdos専用のチューニングを施す流れを説明します。

はじめに

既にModSecurityについては、CentOS+yumおよびUbuntu+apt-getにより導入する方法を説明しています。このエントリでは、ModSecurityをソースからビルドする方法を説明します。
ModSecurityのビルドは依存関係が複雑であり、バージョンによってビルド方法が変わるなど、面倒な面があります。このエントリでは、CentOSとUbuntuの場合について、実際的なビルド方法を説明します。

準備するもの

ModSecurityは以下のプロダクトに依存しています(ModSecurity HandbookP27)。ビルドに先立って準備しておく必要があります。
  • Apache Portable Runtime(APR)
  • APR-UTIL
  • mod_unique_id
  • libcurl
  • libxml2
  • Lua5.1 (オプション)
  • PCRE

PCRE、libcurl、libxml2、Lua5.1の準備

これらはパッケージを用いて導入するとよいでしょう。

(1)CentOSの場合
Lua5.1以外は、yumで導入できます。
$ sudo yum -y install pcre-devel libxml2-devel curl-devel
CentOS6の場合、Luaもyumで導入できます。
$ sudo yum install lua-devel
CentOS5の場合、標準パッケージにLuaが用意されていません。Luaは必須ではないし、まだLuaを活用した事例はほとんどないので、通常はLuaなしでよいでしょう。
Luaを使いたい場合は、EPELリポジトリを使えばLuaを導入できます。hashdos攻撃をmod_securityで防御する(CentOS+yum編)を参照して、EPELパッケージを設定した後、以下でLuaを導入して下さい。
$ sudo yum --enablerepo=epel install lua-devel

(2)Ubuntuの場合
Luaも含めて、apt-getで導入できます。
$ sudo apt-get install libpcre3-dev libxml2-dev libcurl3-dev liblua5.1-dev

Apacheの再構築

次に、Apacheの再構築です。Apacheを再構築する理由は、ApacheにバンドルされるPCREが古く、ModSecurityの前提とするPCREのバージョンが異なるからです。このため、Apacheからも外部のPCREを呼び出すようにします(ModSecurity HandbookP30)。また、mod_unique_idが必要になるため、必要に応じてコンパイルします。
パッケージからApacheを導入している場合は、APRとAPR-UTILが入っていないので、開発版のApacheを導入します。

(1)ソースからApacheをビルドしている場合
デフォルトでAPR、ARP-UTILは元々入っています。mod_uniquie_idはコンパイルオプションのチェックをしてください。PCREも先のステップで導入ししたものをApacheからも利用します。
最小限のconfigureのオプションは下記となります。
$ ./configure --with-pcre --enable-so --enable-mods-shared="unique_id"

(2)CentOS+yumでAapcheを導入している場合
開発版のApacheを追加導入します。
$ sudo yum install httpd-devel

(3)Ubuntu+apt-getでApacheを導入している場合
開発版のApacheを追加導入します。
$ sudo apt-get install apache2-dev

mod_securityのビルド

次に、mod_securityのビルドです。configureの際に、以下のように前提モジュールのパスを明示してやるとトラブルの可能性が少ないようです。パスは適宜調整してください。
以下の例では、/usr/local/apache2にApacheが導入されていて、そこにModSecurityも導入する前提で説明しています。
$ cd
$ wget http://www.modsecurity.org/download/modsecurity-apache_2.6.3.tar.gz
$ tar xf modsecurity-apache_2.6.3.tar.gz
$ cd modsecurity-apache_2.6.3
$ ./configure \
  --prefix=/usr/local/apache2 \
  --with-apxs=/usr/local/apache2/bin/apxs \
  --with-apr=/usr/local/apache2/bin/apr-1-config \
  --with-apu=/usr/local/apache2/bin/apu-1-config \
  --with-pcre=/usr/bin/pcre-config \
  --with-libxml=/usr/bin/xml2-config \
  LDFLAGS=-L/usr/local/apache2/lib
$ make
$ sudo make install
ブログなどでは、--enable-performance-measurementを指定している例も見かけますが、これを指定するとModSecurityが遅くなり、ModSecurity自身がhashdos攻撃を受けるような挙動になります。このオプションは指定しないで下さい。

(2)ディレクトリの作成
次に、ModSecurityの使用するワーク用のディレクトリを作成します(ModSecurity HandbookP34~)。apacheの実行ユーザをapacheと仮定しています。適宜変更してください。
$ sudo mkdir /var/modsecurity/
$ sudo mkdir /var/modsecurity/data
$ sudo mkdir /var/modsecurity/tmp
$ sudo mkdir /var/modsecurity/upload
$ sudo chown root:apache /var/modsecurity
$ sudo chown apache:root /var/modsecurity/data
$ sudo chown apache:apache /var/modsecurity/tmp
$ sudo chown apache:root /var/modsecurity/upload/
$ sudo chmod 750 /var/modsecurity
$ sudo chmod 700 /var/modsecurity/data
$ sudo chmod 750 /var/modsecurity/tmp
$ sudo chmod 700 /var/modsecurity/upload

CRS(Core Rule Set)の導入

ModSecurity用の標準ルールセットとしてCore Rule Set(CRS)を導入します。

(1)ダウンロード、展開
http://sourceforge.net/projects/mod-security/files/modsecurity-crs/0-CURRENT/ から最新版をダウンロードします
$ cd
$ wget http://sourceforge.net/projects/mod-security/files/modsecurity-crs/0-CURRENT/modsecurity-crs_2.2.3.tar.gz/download
$ mv download modsecurity-crs_2.2.3.tar.gz  # downloadというファイル名になったのでリネーム
$ tar xvf modsecurity-crs_2.2.3.tar.gz

(2)CRSのコピー
CRSを定位置にコピーします。ここでは、Apacheホームディレクトリ下のcrsというディレクトリにコピーしています。
$ cd /usr/local/apache2/
$ sudo mkdir crs
$ sudo cp -r ~/modsecurity-crs_2.2.3/* crs

mod_securityの設定

modsecurity_crs_10_config.confという設定ファイルを作成します。exampleを元に修正します。
$ cd /usr/local/apache2/crs
$ sudo cp modsecurity_crs_10_config.conf.example modsecurity_crs_10_config.conf
$ sudo vi modsecurity_crs_10_config.conf
「#SecRuleEngine DetectionOnly」 という行を探し、その後ろに以下を追加します。
SecRuleEngine On
# SecRequestBodyAccess リクエストボディのチェックを有効にする(必須)
SecRequestBodyAccess On
SecResponseBodyAccess Off
# SecRequestBodyLimit はPOSTサイズの上限。できるだけ小さく設定する
SecRequestBodyLimit 5242880
# SecRequestBodyNoFilesLimit はファイルアップロード以外のPOSTサイズの上限。できるだけ小さく設定する
SecRequestBodyNoFilesLimit 51200
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus "^(?:5|4(?!04))"
SecAuditLogType Serial
SecAuditLog logs/modsec_audit.log
SecAuditLogParts "ABIFHKZ"
SecDebugLog             logs/modsec_debug.log
SecDebugLogLevel        3
SecDataDir      /var/modsecurity/data/
SecTmpDir       /var/modsecurity/tmp/
SecUploadDir    /var/modsecurity/upload/

Apacheの設定

ModSecurity用のconfファイルを作成します。
$ sudo vi /usr/local/apache2/conf/extra/httpd-modsecurity.conf
以下の内容を入力します。
LoadModule unique_id_module modules/mod_unique_id.so
LoadModule security2_module modules/mod_security2.so

Include crs/modsecurity_crs_10_config.conf
Include crs/base_rules/*.conf
httpd.confを編集します。
$ sudo vi /usr/local/apache2/conf/httpd.conf
最後の行に以下を追加します。
Include conf/extra/httpd-modsecurity.conf
Apacheを起動します。
$ sudo apachectl start
エラーログに以下が出力されていることを確認します。
[Sun Jan 22 23:21:56 2012] [notice] ModSecurity for Apache/2.6.3 (http://www.modsecurity.org/) configured.
[Sun Jan 22 23:21:56 2012] [notice] ModSecurity: APR compiled version="1.4.5"; loaded version="1.4.5"
[Sun Jan 22 23:21:56 2012] [notice] ModSecurity: PCRE compiled version="7.8"; loaded version="7.8 2008-09-05"
[Sun Jan 22 23:21:56 2012] [notice] ModSecurity: LUA compiled version="Lua 5.1"
[Sun Jan 22 23:21:56 2012] [notice] ModSecurity: LIBXML compiled version="2.7.6"
ModSecurityが起動して、APR、PCRE、LUA、LIBXMLがロードされていることを確認してください。LUAはオプションですので、設定していない場合はロードされていなくても構いません。
次に、正常系のアクセスを確認します。以下のURLはサンプルですので、既存コンテンツのURLを指定して下さい。
http://example.jp/index.php
次に、以下がmod_securityによりブロックされることを確認します。既存コンテンツの後ろに、「?union+select」をつけてアクセスします。
http://example.jp/index.php?union+select
403 Forbiddenのエラーが表示されれば、mod_securityが稼働していることになります。

hashdos向けのチューニング

次に、hashdos向けのカスタマイズです。modsecurity_crs_23_request_limits.confに、Cookie数の制限のルールを追加します(Cookieによるhashdos攻撃と対策参照)。
$ sudo vi /usr/local/apache2/crs/base_rules/modsecurity_crs_23_request_limits.conf
以下のルールを探します。
# Maximum number of arguments in request limited
SecRule &TX:MAX_NUM_ARGS "@eq 1" "chain,phase:2,t:none,block,msg:'Too many arguments in request',id:'960335',severity:'4',rev:'2.2.3'"
        SecRule &ARGS "@gt %{tx.max_num_args}" "t:none,setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.notice_anomaly_score},setvar:tx.policy_score=+%{tx.notice_anomaly_score},setvar:tx.%{rule.id}-POLICY/SIZE_LIMIT-%{matched_var_name}=%{matched_var}"
このルールの次に、以下を追加します。Cookieの最大数が30にハードコードされているので適宜変更してください。
SecRule &REQUEST_COOKIES "@gt 30" "phase:2,t:none,deny,log,auditlog,ctl:auditLogParts=AFHZ,status:413,msg:'Too many cookies in request',id:'960336',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+20,setvar:tx.policy_score=+1,setvar:tx.%{rule.id}-POLICY/SIZE_LIMIT-%{matched_var_name}=%{matched_var}"
次に、base_rulesから必要なルールのみを選択するために、activated_rulesというディレクトリに必要なルールのシンボリックリンクを作成します。以下のステップは、CRSを(SQLインジェクション対策など)フルに活用する場合は省略して下さい。
$ cd /usr/local/apache2/crs/activated_rules
$ sudo ln -s ../base_rules/modsecurity_crs_23_request_limits.conf .
$ sudo ln -s ../base_rules/modsecurity_crs_49_inbound_blocking.conf  .
$ sudo ln -s ../base_rules/modsecurity_crs_60_correlation.conf .
httpd-modsecurity.confを修正します。
$ sudo vi /usr/local/apache2/conf/extra/httpd-modsecurity.conf
最終行を以下のように変更します。
##Include crs/base_rules/*.conf
Include crs/activated_rules/*.conf
Apacheを再起動します。
$ sudo apachectl graceful
以上で、ModSecurityがhashdos専用にチューニングされました。

まとめ

ModSecurityをソースからビルドして、hashdos対策専用のチューニングを施す流れを説明しました。
ModSecurityは導入や設定がやっかいで、バージョンアップの際に互換性が損なわれる場合が多いので、大々的には推奨しにくい状況ですが、Apache Killerhashdosのように、あたらな脅威が発覚した際の緊急対処用のツールとしては有効だと思いました。フルのCRSは過剰検知が多くて使いにくい(チューニングが必須)と思いますが、上記のように特定の脅威向けに絞って活用することは有効だと思います。

追記

Apacheの設定の記述漏れがありましたので追記しました。


[PR]
hashdosApacheKillerその他、Webサイトのセキュリティ強化策についての相談は、HASHコンサルティング株式会社まで。
安全なWebアプリケーションの作り方DRMフリーのPDFによる電子版もあります。

0 件のコメント:

コメントを投稿

フォロワー