Apache

mod_dosdetectorを使ってみましょうよ。~挫折を乗り越え~

ごあいさつ

こんばんは。
ハロウィンの季節は生き生きしているが、10/31が近づくにつれ悲しくなってくるもに倉です。
もうハロウィンが終わってしまう……(まだ始まってもいない)。

さて、今回はDoS攻撃対策にmod_dosdetectorを導入してみたところいろいろと
苦戦した部分があったので、導入~設定までを記事にしてみました。
困っているだれかの力になれれば幸いです。

mod_dosdetectorについて

そもそもmod_dosdetectorとは? というところですね。
端的に言うと、DoS攻撃を検出してくれるApacheのモジュールのことです。

メインは「検出」だけなので、きちんと設定しないと攻撃対策してくれないところは注意。
また、設定内容がかなり単純でわかりやすい分、細かい設定はできません。

導入

さっそく導入していくぞ!(やる気)

環境

今回は、さくっと検証環境が作りやすいのでAWSのEC2でやっていきます。

cat /etc/system-release
--------------------------------------------------------------------------
Amazon Linux release 2 (Karoo)
--------------------------------------------------------------------------

下準備

Apacheがないと話にならないので、インストール&起動

yum install httpd -y
systemctl enable httpd --now

適当にバーチャルホストを作成

mkdir /var/www/monikura.com

vi /etc/httpd/conf.d/virtual.conf
--------------------------------------------------------------------------
<VirtualHost *:80>
ServerName monikura.com
ServerAdmin root@localhost
DocumentRoot /var/www/monikura.com
</VirtualHost>
--------------------------------------------------------------------------

gitでもにょもにょするので用意

yum install git -y

apxsとかgccとかも使うので用意

yum install httpd-devel -y
yum install gcc gcc-c++ make -y

mod_dosdetectorのインストール

まずはソースをダウンロードしてきましょう。

cd /usr/local/src

git clone https://github.com/stanaka/mod_dosdetector.git
--------------------------------------------------------------------------
Cloning into 'mod_dosdetector'...
remote: Enumerating objects: 24, done.
remote: Total 24 (delta 0), reused 0 (delta 0), pack-reused 24
Receiving objects: 100% (24/24), 13.98 KiB | 4.66 MiB/s, done.
Resolving deltas: 100% (10/10), done.
--------------------------------------------------------------------------

以下の通り、mod_dosdetectorのディレクトリができていればOK

ll /usr/local/src/
--------------------------------------------------------------------------
total 0
drwxr-xr-x 3 root root 104 Oct 25 02:17 mod_dosdetector
--------------------------------------------------------------------------

では、いよいよインストールを行いますが、その前に……

which apxs
--------------------------------------------------------------------------
/usr/bin/apxs
--------------------------------------------------------------------------

apxsの場所を確認しておきましょう。

というのも、Makefileでは以下のようにapxsの場所が指定されているので、
この指定先が実際のapxsの場所と違うとインストールの際にエラーが出るのです。

cd /usr/local/src/mod_dosdetector/

cat Makefile
--------------------------------------------------------------------------
(抜粋)
#   the used tools
APXS=/usr/sbin/apxs
APACHECTL=apachectl
--------------------------------------------------------------------------

よって、以下の通り変更。

vi Makefile
--------------------------------------------------------------------------
APXS=/usr/sbin/apxs
↓
APXS=/usr/bin/apxs
--------------------------------------------------------------------------

さて、ようやくインストールです。
まずはなにかあったときのために、confファイルをバックアップ

cp -p /etc/httpd/conf/httpd.conf{,_`date "+%Y%m%d"`}

そして、満を持してインストール!

make install
--------------------------------------------------------------------------
(略)
chmod 755 /usr/lib64/httpd/modules/mod_dosdetector.so
[activating module `dosdetector' in /etc/httpd/conf/httpd.conf]
--------------------------------------------------------------------------

だららららーっと出て、とくにエラーが起きていなさそうであればOKです。

これでmod_dosdetectorがインストールできました!
勝手に読み込む設定を入れてくれています。助かる。

diff -s /etc/httpd/conf/httpd.conf{_`date "+%Y%m%d"`,}
--------------------------------------------------------------------------
54a55
> LoadModule dosdetector_module /usr/lib64/httpd/modules/mod_dosdetector.so
--------------------------------------------------------------------------

mod_dosdetectorの設定

さて、インストールだけしても仕方ないので、設定をこちょこちょいじっていきます。

やりたいこと

5秒間に10回以上のアクセスがあった場合、DoS攻撃と判定して20秒間403エラーを返すようにする。

※今回は、あとで検証するのが楽になるのでかなり厳しめ検知するようにしています。
※実際に使用する際は、通常アクセスが遮断されないように気を付けてください。


設定を記載するファイルを個別で用意すると便利なので、作りましょう。

vi /etc/httpd/conf.modules.d/dosdetector.conf
--------------------------------------------------------------------------
<IfModule dosdetector_module>
  DoSDetection on
  DoSPeriod 5
  DoSThreshold 5
  DoSHardThreshold 10
  DoSBanPeriod 20
  DoSTableSize 600
  DoSIgnoreContentType ^(image/|application/|text/javascript|text/css)
</IfModule>
--------------------------------------------------------------------------

それぞれの設定値の意味は以下の通りです。

設定名 設定の意味
DoSDetection 設定のon/off
DoSPeriod アクセス数カウント期間(秒)
DoSThreshold DoSPeriodの期間中に指定したアクセス数があると、「SuspectDoS」判定
DoSHardThreshold DoSPeriodの期間中に指定したアクセス数があると、「SuspectHardDoS」判定
DoSBanPeriod 「SuspectDoS」判定が持続する期間(秒)
DoSTableSize アクセス数をカウントするIPアドレスの数
DoSIgnoreContentType アクセス数カウントに含まないコンテンツタイプの指定(MIME typeで)

ちょっとややこしいですが、今回の設定イメージはこんなかんじ↓

・5秒間に5回以上アクセスがあると対象IPは「SuspectDoS」に判定される。
 →「SuspectDoS」判定は20秒で解除される。
・5秒間に10回以上のアクセスがあると対象IPは「SuspectHardDoS」に判定される。
 →アクセスが5秒以上途切れたら「SuspectHardDoS」判定は解除される。
・アクセス数をカウントするIPアドレスの数は600個で、それ以上増えると古いものから忘れていく。
・image/|application/|text/javascript|text/cssへのリクエストは数に数えない。

今回は、DoS攻撃と判定した場合に20秒間ずっとエラーを返すかたちにしたいので、
それを実現するために「SuspectDoS」判定しか使いません。

というのも、「SuspectDoS」と「SuspectHardDoS」では、上記の通り仕様が違うのです。
私はこの仕様の違いにかなり苦しめられました……;;;;

仕様の違いについて参考になったURL↓
mod_dosdetector でDoS対策, BANが予定よりも早く解除される

DoS攻撃と判定した際の挙動設定

さて、もろもろ設定しましたが、これだけではDoS攻撃が来ても対処はできていません。
あくまで、DoS攻撃を検出してくれるようになっただけです。

そこで、DoS攻撃を検出した際の挙動を設定していきます。
今回は403エラーを返すように設定します。

vi /etc/httpd/conf.d/virtual.conf
--------------------------------------------------------------------------
<VirtualHost *:80>
ServerName monikura.com
ServerAdmin root@localhost
DocumentRoot /var/www/monikura.com

↓↓追加↓↓
# dosdetector_module
RewriteEngine On
RewriteCond %{ENV:SuspectDoS} =1
RewriteCond %{REMOTE_ADDR} !127.0.0.1
RewriteRule .*  - [R=403,L]
↑↑追加↑↑
</VirtualHost>
--------------------------------------------------------------------------

これで、「SuspectDoS」判定されたIPには403エラーを返すようになります。

なお、Apacheのデフォルト設定では403エラーを出すと
Apacheテストページが表示されるようになっています。
ちょっといやなのでそこの設定も変更。

vi /etc/httpd/conf.d/welcome.conf
--------------------------------------------------------------------------
↓の通り変更
ErrorDocument 403 /error/noindex.html
--------------------------------------------------------------------------

設定適応のためにApache再起動

systemctl restart httpd

以上で設定が完了したので、ちゃんとmod_dosdetectorが働いているか検証していきましょう!

検証

ログを出しつつアクセスし、F5連打。

tail -f /var/log/httpd/access_log
--------------------------------------------------------------------------
 [27/Oct/2022:03:25:48 +0000] "GET / HTTP/1.1" 304
 [27/Oct/2022:03:25:48 +0000] "GET / HTTP/1.1" 304
 [27/Oct/2022:03:25:49 +0000] "GET / HTTP/1.1" 304
 [27/Oct/2022:03:25:49 +0000] "GET / HTTP/1.1" 304
 [27/Oct/2022:03:25:49 +0000] "GET / HTTP/1.1" 304
--------------------------------------------------------------------------


とんとんとんとんとん……


tail -f /var/log/httpd/access_log
--------------------------------------------------------------------------
 [27/Oct/2022:03:25:49 +0000] "GET / HTTP/1.1" 404
 [27/Oct/2022:03:25:51 +0000] "GET / HTTP/1.1" 404
 [27/Oct/2022:03:25:52 +0000] "GET / HTTP/1.1" 404
 [27/Oct/2022:03:25:52 +0000] "GET / HTTP/1.1" 404
 [27/Oct/2022:03:26:08 +0000] "GET / HTTP/1.1" 404
 [27/Oct/2022:03:26:08 +0000] "GET / HTTP/1.1" 404
--------------------------------------------------------------------------

エラーが返りました!
5秒以上あいてもエラーのままであることも確認。

tail -f /var/log/httpd/access_log
--------------------------------------------------------------------------
 [27/Oct/2022:03:25:49 +0000] "GET / HTTP/1.1" 404
 [27/Oct/2022:03:25:51 +0000] "GET / HTTP/1.1" 404
 [27/Oct/2022:03:25:52 +0000] "GET / HTTP/1.1" 404
 [27/Oct/2022:03:25:52 +0000] "GET / HTTP/1.1" 404
 [27/Oct/2022:03:26:08 +0000] "GET / HTTP/1.1" 404
 [27/Oct/2022:03:26:08 +0000] "GET / HTTP/1.1" 404
 [27/Oct/2022:03:26:10 +0000] "GET / HTTP/1.1" 200
 [27/Oct/2022:03:26:11 +0000] "GET / HTTP/1.1" 304
 [27/Oct/2022:03:26:12 +0000] "GET / HTTP/1.1" 304
--------------------------------------------------------------------------

そして、約20秒後に復活しています。

cat /var/log/httpd/error_log
--------------------------------------------------------------------------
[Thu Oct 27 03:25:49.867368 2022] [:notice] [pid 3359] dosdetector: 'XXX.XXX.XXX.XXX' is suspected as DoS attack! (counter: 6)
--------------------------------------------------------------------------

エラーログにDoS攻撃を検出したログも出ています。
ばっちりですね。

あとがき

単純で使いやすいmod_dosdetectorでした。
使えるタイミングはそこそこありそうです。

返信を残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA