_ 最近話題になってる Apache その他に対する DoS 攻撃ツール slowloris。中途半端なリクエストヘッダを送って、宙ぶらりんのままの HTTP セッションを大量に生成させてサーバ側のリソースをパンクさせる、という理屈らしい。消化しきれない中途半端なリクエストを Apache が食おうとしてるのが原因ってことだから、ちゃんと消化できる状態になるのを待ってから Apache に食わせるようにしてやればこの攻撃にも耐えられるよね、きっと。
_ ということで試してみた。 AcceptFilter。FreeBSD で AcceptFilter http httpready と設定すると、accf_http(9) を利用してカーネルレベルで HTTP リクエストをバッファリングして、リクエスト全体を受信完了するまで apache にリクエストを渡さない。つまり、この攻撃を食らっても、カーネルで止まって apache までは到達しないので DoS は成立しない、はず。
_ 結果。目論見どおり、FreeBSD 7.1 + Apache 2.2.11 で slowloris の攻撃に耐えられました。httpready が無効な状態だとあっとゆーまに server-status が R (Reading Request) でいっぱいになって新規の接続を受けつけなくなったけど、有効にするとふつーにアクセスできて、server-status を見てもスカスカでとーぜん R はひとつもなし。中途半端なリクエストが apache に到達しないといっても、今度はカーネルの方で中途半端なリクエストを大量にバッファリングすることになるからそっちの方に影響が出るかも、と思ったんだけど、長時間攻撃を続けていても目立った影響はなし。ほんとにまったく問題ないのかは不明。
_ うわー FreeBSD えらいー、こいつを使えば問題ないね☆、ということで話が済めばいいんだけど、そう甘くはなかった。slowloris の側でも httpready を回避するというオプションがあって、それを使うと FreeBSD でも陥落。中身を見たら GET ではなく POST でリクエストするということ以外の違いはない。調べてみたら accf_http の方が GET/HEAD にしか対応してなかった。
_ まあ POST ではダメといっても GET での攻撃に耐えられるだけでもずいぶんマシだし、今回の DoS とはまったく関係なくパフォーマンスが向上するという利益もあるので、accf_http を有効にしておいて損はないだろう。
_ なお、HTTPS で AcceptFilter https dataready (accf_data) がどうなるかは試してないけど、その仕組みから考えて効果はないはず(HTTPS ではなく HTTP で dataready にしても死んだし)。試してみるまでもなく Linux の AcceptFilter http data も同じように効果なし(そして試してみた結果やはり陥落)。
_ slowloris 対抗モジュール。……なんだけど、うーん。
_ 3種類の方法で防御してるんだけど、そのうちふたつは攻撃側で回避可能。実際にこのモジュールを組み込んだ apache に対して改造版 slowloris で攻撃して DoS が成立するところまで確認済み。詳細は書きません。作者には連絡済み。
_ 無改造の slowloris ならちゃんとひっかかって蹴るし、そうでなくても残りのひとつはちゃんと効くのでまあ当面は大丈夫そうではあるけど、今後ボットネットあたりに slowloris が組み込まれるようなことがあれば、そのときは最後の砦も突破されてこのモジュールは意味なしってこと。
_ 終了しないリクエストをいつまでも待ち続けるという根本的な問題を修正するモジュールではないのでどうしようもないのかなぁ。つーか、この攻撃に耐えられる IIS とか lighttpd とかって、どんな理屈で弾いてんのかね?