公開サーバーの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 | ログから攻撃を見つける正規表現パターン |
| jail | filter+対象ログ+ban条件をまとめた設定単位 |
| maxretry | ban対象とする失敗回数 |
| findtime | 失敗回数をカウントする時間窓 |
| bantime | banを継続する時間 |
インストールと有効化 ― まず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 sshdfail2ban-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 = trueとbantime.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.phpやxmlrpc.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してしまうことだ.これを防ぐ設計が運用の肝になる.
- 自分のIPをignoreipに登録:固定IPがあれば
ignoreipに入れ,絶対にbanされないようにする. - 閾値を厳しくしすぎない:maxretryを1〜2にすると,正規ユーザーのタイプミスでbanが起きる.3〜5が無難.
- bantimeを最初は短く:運用に慣れるまでは1時間程度にし,誤banの影響を小さくする.
- 解除手段を確認:締め出されても,別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を恐れず最適な閾値を攻められる.