EC2 Amazon LinuxにWAF(ModSecurity)をインストールする

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

昨日から突然不正・不要なHTTPアクセスが鬼のように増えてしまったので何か対策を打たねばという事から、mod_securityを適用することにしました。早速modsecurity-apache_2.6.6をダウンロードし、インストールを試みました

cd /usr/local/src
wget http://sourceforge.net/projects/mod-security/files/modsecurity-apache/2.6.6/modsecurity-apache_2.6.6.tar.gz/download
tar xvfz modsecurity-apache_2.6.6.tar.gz
cd modsecurity-apache_2.6.6
./configure

configure: *** pcre library not found.
configure: error: pcre library is required

と早速PCREがないと怒られました。

rpm -qa | grep pcre

pcre-7.8-3.1.8.amzn1.x86_64

古いかもしれないので、アップデートをやってみる。

yum -y update pcre

pcre.x86_64 0:8.21-5.2.amzn1

になりました。で再度実行しましたが、やっぱりこれだけではダメでした。依存するパッケージを追加でインストールします。

yum -y install pcre-devel
yum -y install libxml2
yum -y install libxml2-devel

mod_securityを利用するにはmod_unique_idが必要ということでしたので、インストールします。

cd /usr/local/src/httpd-2.2.22/modules/metadata
/usr/local/apache2/bin/apxs -cia mod_unique_id.c

次にaprとapr-utilをインストールします。

cd /usr/local/src/httpd-2.2.22/srclib/apr
./configure
make
make install

cd /usr/local/src/httpd-2.2.22/srclib/apr-util
./configure --with-apr=/usr/local/apr/bin/apr-1-config
make
make install

ここまで出来たらpcre,apr,apr-utilに対応させるためにApacheの再構築を行います。

service httpd stop
cd /usr/local/src/
cd httpd-2.2.22
make clean
./configure --enable-so \
            --enable-rewrite \
            --enable-mods-shared="unique_id" \
            --with-pcre \
            --with-apr=/usr/local/apr/bin/apr-1-config \
            --with-apr-util=/usr/local/apr/bin/apu-1-config \
            --prefix=/usr/local/apache2
make
make install

よし、Apacheの再構築も終わったし、modsecurityのインストールに再チャレンジします

cd /usr/local/src/modsecurity-apache_2.6.6
make clean
./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
make install

すると次は以下のエラーが出てしまいました。も〜ってな感じですが。。。

curl/curl.h: No such file or directory

う~んCURLなんて使うのか。。。
仕方ないので、
wget http://curl.haxx.se/download/curl-7.26.0.tar.gz
でダウンロード&インストールします

cd /usr/local/src
wget http://curl.haxx.se/download/curl-7.26.0.tar.gz
tar xvfz curl-7.26.0.tar.gz
cd curl-7.26.0
./configure
make
make install

curlのインストールがうまくいったので、modsecurityのインストールに再々チャレンジします

cd /usr/local/src
cd modsecurity-apache_2.6.6
make clean
./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
make install

ようやくエラーもなくmodsecurityがインストールできました。
次はmodsecurityで使用するテンポラリディレクトリを作成します。(Apacheの実行ユーザがapacheを想定しています。)

mkdir /var/modsecurity/
mkdir /var/modsecurity/data
mkdir /var/modsecurity/tmp
mkdir /var/modsecurity/upload
chown root:apache /var/modsecurity
chown apache:root /var/modsecurity/data
chown apache:apache /var/modsecurity/tmp
chown apache:root /var/modsecurity/upload/
chmod 750 /var/modsecurity
chmod 700 /var/modsecurity/data
chmod 750 /var/modsecurity/tmp
chmod 700 /var/modsecurity/upload

次はCRS(Core Rule Set)をダウンロードしてセットアップします。

cd /usr/local/src
wget http://sourceforge.net/projects/mod-security/files/modsecurity-crs/0-CURRENT/modsecurity-crs_2.2.5.tar.gz/download

tar xvfz modsecurity-crs_2.2.5.tar.gz
cd modsecurity-crs_2.2.5

mkdir /usr/local/apache2/crs
cp -r /usr/local/src/modsecurity-crs_2.2.5/* crs/.

cd /usr/local/apache2/crs
cp modsecurity_crs_10_setup.conf.example modsecurity_crs_10_config.conf
vi modsecurity_crs_10_config.conf

modsecurity_crs_10_config.confの29行目辺りに以下を追加します。

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/

modsecurity用のconfファイルを作成します。

touch /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

Apacheを再起動して、modsecurityが正しく起動され、APR,PCRE,LIBXMLがロードされていることを確認します。

service httpd stop
service httpd start

cd /usr/local/apache2/log

cat error_log | grep APR

[Wed Jun 20 11:38:56 2012] [notice] ModSecurity: APR compiled version="1.4.5"; loaded version="1.4.5"

cat error_log | grep PCRE

[Wed Jun 20 11:38:56 2012] [notice] ModSecurity: PCRE compiled version="8.21"; loaded version="8.21 2011-12-12

cat error_log | grep LIBXML

[Wed Jun 20 11:38:56 2012] [notice] ModSecurity: LIBXML compiled version="2.7.6"

どうやら問題なくロードされているようです。
次に、正常系のアクセスを確認してみます。以下のURLはサンプルですので、環境に応じて変更してください。
http://ec2-[サーバホスト名称].compute.amazonaws.com/phpinfo.php

次にmod_securityによりブロックされることを確認します。先ほどのURLの後ろに、「?union+select」をつけてアクセスしてます。

http://ec2-[サーバホスト名称].compute.amazonaws.com/phpinfo.php?union+select

上記の画面の様に403 Forbiddenのエラーが表示されれば、mod_securityが稼働していることになります。これでだいぶ不正なアクセスは減ったのですが、やはりapacheのaccessログにはまだまだ不正・不要なリクエストが来ています。もしかしてこのIPアドレス自体が呪われているのではないか?という事になりElastic IPを振り直すことにしてみました。その結果、不要なリクエストがまったく飛んでこなくなりました。根本的な解決方法ではないかもしれませんが、AWSを利用していることもあり、簡単にIPアドレスを振り直すことができたので、暫定対策としてElastic IPを振り直すでまずは逃れることにします。

あと試してみることとしてはIPアドレスでのリクエストを遮断する設定をapacheに追加して設定してみたりですが、IP変更後、不正・不要なアクセスがこないのでこの設定がどこまで有効なのかは現時点では確認できませんが、一応apacheの設定に追加しておきました。

cd /usr/local/apache2/conf
vi httpd.conf

下記をhttpd.confに追加しました。追加後はapacheを再起動します。ServerNameのxxx-xxx-xxx-xxxは適宜変更してください。

<VirtualHost *:80>
        ServerName any
        DocumentRoot /tmp
</VirtualHost>

<VirtualHost *:80>
        ServerName ec2-xxx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com
        DocumentRoot /usr/local/apache2/htdocs
        ErrorLog logs/error_log
        CustomLog logs/access_log combined env=!nolog
</VirtualHost>