Contents
はじめに
WAF(Web Application Firewall)のModSecurityを導入します。例によってほぼ手順のみ、詳細については他のサイトで素晴らしい説明がいくらでも出てくると思うのでそちらへ。
対象バージョン
バージョン | |
ModSecurity | 2.9.2 |
最新バージョンは公式HPで確認してください。
サーバ環境(ConoHa VPS)
バージョン | 参照 | |
CentOS 7 | 7.4.1708 | |
OpenSSL | 1.1.0g | OpenSSL 1.1.0 導入 |
Apache | 2.4.29 | Apache 2.4.29 導入 |
MySQL | 5.7.21 | MySQL 5.7.21 導入 |
PHP | 7.2.1 | PHP 7.2.1 導入 |
WordPress | 4.9.2 | WordPress ダウンロードと設定 |
インストール
事前準備
# yum install libxml2-devel lua-devel libcurl-devel expat-devel
ダウンロード
# cd /usr/local/src/ # wget https://www.modsecurity.org/tarball/2.9.2/modsecurity-2.9.2.tar.gz
展開
# tar zxvf modsecurity-2.9.2.tar.gz
configure
# cd modsecurity-2.9.2 # ./configure \ --with-apxs=/usr/local/httpd-2.4.29/bin/apxs \ --with-apr=/usr/local/httpd-2.4.29/bin/apr-1-config \ --with-apu=/usr/local/httpd-2.4.29/bin/apu-1-config
インストール
# make # make CFLAGS=-DMSC_TEST test ============================================================================ Testsuite summary for modsecurity 2.9 ============================================================================ # TOTAL: 1 # PASS: 1 # SKIP: 0 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 ============================================================================ # make mlogc # make install
Apacheの設定
mod_securityを使用するにはApacheモジュールのmod_uniq_idが必要
# ls -l /usr/local/httpd-2.4.29/modules/ | grep mod_unique_id.so -rwxr-xr-x 1 root root 32400 Jan 18 17:07 mod_unique_id.so
有効化
# vi httpd.conf #LoadModule unique_id_module modules/mod_unique_id.so ↓ LoadModule unique_id_module modules/mod_unique_id.so
インストールされたライブラリのパーミッション変更
# cd /usr/local/httpd-2.4.29/modules/ # chmod 755 mod_security2.so
httpd.confにインストールしたモジュールを追加する
LoadModule security2_module modules/mod_security2.so
CRS(ModSecurity Core Rule Set)の適用
サンプルルールのCRSをダウンロードしてインストールします。
gitインストール
# yum install git
ディレクトリ作成
# cd /usr/local/httpd/ # mkdir modsecurity.d
ダウンロード
# cd modsecurity.d/ # git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git ls -l | grep crs drwxr-xr-x 7 root root 291 Feb 2 17:35 owasp-modsecurity-crs
設定ファイルをリネーム(.exampleを外す)
# cd owasp-modsecurity-crs/ # mv crs-setup.conf.example crs-setup.conf
以下のファイルをリネームする(.exampleを外す)
# mv rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf
Apacheの設定ファイルに以下を追加
# vim /usr/local/httpd/conf/httpd.conf <IfModule security2_module> Include modsecurity.d/owasp-modsecurity-crs/crs-setup.conf Include modsecurity.d/owasp-modsecurity-crs/rules/*.conf </IfModule>
Apache再起動
# systemctl reload httpd.service
modsecurity.conf
ダウンロード
# cd /usr/local/httpd/conf.d/ # wget https://raw.githubusercontent.com/SpiderLabs/ModSecurity/master/modsecurity.conf-recommended
リネーム
# mv modsecurity.conf-recommended modsecurity.conf
modsecurityソースからunicode.mappingファイルをコピー
# cp /usr/local/src/modsecurity-2.9.2/unicode.mapping /usr/local/httpd/conf.d/
Syntax確認
# httpd -t Syntax OK
Apache再起動
# systemctl reload httpd.service
modsecurity.confの設定変更
# -- Rule engine initialization ---------------------------------------------- #SecRuleEngine DetectionOnly # 監査は実行するが、block, deny,drop,allow,proxy,redirecのアクションは実行しない SecRuleEngine On # ルールを処理するようにmod_secureityを実行する # -- Request body handling --------------------------------------------------- SecRequestBodyAccess On # クライアントからサーバへのリクエストデータに対して監査する # -- Response body handling -------------------------------------------------- #SecResponseBodyAccess On # サーバからクライアントへのレスポンスデータに対して監査する SecResponseBodyAccess Off # サーバからクライアントへのレスポンスデータに対して監査しない # -- Debug log configuration ------------------------------------------------- #SecDebugLog /opt/modsecurity/var/log/debug.log #SecDebugLog /var/log/modsec_debug.log # デバッグログ出力先(変更) SecDebugLog /usr/local/httpd-2.4.29/logs/modsec_debug.log # 容量が多いため、通常は止めておく #SecDebugLogLevel 3 #デバッグログレベル0でなにも出力しない、9で全ての情報を出力 # -- Audit log configuration ------------------------------------------------- SecAuditEngine RelevantOnly # 監査に引っ掛かったものだけを記録 #SecAuditLog /var/log/modsec_audit.log # 監査ログの出力先 SecAuditLog "|/usr/local/httpd-2.4.29/bin/rotatelogs logs/modsec_audit.log.%Y%m%d 86400 540"
Apache再起動
# systemctl reload httpd.service
テスト
ブラウザでアクセス拒否されてログにも記録されることを確認する。以下のサイトが参考になります。
例えばこんな感じ
http://www.eastforest.jp/esthome/?union+select
例)
http://www.eastforest.jp/esthome/?id=1+union+select+1,2,3/*
問い合わせフォーム等で
<script>alert('test')</script>
トラブルシューティング
インストールと設定は以上ですが、実際このままだとチェックが厳しすぎてWordPressにもログインできなくなったりします。制御された内容をログで確認しながら、不要なチェックは外していく作業が必要になってきます。私みたいに個人サイトなら良くても、組織で運用となるとメンテナンスが結構しんどそうですね、このソフトは…
例)WordPressにログインできない
【対応】WordPressにログインしたときのmodsec_audit.logに表示されるIDを控えておき、ルールから除外する
# grep -o -E '\[id "......"\]' modsec_audit.log.20180208 | sort | uniq [id "920350"] [id "931100"] [id "949110"] [id "980130"] # httpd.confに除外するIDを登録する # httpd.confにincludeしているmodsecurity.confに追加 # vi modsecurity.conf (追加) # -- SecRule Remove ID -- # SecRuleRemoveById 920350 SecRuleRemoveById 931100 SecRuleRemoveById 949110 SecRuleRemoveById 980130 # systemctl reload httpd.service ↓ ログインOK
【懸念】上記除外に設定すると今度はテストで使った以下のアクセスが通る
http://www.eastforest.jp/esthome/?union+select
その時のIDは以下(同じIDで引っかかってる)
# grep -o -E '\[id "......"\]' modsec_audit.log.20180208 | sort | uniq [id "942190"] [id "949110"] [id "980130"]
ルール設定を詰めていく必要がありそうですが、使いこなすのはなかなか厳しそう。
参考
https://open-groove.net/modsecurity/rebuild-with-curl/
https://raw.githubusercontent.com/SpiderLabs/owasp-modsecurity-crs/v3.0/master/INSTALL
https://github.com/SpiderLabs/ModSecurity/wiki#configuration-steps
https://www.lsof.pl/centos/2016/04/01/modsecurity-configuration-base-rules/
https://www.websec-room.com/2013/11/17/1019
https://www.websec-room.com/2013/12/06/1237
https://memorandum.yamasnet.com/archives/Post-6703.html