さくらのVPS・KUSANAGI環境のFail2BanでDoS対策をする

さくらのVPSで利用できる仮想マシンのKUSANAGI。このKUSANAGIでは、セットアップした時点でFail2Banというツールを利用できる。ただし、初期段階で有効になっているのはSSHへの攻撃のブロックのみ。ウェブサーバに負荷をかけるDoS攻撃などはそのまま受け入れてしまう。

Dos攻撃を遮断するために解説サイトと同じようにFail2Banを設定しても、KUSANAGI環境では想定する動作はしてくれない。これはKUSANAGIのログフォーマットが特殊なために、Fail2Banのフィルター定義に一致しないから。Fail2Banのjailファイルやフィルターを作る前に、ログを一般的なフォーマットに変更する必要がある。

このページでは以下の環境

  • サーバはさくらインターネットのVPS
  • OSはKUSANAGI(CentOS7ベース)
  • ウェブサーバはApache(httpd)

で、Fail2Banを動作させるための設定や操作を説明する。

1. Apacheのログフォーマットの変更

まずはSSHでサーバに接続して、httpd.conf(Apacheの設定ファイル)をバックアップしておく。
cp /etc/httpd/httpd.conf /etc/httpd/httpd.conf.backup

このhttpd.confの47行目行頭の#(コメントアウト)を外し、48行目を#でコメントアウトする。

新しいフォーマットでログを記録させるために、Apacheを再起動する。
systemctl restart httpd

Apacheの再起動後、アクセスログのフォーマットが変わったことを確認するとともに、アクセスログのパスを確認しておく。
tail -f /home/kusanagi/(KUSANAGIのプロファイル名)/log/httpd/access.log

サイト全体を常時https化している場合は、パスの最後がssl_access.logになるので注意。

2. no_logの編集

KUSANAGIのアクセスログはページへのアクセスのみが記録され、ページに埋め込まれたファイル(画像やCSS、JavaScriptなど)へのアクセスは記録しない設定になっている。が、WordPressのテーマによっては、あらかじめ指定された拡張子以外のファイルも読み込むものがある。

アクセスログをよく確認し、そういったファイルが見つかった場合は、上で編集したhttpd.confのno_logの定義に拡張子を追加する。

56行目の拡張子が書かれている箇所に |(拡張子) の形式で追加する。

自分の環境ではウェブフォントの拡張子(woff2形式)を追加する必要があった。アクセスログをリアルタイム表示(tail -f)しながら、ブラウザでページを表示させると見つけやすい。重要なのは一度のアクセスでログが1行だけ記録されるようにすること。

Apache再起動後にサイトへアクセスして、ログフォーマットの変更が適用されたことを確認する。
systemctl restart httpd

tail -f /home/kusanagi/(KUSANAGIのプロファイル名)/log/httpd/access.log

3. jail.conf の複製と編集

ここからはFail2Banの作業となる。Fail2Banの設定ファイル、jail.confを複製してjail.localを作成する。
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.d/jail.local

作成したjail.localの任意の場所に、以下の記述を追加する。

自分の場合は216行目あたりの
#
# JAILS
#

のすぐ下に追加した。

この記述は、3秒間に10回のアクセスした接続元を600秒間(10分間)遮断して、それをメールで通知するというもの。3秒のあいだに10回のページ表示というと、かなり不自然なアクセスだ。bot的なプログラムや、人間であればF5アタックのような接続に該当する。

次に、apache-ddos.confという名前でフィルターのファイルを新規作成する。
vi /etc/fail2ban/filter.d/apache-ddos.conf

このapache-ddos.confに、以下の記述を貼り付けて保存する。
[Definition]
failregex = ^<HOST> .*"(GET|POST).*
ignoreregex =

failregexはIPアドレス(HOST)の位置を特定するための正規表現。

ignoreregexは除外する条件。アクセスログにページのURLだけでなく、ページに読み込まれたファイル(JavaScriptやcss、画像など)までログに記録される場合はここに拡張子を書くことになるが、httpd.confのno_logで定義しているのでここでは何も指定しない。

4. 動作テスト

これで準備は整った。Fail2Banを再起動して
systemctl restart fail2ban

3秒間に10回以上という条件に当てはまるようにF5アタックを試してみる。

Apacheの上のレベル(firewalld)でアクセスが遮断されるので、403 Forbidden などのエラーページは表示されず、webサーバ自体に接続できなくなる。

5. 関連コマンド

banされたIPアドレスの解除
fail2ban-client set apache-ddos unbanip (IPアドレス)

DoS攻撃を目的としたアクセスでなくとも、たとえばWordPressのダッシュボードで複数の画像を削除する場合などにFail2Banでブロックされる。その場合は上のコマンドで解除するか、/etc/fail2ban/jail.d/jail.localの50行目あたりにあるignoreipに除外するIPアドレスを記述する。IPアドレスが複数ある場合はスペース区切りで。
ignoreip = 127.0.0.1/8 0.0.0.0 1.1.1.1

fail2banの状態確認
systemctl status fail2ban

緑色の文字でactive (running)と表示されていれば、正常に動作している状態ということになる。