Displaying posts tagged with

“Apache”

mod_dosdetector の使い方

サーバ/インフラを支える技術』で知ったDoS攻撃判定モジュール mod_dosdetector の使い方。mod_dosdetecotr のバージョンは 0.2、環境は Apache 2.2.3 @ CentOS 5。

改造版も公開しています。

インストール

wget http://ncu.dl.sourceforge.net/sourceforge/moddosdetector/mod_dosdetector-0.2.tar.gz
tar xvzf mod_dosdetector-0.2.tar.gz
cd mod_dosdetector-0.2
make
sudo make install

httpd.conf 設定例

# 実際にはこの一行は make install で追加される
LoadModule dosdetector_module modules/mod_dosdetector.so
 
DoSDetection     on
DoSPeriod        5
DoSThreshold     10
DoSHardThreshold 25
DoSBanPeriod     30
DoSTableSize     100
DoSIgnoreContentType  image|javascript|css

DoS判定の肝となる数値は DoSPeriod, DoSThreshold, DoSHardThreshold, DoSBanPeriod の4つで、上の例ではだいたい次のような意味になる:

  1. 同一IPアドレスから5秒間に10回以上のアクセスがあった場合「DoS攻撃の疑いあり」と見なし、その後30秒間のアクセスに対しては環境変数 SuspectDoS をセットする(値は”1″)
  2. さらに5秒間のアクセス回数が25回に達した場合、「激しいDoS攻撃の疑い」と見なし、環境変数 SuspectHardDoS もセットする(値は”1″)
  3. 初めに「DoS攻撃の疑いあり」と判定してから30秒が経過したら、次のアクセスでもう一度判定をやり直す。直近5秒のアクセスが10回を下回っていれば、疑いは晴れる

アクセス数の計測はファイルの種類・有無を問わずに行われるため、デフォルトではページ内の画像やCSSなども計測対象となってしまう。それらを除外したい場合は、DoSIgnoreContentType ディレクティブで除外したいファイルの MIME type を正規表現で指定しておく(ファイル名(URL)ではないので注意)。各種画像ファイル・JavaScript・CSSファイルを除外したい場合は上例のように設定しておけば良い。

ただし多くの環境では拡張子 ico に対する MIME type の指定は行われていないはずなので、そのままだと favicon.ico が text/plain 等と見なされて除外されない(.ico に限らず、未設定の場合は httpd.conf の DefaultType になる)。次のように AddType を追加しておけば image と判定される。

AddType  image/vnd.microsoft.icon  .ico

ちなみにこれがアイコンファイルの正式な MIME type である。

DoS攻撃に対する防御設定

mod_dosdetector が行うのはあくまでも攻撃の”検出”だけなので、防御する方法はまた別に設定する必要がある。多くの場合は mod_rewrite と併用することになるだろう。例えば「激しいDoS攻撃の疑い」なアクセスに対してステータスコード503 + 静的なHTMLを返す場合は次のように設定する(Apache 2.2 only)。

RewriteEngine On
RewriteCond %{ENV:SuspectHardDoS} =1
RewriteRule .*  - [R=503,L]
 
ErrorDocument 503 /server_is_busy.html

しかし現実には、攻撃の判定とその後の防御は、匙加減が難しい。どの程度のアクセスを攻撃と見なすかはサイトによって千差万別だろうし、あまりに頻繁・過剰な反応をしてしまうとユーザが離れてしまう。

そこで個人的には、まず厳し目の設定を行って、ログを取ってみることをおすすめする。「DoS攻撃の疑いあり」なアクセスを普通のログと分けて記録するには次のように設定する。

LogFormat "%{SuspectHardDoS}e %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" dos_suspect
CustomLog logs/dos_suspect_log dos_suspect env=SuspectDoS

ログの行頭に環境変数 SuspectHardDoS が記録されるため、どのような経過をたどって「疑いあり」から「激しい攻撃の疑い」へと移行したかも分かる。

後はこの記録を見つつ、通常のアクセスが引っかからないような適当な設定を探ることになる。もしサーバリソースの都合上、どうしても通常のアクセスが引っかてしまう可能性があるのなら、その時は防御方法をより穏当なものに設定することもできる(このあたりの柔軟性は mod_dosdetector の設計の妙だと思う)。

その他

上で触れなかったディレクティブについて少々:

DoSDetection
DoS判定機能の有効・無効を設定。on で有効
DoSTableSize
クライアントの追跡記録の最大保存数。この数値を大きくすればより多くのクライアントを同時に追跡できるが、メモリ使用量と負荷が上昇する
DoSShmemName
クライアントの追跡記録を保存しておくための共有メモリの名前。普通は設定する必要は無いはず

最後に

素晴らしいソフトウェアをオープンソースとして公開してくださった田中慎司さん(そして株式会社はてな)に感謝!

Apache 2.2ではmod_rewriteのRフラグで任意のステータスコードを返せる

昔Apache 2.0系で試したときは無理だったのに、2.2系ではできるようになっていたのか。

mod_rewriteで503 – Do You PHP はてな

上エントリーで引用されているドキュメントは古くて、現在は次のような記述に置き換わっている。

While this is typically used for redirects, any valid status code can be given here. If the status code is outside the redirect range (300-399), then the Substitution string is dropped and rewriting is stopped as if the L flag was used.

mod_rewrite – Apache HTTP Server

『このフラグは通常リダイレクトのために用いられるが、任意の妥当なステータスコードを指定することができる。もしリダイレクト以外のステータスコード(すなわち300〜399以外)が指定された場合、置換文字列は無視され、さらにLフラグが指定されたときと同じようにURLの書き換えが停止される。』

つまりリダイレクトもURLの書き換えも行われないので、デフォルトのエラー画面以外を表示するには ErrorDocument ディレクティブで指定しておく必要がある。

RewriteEngine On
RewriteCond %{some_condition} =1
RewriteRule .*  - [R=503]
 
ErrorDocument 503 /server_is_busy.html

ソースに付属している文書(CHANGES)によれば、この仕様に変わったのはバージョン2.1.1。Bugzillaで以下のような議論も見つけた。

In the <300, >=400 cases, one can think of this as [R{esponse}=nnn} as opposed to [R{edirect}], and it really harms nothing to overload it.

Bug 45478 – R flag in RewriteRule does not honor 400 and 500 range error code

Redirect の ‘R’ ではなく Response の ‘R’ と見なしてくれ、と。なるほど…。