ちょっと話題の記事

Apache DoS攻撃にそなえる

2013.03.07

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

mod_evasiveをインストールする

ApacheのDoS攻撃対策で有名なところとしてmod_evasiveやmod_dosdetectorが有名どころですね。
今回はmod_evasiveをインストール&セットアップしてみます。
セットアップ環境はお決まりのAWS Amazon Linuxです。早速ソースをダウンロードしてきて、セットアップします。
事前にApacheモジュール(mod_so.c)が有効かを確認します。

# /usr/local/apache2/bin/apachectl -l
Compiled in modules:
  core.c
  ・
  ・        多いので省略(そもそも多いのも改善の余地はありますがw)
  ・
  mod_env.c
  mod_setenvif.c
  mod_version.c
  prefork.c
  http_core.c
  mod_alias.c
  mod_so.c

mod_so.cが有効になっているので、次に進みます。(これが入ってない方はhttpd-develを先にインストールする必要があります。)
mod_evasiveはhttp://www.zdziarski.com/でダウンロードできます。

# cd /usr/local/src/
# wget http://www.zdziarski.com/blog/wp-content/uploads/2010/02/mod_evasive_1.10.1.tar.gz
# tar zxvf mod_evasive_1.10.1.tar.gz
# cd mod_evasive
# /usr/local/apache2/bin/apxs -i -a -c mod_evasive20.c

# cd /usr/local/apache2/modules
# ls -l mod_evasive20.so
-rwxr-xr-x 1 root root 51287 Mar  1 15:33 mod_evasive20.so

必要に応じてmod_evasive20.cを編集して、通知メールの設定を行うこともできますが、今はデフォルトのままでセットアップを進めます。

mod_evasiveの設定

ログ書き出しディレクトリを作成します。(apacheを実行しているユーザにオーナーを変更しておきます。)

# mkdir /var/log/mod_evasive/
# chown apache:apache /var/log/mod_evasive/

次にapacheのコンフィグレーションファイルを開いてDos攻撃とみなす条件を設定します。
自動でLoadModule evasive20_module modules/mod_evasive20.soが追加されていると思いますので確認します。あとはIfModuleを追加してhttpd.confに設定反映させます。(デフォルト値はmod_evasive20.cをviで開くと記載があります。)以下がデフォルト値のようです。

#define DEFAULT_HASH_TBL_SIZE   3097ul  // Default hash table size
#define DEFAULT_PAGE_COUNT      2       // Default maximum page hit count per interval
#define DEFAULT_SITE_COUNT      50      // Default maximum site hit count per interval
#define DEFAULT_PAGE_INTERVAL   1       // Default 1 Second page interval
#define DEFAULT_SITE_INTERVAL   1       // Default 1 Second site interval
#define DEFAULT_BLOCKING_PERIOD 10      // Default for Detected IPs; blocked for 10 seconds
#define DEFAULT_LOG_DIR         "/tmp"  // Default temp directory

下記設定は同一ページに2秒間で3回のリクエストがあった場合と同一サイトに1秒間に20回アクセスがあった場合に3600秒アクセス禁止(403 Forbidden)にする設定です。ちょっと長めに設定しすぎかな^^; この値は必要に応じてチューニングする必要があります。

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

LoadModule evasive20_module   modules/mod_evasive20.so

<IfModule mod_evasive20.c>
     DOSHashTableSize 3097
     DOSPageCount 3
     DOSSiteCount 20
     DOSPageInterval 2
     DOSSiteInterval 1
     DOSBlockingPeriod 3600
     DOSLogDir "/var/log/mod_evasive"
     DOSEmailNotify xxxxx@xxxx.jp ←拒否したIPアドレスをメール送付。
</IfModule>

設定が完了したらviを終了して、Apacheの再起動を行います。

# service httpd restart
# /usr/local/apache2/bin/apachectl -M
Loaded Modules:
 core_module (static)
 authn_file_module (static)
 authn_default_module (static)
 authz_host_module (static)
 authz_groupfile_module (static)
 authz_user_module (static)
 authz_default_module (static)
 auth_basic_module (static)
  ・
  ・        
  ・
 so_module (static)
 evasive20_module (shared)
 proxy_module (shared)
 proxy_http_module (shared)
Syntax OK

evasive20_moduleが読み込まれていることを一応確認

動作テスト

検証用のPerlモジュールが入っているので、それを実行して動作確認をします。実行権が付いてない場合は実行権を付与します。

# cd /usr/local/src/mod_evasive
# chmod +x test.pl
# /usr/local/src/mod_evasive/test.pl
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden

途中から403 Forbiddenになり拒否されたことが確認できました。ログは拒否したIP単位で残ります。

# cd /var/log/mod_evasive
# ls -l
-rw-r--r-- 1 apache apache 5 Mar  6 13:35 dos-127.0.0.1
# cd ..
# grep Blacklisting messages
Mar  6 13:35:57 ip-10-156-205-80 mod_evasive[1612]: Blacklisting address 127.0.0.1: possible DoS attack.

正しく動作していることが確認できたので、ループバック・アドレスは対象外にするように設定ファイルを変更します。

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

LoadModule evasive20_module   modules/mod_evasive20.so

<IfModule mod_evasive20.c>
     DOSHashTableSize 3097
     DOSPageCount 3
     DOSSiteCount 20
     DOSPageInterval 2
     DOSSiteInterval 1
     DOSBlockingPeriod 3600
     DOSLogDir "/var/log/mod_evasive"
     DOSWhitelist 127.0.0.1 ←ループバック・アドレスをホワイトリストにする設定。
     DOSEmailNotify xxxxx@xxxx.jp
</IfModule>

# service httpd restart

次に外部からアクセスして正しく拒否するかをテストしてみます
別のEC2インスタンスにSSHでログインして下記コマンドを実行してみます。(Apacheはソースからインストールされているものを利用しています。)

# /usr/local/apache2/bin/ab -n 50 -c 10 http://xxx.xxx.xxx.xxx/index.html(xxx.xxx.xxx.xxxはmod_evasiveの入っているサーバです)

別インスタンスからapacheのabコマンドを実行する前にmod_evasiveの入ってるサーバで以下を実行してログ監視しておく

# tail -f  /var/log/messages
Mar  6 14:09:38 ip-10-156-205-80 mod_evasive[1678]: Blacklisting address xxx.xxx.xxx.xxx: possible DoS attack.

ちゃんとxxx.xxx.xxx.xxxのIPアドレスからのリクエストをブロックしたことが確認できました。/var/log/mod_evasive/配下にも拒否したIP単位で残っていました。しばらく運用してみて設定値のブロック条件の調整をしようと思います。