公開サーバーのSSHやログインフォームには,24時間休みなく総当たり攻撃が降り注ぐ.これを人間が監視して手動でブロックするのは不可能だ.そこで活躍するのがfail2ban── ログを見張り,攻撃元を自動で遮断する仕組みである.

fail2banの本質は,「ログに現れる攻撃の兆候を検知し,そのIPを一定時間ファイアウォールで遮断する」こと.人手をかけずに,攻撃を仕組みで断ち続けられる.

この記事は,公開VPSを運用する個人開発者,ログに並ぶ攻撃試行に不安を感じるエンジニアに向けている.導入から,jailの設計,SSH以外のサービスの保護,誤banの防止までを実践的に解説する.

読み終えたとき,あなたのサーバーは攻撃元を自動で締め出し,認証ログも静かになり,あなた自身は何もしなくてよい状態になっている.

なぜ自動ブロックが必要なのか

公開直後のサーバーの/var/log/auth.logを見ると,世界中のIPからのSSHログイン失敗が秒単位で並ぶ.これは例外ではなく,公開サーバーの日常だ.

鍵認証にしていれば総当たりは突破されないが,攻撃試行そのものはリソースとログを消費し続ける.放置すれば認証ログがノイズで埋もれ,本当に重要な兆候を見逃す.

fail2banは,「短時間に何度も失敗したIPを,自動で一定時間遮断する」.これにより攻撃試行が激減し,ログが静かになり,万一の弱点も突かれにくくなる.

そして一度設定すればあとは自動だ.人間の注意力に頼らず,仕組みで守り続ける── これが「疲れない防御」の考え方だ.

fail2banの仕組み ― ログ監視→jail→ban

fail2banの動作は3段階だ.(1)ログファイルを監視し (2)攻撃パターン(filter)に一致する行を検出し (3)条件を超えたIPをban(ファイアウォールで遮断)する

この一連を束ねる単位がjail(ジェイル)だ.「どのログを・どのパターンで・何回失敗したら・どれだけの時間banするか」を,サービスごとにjailとして定義する.

要素意味
filterログから攻撃を見つける正規表現パターン
jailfilter+対象ログ+ban条件をまとめた設定単位
maxretryban対象とする失敗回数
findtime失敗回数をカウントする時間窓
bantimebanを継続する時間

インストールと有効化 ― まずSSHを守る

導入は簡単だ.パッケージを入れて起動すれば,多くの環境でSSHのjailがデフォルトで有効になる.まずはこの基本状態を確認する.

fail2banの導入と状態確認

sudo apt install -y fail2ban
sudo systemctl enable --now fail2ban
# 全体の状態
sudo fail2ban-client status
# SSH jailの詳細(banされたIP等)
sudo fail2ban-client status sshd

fail2ban-client status sshdで,現在banされているIPや累計のban数が確認できる.公開して数時間も経てば,すでに複数のIPがbanされているのが普通だ.それだけ攻撃が来ているという証拠でもある.

jail.localの設計 ― 設定は.localに書く

設定の鉄則は,jail.confを直接編集せず,jail.localに上書き設定を書くことだ.パッケージ更新でjail.confが上書きされても,jail.localは保護される.

/etc/fail2ban/jail.local

[DEFAULT]
bantime = 1h           # banする時間
findtime = 10m         # この時間内の失敗をカウント
maxretry = 5           # 5回失敗でban
ignoreip = 127.0.0.1/8 203.0.113.10   # 自分のIPは除外

[sshd]
enabled = true
maxretry = 3           # SSHは厳しめに

[DEFAULT]で全jail共通の方針を決め,jailごとに上書きする.繰り返し攻撃してくるIPには段階的に長いbanを課す「bantime.increment = true」も有効だ.設定変更後はsudo systemctl reload fail2banで反映する.

再犯には長期banを課す

一度banを解かれてもすぐ戻ってくる攻撃元には,banを繰り返すごとに期間を延ばす設定が効く.bantime.increment = truebantime.maxtimeを組み合わせれば,しつこい相手を実質的に長期締め出しできる.

SSH以外も守る ― Nginx・WordPressのログイン保護

fail2banはSSHだけのものではない.Webアプリのログイン試行・Nginxへの不正アクセスも保護対象にできる.ログイン突破やスキャンを自動で遮断しよう.

Nginx向けjailの例

[nginx-http-auth]
enabled = true
[nginx-limit-req]
enabled = true
filter = nginx-limit-req
logpath = /var/log/nginx/error.log
maxretry = 10

# WordPressのwp-login.phpを守る独自filterも定義可能
# (filter.d に正規表現を置き, jailで参照)

WordPressのwp-login.phpxmlrpc.phpへの総当たりは定番の攻撃だ.アクセスログを監視する独自filterを定義すれば,これらも自動banできる.Nginxのlimit_req(レート制限)と組み合わせると,検知とブロックの二段構えになる.

ban状況の確認と手動操作 ― 攻撃の実態を知る

fail2banの運用では,「今どれだけ攻撃が来て,何がbanされているか」を把握できると安心だ.確認と手動操作のコマンドを押さえておこう.

ban状況の確認と手動ban/解除

sudo fail2ban-client status sshd       # banされているIP一覧
sudo fail2ban-client set sshd unbanip 203.0.113.50   # 手動解除
sudo fail2ban-client set sshd banip 198.51.100.7     # 手動ban
# 全体のログ
sudo journalctl -u fail2ban -f

誤って自分や正規ユーザーをbanしてしまった場合は,unbanipで即座に解除できる.journalctl -u fail2banでban/解除の履歴を追え,どんな攻撃が来ているかの傾向も掴める.

誤banを防ぐ ― ホワイトリストと慎重な閾値

fail2banの最大のリスクは,自分や正規ユーザーを誤ってbanしてしまうことだ.これを防ぐ設計が運用の肝になる.

  1. 自分のIPをignoreipに登録:固定IPがあればignoreipに入れ,絶対にbanされないようにする.
  2. 閾値を厳しくしすぎない:maxretryを1〜2にすると,正規ユーザーのタイプミスでbanが起きる.3〜5が無難.
  3. bantimeを最初は短く:運用に慣れるまでは1時間程度にし,誤banの影響を小さくする.
  4. 解除手段を確認:締め出されても,別IPやコンソールからunbanipできることを確認しておく.

アラート連携 ― banをチャットに通知する

発展として,banが発生したらDiscord/Slack/メールに通知すると,攻撃の傾向をリアルタイムに把握できる.fail2banはban時にアクションを実行できるため,通知スクリプトを呼ぶよう設定できる.

ただし攻撃が多いと通知も大量になる(アラート疲れ).「特定jailのban」「同一IPの再犯」など,本当に知りたいものだけ通知するよう絞るのがコツだ.

補論:自動防御は「安定した土台」の上でこそ活きる

fail2banは強力だが,土台のサーバーが安定して動いていることが前提だ.ログが正しく出ていなければ検知できないし,万一設定をミスして締め出されたときの復旧手段も要る.

高速NVMe・50種類以上のOSテンプレートに対応した国内VPS─シン・VPS─ はログ周りが素直に動き,コンソールアクセスとスナップショットを備えるため,fail2banの設定で誤って自分を締め出しても確実に復旧できる.攻撃が多い公開サーバーでも,NVMe SSDでログ処理が軽快なので,fail2banの監視が負荷になりにくい.

守るべきWebサービスは独自ドメイン+HTTPSで公開するのが基本だ.取り扱い400種類以上のドメイン取得サービス─ムームードメイン─ でドメインを取得し,ファイアウォール+fail2ban+HTTPSの多層で守られたサイトを運用すれば,個人開発でも実務水準のセキュリティが手に入る.

よくある質問(FAQ)

Q1.鍵認証にしていればfail2banは不要では?

鍵認証は総当たり突破を防ぐが,攻撃試行自体は止まらない.fail2banは試行そのものを遮断し,ログを静かにし,リソース消費を減らす.多層防御の一枚として入れる価値は高い.

Q2.設定はどのファイルに書く?

必ずjail.localに書くjail.confはパッケージ更新で上書きされるが,.localは保護される.フィルタを自作する場合はfilter.d/に置く.

Q3.自分がbanされたらどうする?

別IPやVPSのコンソールからfail2ban-client set <jail> unbanip <IP>で解除する.予防として,固定IPをignoreipに登録しておくのが確実だ.

Q4.SSH以外も守れる?

守れる.Nginx・Apache・WordPressのログイン・メールサーバーなど,ログに攻撃の兆候が出るものは保護対象にできる.対応するfilterを使うか,独自に正規表現を定義する.

Q5.maxretryやbantimeの適正値は?

SSHはmaxretry 3・bantime 1h程度から始め,攻撃状況を見て調整する.厳しすぎると誤banが増え,緩すぎると効果が薄い.再犯にはbantime.incrementで長期化させると効く.

Q6.banされたIPの確認方法は?

sudo fail2ban-client status <jail名>で現在banされているIPと累計が見える.journalctl -u fail2banで履歴と傾向も追える.

まとめ ― 攻撃は「仕組み」で締め出す

fail2banは,ログを見張り,攻撃元を自動で遮断する「疲れない防御」だ.jailを設計し,SSH以外も守り,誤banを防ぐ設定を入れれば,攻撃試行は激減し認証ログは静かになる.

今日やるべきことは,fail2banを導入し,fail2ban-client status sshdで「すでに何がbanされているか」を見ること.自分のサーバーにどれだけ攻撃が来ているかを実感すれば,自動防御の価値が腹落ちする.

一度設定すれば,あとは自動で守り続けてくれる.コンソールから復旧できるVPSがあれば,誤banを恐れず最適な閾値を攻められる.