Help us understand the problem. What is going on with this article?

apacheのmod_dosdetectorでDos(F5アタック)対策

More than 3 years have passed since last update.

方式

apacheで同一IPアドレスからの連打を検出した場合アクセスを拒否するか、
特定の静的なページに飛ばすことでサーバの負荷を低減させる。

有名なのは下記の2つだが、今回は mod_dosdetector を選択した。

mod_evasive

即アクセス禁止になるため、特定のエラーページ等への遷移ができない(かもしれない)。
目的からすれば充分だが、エンタープライズでは
意図せぬ連打(F5の上に本置きっぱなし状態とかも)した顧客に
いきなり403を見せるというのは結構キツイ。

何より、apacheをpreforkで動かしている場合
子プロセス単位の個別でアクセス数がカウントされるため
(サーバ単位でアクセスをカウントしてくれないため)
httpサーバやpreforkの設定次第では、結構連打したけど防いでくれないとか、普通にあり得る。

mod_dosdetector

こちらは同一IPから一定時間内に一定数以上のアクセスを検知したら
環境変数を立ててくれるだけ。二段階方式で環境変数をみてのアクセス制御をいれなくてはならない。

多少面倒だが、融通は効く形式になるしpreforkでもきちんと動く。

mod_dosdetector をインストール

$ wget http://ncu.dl.sourceforge.net/sourceforge/moddosdetector/mod_dosdetector-0.2.tar.gz
$ tar -xzvf mod_dosdetector-0.2.tar.gz
$ cd mod_dosdetector-0.2
$ make
$ make install
Libraries have been installed in:
   /usr/lib64/httpd/modules

apacheの設定

1分間に100回アクセスがあれば、Dos攻撃とみなす設定の例。

httpd.conf
LoadModule dosdetector_module /usr/lib64/httpd/modules/mod_dosdetector.so

# 検出を行うかを指定。ここをoffにしてapache再起動で無効化可能
DoSDetection     on

# 連打の検出をカウントする秒数を指定。以下は1分間。
DoSPeriod        60

# Dosの疑いありの閾値を設定、現在は利用していない。
# 「DosHardThreshold」に合わせておく。以下は100回アクセスで疑いありとみなす。
# 閾値に達すると環境変数SuspectDoS=1がセットされる
DoSThreshold     100

# Dosとして明確にみなすの閾値を設定。判定はこれを利用している。
# 800回アクセスでDos攻撃とみなす。
# 閾値に達すると環境変数SuspectHardDoS=1がセットされる
DoSHardThreshold 100

# 閾値に到達してからセットした環境変数がクリアされるまでの秒数を指定。
# 以下は5秒で判定を解除し、再判定に入ることを示す。
DoSBanPeriod     5

# 保持するIPの履歴を指定。
# 実際のIP種類は下記設定より遥かに多いが
# Dos判定に利用する=連続でリクエストが来るため、さしあたって3000で設定。
DoSTableSize     3000

# 判定から除外するMIMEタイプを指定
DoSIgnoreContentType  image|javascript|css

これで設定は終わるが・・・
あくまで環境変数立てるだけなんで、連打を検出した振る舞いを続けて入れてみる。

httpd.conf
## 連打対応
# ドメインを指定
RewriteCond %{HTTP_HOST} www\.foo\.co\.jp

# Dos攻撃判定(上記で設定される)を確認
RewriteCond %{ENV:SuspectHardDoS} .+

# 対象外のURL指定したければここで
RewriteCond %{REQUEST_URI} !^/hoge/.* [NC]

# 同じようにDos検出時に遷移させるページも当然除外
RewriteCond %{REQUEST_URI} !^/error/dos.page [NC]

# Dos判定されたらエラーページに飛ばしてあげる
# /inner で始まるUELは社内とかアクセス用なので除外とかも設定できる
RewriteRule !^/inner/(.*) http://xx.xx.xx.xxx/error/dos.page [P,L]

apacheの再起動で終わり

$ service httpd restart

補足

DOS攻撃を防ぎたいくらいの規模の場合は
数台のWeb(httpd)サーバをLBで繋いでいる環境が殆どだ思う。

上記の設定はあくまで1台単位なので、
LBを介した クライアント と Web(httpd)サーバ 間の接続が
stickinessなのか、Round Robinなのか確認して閾値を設定する必要がある。

もしRound Robinの場合は多少雑だが
(防ぎたい回数の閾値 / サーバ台数) の値を各apacheに設定するのが良いと思う。

あと、エンタープライズで、企業ユーザの場合は
大抵企業から外に出るグローバルIPアドレスは1つ(ないし数個)なので
これは個人単位ではなく、企業単位のアクセス制限になる、ということは意識しておくと良い。

hakozaki
B2Bの商取引を電子化するプラットフォーマー(サービスプロバイダ)の会社で 自社の技術系ラボの責任者をしております。 新規事業やFintechプラットフォームの実現にむけて AI(ML)やブロックチェーンを用いた技術基盤の構築や協業での実証検証を主に行っています。 技術のこと・ビジネスのこと・これからの業界の動向のこと 色々情報交換させて頂ければ幸いです。
infomart
40万社以上の企業に商取引を電子データ化して効率化・利便性をもたらすBtoBプラットフォームを提供しています。
https://www.infomart.co.jp/index.asp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away