エラーの修正

WordPressサイトにFail2banを導入したのに Total banned: 0 のまま——これは故障ではなく、正常な状態であることのほうが多い。ban数は「守れているか」の指標として使えないからだ。突破されていないかは別の場所を見る。

ban数ではなくwp-loginのレスポンスコードを見る

知りたいのは「ログインを突破されていないか」であって「何件banしたか」ではない。アクセスログで POST /wp-login.php のレスポンスコードを数えれば、突破の有無が直接わかる。

grep "POST /wp-login.php" /path/to/logs/access.log | awk '{print $9}' | sort | uniq -c

Basic認証やIP制限を手前に置いていれば、ここは 401403 だけが並ぶ。WordPressの認証画面まで到達していない状態だ。200 はログイン失敗(フォーム再表示)、302 はログイン成功を意味する。心当たりのないIPからの302が出たら、それが本当の警戒シグナルになる。ban数を毎日眺めるより確実だ。

ban 0 が正常になる2つのパターン

Fail2banは「一定時間内に同じIPが規定回数失敗したらban」という仕組みなので、その条件が成立しなければ何もしない。

手前の防御が全部止めている場合。 Basic認証やIP制限を通過できないリクエストは、WordPressの認証処理に届かない。攻撃は来ているが、Fail2banの出番が来ていないだけだ。

攻撃が成立し得ない場合。 SSHで PasswordAuthentication no にしていれば、パスワード総当たりは試行そのものが成立しない。この状態のsshdジェイルは検知数も0になる。

検知数を見れば故障かどうか切り分けられる

とはいえ「設定ミスでログを読めていない」可能性は潰しておきたい。fail2ban-client status <ジェイル名>Total failed(検知数)とban数を組み合わせれば切り分けられる。

検知数 ban数 判断
0 0 攻撃が来ていないか、filter・logpathがずれている
多い 0 検知はできている。閾値に届いていないだけ
多い あり 正常に機能している

攻撃が確実に来ているはずのジェイルで検知数が0なら、filterの正規表現かlogpathを疑う。検知数が数百件あってban 0なら、Fail2banは正しく動いている。

注意したいのは、このコマンドがジェイルを1つずつしか表示しないことだ。 実際に私は、3つあるジェイルのうち2つだけを見て「機能していない」と判断しかけた。fail2ban-client status(ジェイル名なし)で一覧を出したところ、見ていなかった3つ目が21件banしていた。監視対象から漏れたジェイルは存在ごと視界から消える。まず一覧を出す。

閾値に届かないのは分散型総当たりだから

検知数が多いのにban 0 になるのは、攻撃側が1IPあたりの試行回数を抑えているからだ。ログを集計すると、1日に来た8つのIPがすべて1回ずつPOSTしていた。maxretry = 5 にはどう転んでも到達しない。

大量のIPを使い捨てて1回ずつ試す手口には、回数ベースの対策が構造的に効かない。閾値を下げれば数字上のbanは増えるが、正規ユーザーの打ち間違いを巻き込むほうが実害が大きい。この手の攻撃はFail2banを調整するより手前で止めるほうが有効で、止まっているかどうかは冒頭のレスポンスコードで確認できる。

日本発!ECオープンプラットフォーム「EC-CUBE」 EC-CUBEゴールドパートナー EC-CUBEは株式会社イーシーキューブの商標です

カスタマイズに関するお問い合わせはこちら