WAF(ModSecurity)導入

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