Linux環境におけるFail2banの導入・設定ガイド:SSHとNginxのブルートフォース攻撃を実践的に防御

Security tutorial - IT technology blog
Security tutorial - IT technology blog

背景:サーバー公開直後から始まるボットの攻撃

パブリックIPを持つVPSを立ち上げた直後、わずか10〜15分ほどで世界中からポートスキャンボットがアクセスを仕掛けてきます。実際のインフラ監査でも、SSHやWebサーバーのポートを開放したまま、能動的な防御策を何も講じていないケースが散見されます(不審な通信の検知にはTsharkによるパケットキャプチャと解析も役立ちます)。

SSHのログファイル(Ubuntuなら/var/log/auth.log、RHEL/CentOSなら/var/log/secure)やNginxのログ(/var/log/nginx/access.log)を開いてみてください。毎日平均して数千件ものログイン試行失敗が記録されているはずです。攻撃者はroot、admin、testといった一般的なユーザー名を総当たりで試したり、/.env、/wp-login.php、/phpmyadminなどの機密パスを執拗にスキャンしたりしています。

Fail2banは、こうした課題を根本から解決するために作られたツールです。その仕組みは非常にシンプルで明確です。

  • ログ監視: システムのログファイルをリアルタイムで継続的に監視します。
  • パターン検出: フィルター内の正規表現(Regex)を用いて、認証失敗や不審なリクエストを特定します。
  • IP遮断: 一定期間(findtime)内に同一IPからの失敗回数が閾値(maxretry)に達すると、Fail2banが自動的にファイアウォール(iptables、nftables、またはUFW)を呼び出し、設定された期間(bantime)そのIPを遮断します。

LinuxへのFail2banのインストール

Fail2banは、主要なLinuxディストリビューションの公式リポジトリで提供されています。インストールは1分もかからず完了します。

1. Ubuntu / Debianの場合

sudo apt update
sudo apt install fail2ban -y

2. CentOS / RHEL / AlmaLinux / Rocky Linuxの場合

sudo dnf install epel-release -y
sudo dnf install fail2ban fail2ban-systemd -y

インストールが完了したら、サービスを有効化してOS起動時に自動開始されるようにします:

sudo systemctl enable fail2ban
sudo systemctl start fail2ban
sudo systemctl status fail2ban

SSHとNginxを保護するための詳細設定

ここで重要なルールがあります。/etc/fail2ban/jail.confファイルを直接編集してはいけません。このファイルはパッケージの更新時に上書きされる可能性があります。安全にカスタマイズするため、内容をjail.localにコピーして作業します。

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

1. グローバルデフォルト(Global Defaults)の設定

使い慣れたエディタで/etc/fail2ban/jail.localを開きます:

sudo nano /etc/fail2ban/jail.local

[DEFAULT]ブロックを探し、以下の基本パラメータを設定します:

[DEFAULT]
# 除外する安全なIPアドレス(オフィスIP、自宅の固定IP、ローカルホストなど)
ignoreip = 127.0.0.1/8 ::1 203.0.113.50

# デフォルトの遮断時間(1h = 1時間、1d = 1日)
bantime  = 1h

# 失敗回数をカウントする監視期間(10分)
findtime  = 10m

# 遮断されるまでの最大試行失敗回数
maxretry = 5

# 累進ペナルティ:再犯IPに対する自動的な遮断時間の延長
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 4w

bantime.increment = trueの設定は、本番環境において非常に効果的です。初回違反時は1時間の遮断ですが、解除直後に再び攻撃を仕掛けてきた場合、遮断時間は2時間、4時間と倍増し、最大で4週間(4w)まで延長されます。この設定により、執拗なボットネットによるブルートフォース攻撃を効果的に抑止できます。さらに、執拗なSSHスキャンに対してはEndlesshを使って攻撃ボットを無限SSHトラップに閉じ込める防御手法を併用するのも効果的です。

2. SSH保護設定(sshd)

[sshd]セクションへ移動するか、以下の内容をjail.localに追加します:

[sshd]
enabled = true
port    = ssh
logpath = %(sshd_log)s
backend = systemd
maxretry = 3
findtime = 15m
bantime  = 24h

注意: SSHポートをカスタムポート(例: 2222)に変更している場合は、Fail2banがファイアウォール上で正しいポートをブロックできるよう、port = 2222に変更してください。また、認証自体の強度を高めるためにTPM 2.0によるSSH Keyの保護を組み込むことも推奨されます。

3. Nginx保護設定

Nginx Webサーバーでは主に、HTTP Basic認証へのブルートフォース攻撃、機密ファイルのスキャン、リソースを枯渇させるスパムリクエストという3つの攻撃パターンが想定されます(大量の不正リクエストに対してはNginx Mapで悪質なBotやスクレイパーをブロックする設定も非常に効果的です)。

jail.localに以下の専用Jailを追加します:

# 1. HTTP Basic認証へのブルートフォース攻撃を遮断(パスワード保護された管理画面やステージング環境など)
[nginx-http-auth]
enabled = true
port    = http,https
logpath = /var/log/nginx/error.log
maxretry = 3
bantime  = 12h

# 2. 機密ファイル(.env、.git、wp-admin、phpmyadminなど)を探索するボットを遮断
[nginx-botsearch]
enabled  = true
port     = http,https
logpath  = /var/log/nginx/access.log
maxretry = 2
findtime = 10m
bantime  = 48h

# 3. Nginxで設定したレートリミットを超過したクライアントを遮断
[nginx-limit-req]
enabled  = true
port     = http,https
logpath  = /var/log/nginx/error.log
findtime = 5m
maxretry = 5
bantime  = 1h

4. 大量の404エラーを引き起こすボットを遮断するカスタムフィルター

自動スキャンツールは、バックアップファイル(backup.zipやdb.sqlなど)を探るために1分間に数百件ものリクエストを送信することがあります。短時間に過剰な404エラーを発生させるIPを検出するカスタムフィルターを作成しましょう。

フィルター定義ファイル/etc/fail2ban/filter.d/nginx-404-scan.confを作成します:

[Definition]
failregex = ^<HOST> - .* "(GET|POST|HEAD).*".* 404 .*
ignoreregex =

次に、/etc/fail2ban/jail.localの末尾に新しいJailを追記します:

[nginx-404-scan]
enabled  = true
port     = http,https
filter   = nginx-404-scan
logpath  = /var/log/nginx/access.log
findtime = 1m
maxretry = 20
bantime  = 2h

このルールは、同一IPが1分間に20回以上404エラーを発生させた場合、Fail2banが直ちにそのIPを2時間遮断するというものです。

設定を反映させるため、サービスを再起動します:

sudo systemctl restart fail2ban

運用とモニタリングの実践

各Jailの稼働状況を確認・管理するには、主にfail2ban-clientコマンドを使用します。

1. 全Jailのステータス概要を確認

sudo fail2ban-client status

正常に動作している場合の出力例:

Status
|- Number of jail:      4
`- Jail list:   nginx-404-scan, nginx-botsearch, nginx-http-auth, sshd

2. 各Jailで遮断中のIPリストを確認

SSHのJailが捕捉したボットの詳細を確認する場合:

sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed: 2
|  |- Total failed:     45
|  `- File list:        /var/log/auth.log
`- Actions
   |- Currently banned: 3
   |- Total banned:     12
   `- Banned IP list:   198.51.100.23 203.0.113.11 192.0.2.88

3. トラブルシューティング:誤って自身のIPを遮断してしまった場合の解除手順

SSHパスワードを連続で間違えると、自身のサーバーから締め出されてしまうことがあります。モバイル回線や別回線、VPS管理画面のWebコンソールなどからログインし、以下のコマンドでBANを解除します:

# sshd Jailから特定のIPの遮断を解除
sudo fail2ban-client set sshd unbanip 203.0.113.50

# または、稼働中のすべてのJailから対象IPの遮断を一括解除
sudo fail2ban-client unban 203.0.113.50

4. リアルタイムログの監視

Fail2banがIPを検知して遮断する様子をリアルタイムで確認するには、次のコマンドを実行します:

sudo tail -f /var/log/fail2ban.log

ルール違反が発生すると、ログに明確な通知が出力されます:

2026-10-07 10:15:22,418 fail2ban.actions [1452]: NOTICE [sshd] Ban 198.51.100.23
2026-10-07 10:20:05,112 fail2ban.actions [1452]: NOTICE [nginx-botsearch] Ban 192.0.2.14

わずか5分ほどの設定作業で、堅牢な自動防御壁を構築できます。これにより、サーバーが無駄なリクエストにCPUリソースを消費することなく、正当なユーザーへのサービス提供に専念できるようになります。さらなる防御として、Cloudflareと連携してServer IPへの不正アクセスを遮断するAuthenticated Origin Pullsの設定も併用すると安全性が向上します。

Share: