サーバのアクセス数を munin で監視しているんだけど、apache のアクセス数グラフをみたら過剰アクセスを発見した。グラフは先週の様子。土曜から日曜にかけてがいちばん酷い。これはDoS攻撃だよな。
ということで対策を行った。まずは mod_dosdetector をつかってみた。
mod_dosdetector は apache 用の Dos 対策モジュール。インストールは簡単。
$ cd /usr/local/src $ wget https://github.com/stanaka/mod_dosdetector/archive/master.zip -O mod_dosdetector.zip $ unzip mod_dosdetector.zip $ cd mod_dosdetector-master $ make $ make install
httpd.conf に以下が追記されていることを確認。
LoadModule dosdetector_module /usr/lib64/httpd/modules/mod_dosdetector.so
httpd を restart して dosdetector_module がロードされていればOK。
$ service httpd restart $ httpd -D DUMP_MODULES | grep dos dosdetector_module (shared) Syntax OK
httpd.conf に dosdetector 設定を書いてもいいけれど、メンテナンス性を考えて別ファイル( /etc/httpd/conf.d/dosdetector.conf
)にした。設定内容は以下の通り。
# dosdetecotr を有効に DoSDetection on # 10秒間で # 12回同一IPからアクセスがあったら環境変数「DoSThreshold」をセット # 15回同一IPからアクセスがあったら環境変数「DosHardThreshold」をセット DoSPeriod 10 DoSThreshold 12 DoSHardThreshold 15 # セットした環境変数がクリアされるまでの秒数を指定(3600秒 = 60分) DoSBanPeriod 3600 # 保持するIPの履歴を指定。 # 最初は100にしたんだけどすぐいっぱいになってしまうようで3000まで増やした DoSTableSize 3000 # 判定から除外するMIMEタイプを指定 DoSIgnoreContentType ^(image/|application/|text/javascript|text/css)
dosdetector はアクセス自体は遮断せずに環境変数を設定する。なので、mod_rewrite を使って .htaccess に以下のような設定を書く。
# 環境変数に SuspectHardDoS が設定されていたら 404 not found を返す RewriteEngine On RewriteCond %{ENV:SuspectHardDoS} =1 RewriteRule .* - [R=404,L] ErrorDocument 404 "404 not found" AddType image/vnd.microsoft.icon .ico
実際のログ。IPやパスは書き換えているけれど、あるタイミングで 404 を返すようになった。ザマーみろ。
219.xxx.xxx.xxx - - [24/Dec/2017:03:24:19 +0900] "POST /path/to/example.php?p=123 HTTP/1.1" 200 6230 219.xxx.xxx.xxx - - [24/Dec/2017:03:24:19 +0900] "POST /path/to/example.php?p=123 HTTP/1.1" 200 6230 219.xxx.xxx.xxx - - [24/Dec/2017:03:24:19 +0900] "POST /path/to/example.php?p=123 HTTP/1.1" 200 6230 219.xxx.xxx.xxx - - [24/Dec/2017:03:24:19 +0900] "POST /path/to/example.php?p=123 HTTP/1.1" 404 13 ← このタイミングから 404 を返している 219.xxx.xxx.xxx - - [24/Dec/2017:03:24:19 +0900] "POST /path/to/example.php?p=123 HTTP/1.1" 404 13 219.xxx.xxx.xxx - - [24/Dec/2017:03:24:19 +0900] "POST /path/to/example.php?p=123 HTTP/1.1" 404 13 219.xxx.xxx.xxx - - [24/Dec/2017:03:24:19 +0900] "POST /path/to/example.php?p=123 HTTP/1.1" 404 13
ただ、これだとアクセス自体は httpd に到達している。どうせなら httpd に届く前段階で遮断したい。ということで次は iptables をいじって対応。
iptables を更新するには呪文みたいなコマンドを書かなきゃいけなくて俺はこれが苦手。だからいつも system-config-firewall-tui という簡易GUIを使っている。今回はこれにカスタムルールを追加して対応する。
以下の内容でカスタムルールファイル( /root/work/iptables/drop.conf
)を作成した。
# IPアドレス 219.xxx.xxx.xxx と 122.xxx.xxx.xxx からのアクセスは DROP -I INPUT -s 219.xxx.xxx.xxx -j DROP -I INPUT -s 122.xxx.xxx.xxx -j DROPsystem-config-firewall-tui コマンドを実行、カスタムルールに上記ファイルを設定する。
$ system-config-firewall-tui ↓ カスタマイズを選択 ↓ 転送、転送、転送... ↓ カスタムルールを「追加」 ↓ プロトコルタイプ :ipv4 ファイアウォールテーブル:filter ファイル :/root/work/iptables/drop.conf ↓ OK、閉じる
エラーが出ずに iptables が更新されていればOK。これで特定IPアドレスからのアクセスは遮断できる。
しかし、これでは攻撃元IPアドレスが変わるたびに更新が必要。めんどくさい…、と思ったら iptables でも DoS対策ができるらしい。
(あとで書く)