日報 #79 - mod_dosdetectorの導入
超絶ナチュラルに昨日サボりましたが、
俺あるあるですので、気にせず。
さて、実はサーバの根幹部分に色々手を加えておりまして、
ストレスフルな日々でございます。
なんか知らないけど、いつまでだってもLoadAverageが「やや高い(問題があるレベルじゃない)」という、
生ぬるくいじめられている感じです。
メモリのcacheが増えたり、apcのキャッシュが貯まれば落ち着くのでしょうか…
さて、本日はUbuntuのapacheにdosdetectorをぶっこむ作業について共有いたします。
DoS対策にはmod_evasiveとmod_dosdetectorがあるようですが、
前者はプロセス毎へのアクセス回数でみているらしいので、
使うなら後者がよいということでそうします。
あと、LBやリバースプロキシのようなものをつかってWebサーバへの直近アクセスが固定されているような時は、
forwardのIPをとってこなくてはならないので、その辺の対策ようにmod_extract_forwardedも導入します。
とはいえ、dosdetectorの設定をみるとDoSForwardedという項目があるので、もしかしたら対応しているかもしれません。
正確には確認してませんが。
でもまぁどの道、既存のLogFormatなどでもフランクにRemoteIPを使うので、
フォワードにしておくのは意味のあること判断して導入します。
まず、mod_extract_forwardedから。
このサイトのとおりでございます。別段触れることありません。
patchコマンドの書き方を勉強した程度です。
MEFacceptの設定はELBならallにしておく必要があります。
ELBのIPは信じてはいけませんので。
続いてメインのdosdetectorです。
dosdetector-forkなる改造版もあるようですが、最終コミットが6年前とかなので、
本家を使うのが吉ということで、そっちのgitからいきます。
cd ~ git clone https://github.com/stanaka/mod_dosdetector.git cd mod_dosdetector cp Makefile Makefile_buckup sed -i -e "s/APXS=\/usr\/bin\/apxs/APXS=\/usr\/bin\/apxs2/g" Makefile sed -i -e "s/APACHECTL=apachectl/APACHECTL=apache2ctl/g" Makefile
後半いじってるのは、apachectlの仕様とapxsの仕様に合わせて変えないとダメです。
Make過程でapacheにa2enmodするのと、apache再起動をするときにサービス名を使うみたいなので。
んで、あとはapache2.confに書き加える設定。
<IfModule mod_dosdetector.c> # 使うならオンにしましょう DoSDetection on # DoS攻撃判定をする為の計測時間 DoSPeriod 1 # DoSPeriodの間にDoS攻撃の嫌疑をかけるアクセスカウント(ちなみにこれを突破したら変数SuspectDoSが1になる) DoSThreshold 20 # DoSPeriodの間にDoS攻撃と確定するアクセスカウント(変数SuspectHardDoSが1になる) DoSHardThreshold 30 # DoS攻撃認定されてから解除までの時間(秒) DoSBanPeriod 60 # このモジュールが一部使うメモリの名前?よく分からん DoSShmemName dosshm # 嫌疑をかけるIPの保存数 DoSTableSize 100 # X-Forwarded-For headerをIPとして扱うかどうかのチェック DoSForwarded on # 無視リスト。ここではjsとcssと画像全部 DoSIgnoreContentType (image/|text/css|text/javascript) </IfModule>
さて、dosdetectorのいいところは、DoSと判定したら変数SuspectDos(またはSuspectHardDoS)を1にするだけのところ。
その後の対応はこちらで自由に設定できます。
で、大体503とかに飛ばすと思うのだけど、
普通VirturalHostのDirectory領域にRewriteを書いていると思うのでそこに追記します。
例えば、/etc/apache2/sites-avairableのdefaultとかに記載されているRewrite部分にRewriteCondを挿入します。
要は条件分岐させます。
# for DoS attack RewriteCond %{ENV:SuspectDoS} .+ [OR] RewriteCond %{ENV:SuspectHardDoS} .+ # クラスAのローカルIPアドレス帯を全て除外 RewriteCond %{REMOTE_ADDR} !^(10\.[0-9]+\.[0-9]\.[0-9])$ # クラスBのローカルIPアドレス帯を全て除外 RewriteCond %{REMOTE_ADDR} !^(172\.(1[6-9]|2[0-9]|3[0-1])\.[0-9]+\.[0-9]+)$ # クラスCのローカルIPアドレス帯を全て除外 RewriteCond %{REMOTE_ADDR} !^(192\.168\.[0-9]+\.[0-9]+)$ # 対クローラー排除 RewriteCond %{HTTP_USER_AGENT} !(google|yahoo|msn|bing) [NC] RewriteRule .* - [R=503,L]
ずらずらとCondを並べ立てて、最終的に
RewriteRule .* - [R=503,L]
しています。503に飛ばせということですね。
以上、すげーシンプルかつ簡単なDoS対策でした。
DDoSに対してはまた別途対策が必要なので、のちほどー。
疲れたぜ…まだロードアベレージ高い…どうにかならんかね、このじゃじゃ馬。