手順

Fail2banの設定:SSHをパスワードの総当たりから守る

更新日: · Skillaria.Top

Fail2banはサービスのログを監視し、繰り返される失敗したログイン試行を見つけて、攻撃元のIPアドレスをファイアウォール経由で一時的にブロックします。SSHを守るには、パッケージをインストールし、/etc/fail2ban/jail.local に [sshd] セクション(enabled = true、maxretry、findtime、bantime)を記述して、サービスを再起動します。状態は fail2ban-client status sshd で確認します。

Fail2banは、サービスのログを監視し、繰り返される失敗したログイン試行を見つけると、その試行元のIPアドレスを一定時間ブロックするデーモンです。SSHにとっては、パスワードの総当たりに対する最も簡単な防御策です。数回失敗すると、ボットはサーバーへのアクセスを諦めます。以下では、fail2banの設定をインストールから、BANの確認や典型的な問題の解決まで解説します。

SSHの鍵認証があるのに、なぜfail2banが必要なのか

ポート22を開けているサーバーは、起動から数分もすると、ボットからのログイン試行を受け始めます。実際に確認してみてください。

$ sudo journalctl -u ssh --since "1 hour ago" | grep -c "Failed password"
412

パスワード認証を無効にして鍵だけを使っていれば、アクセスを突破されることはほぼありません。それでもfail2banは役立ちます。ログのノイズを減らし、数千の接続による負荷を抑え、誤ってパスワード認証が有効のまま残った場合の影響を抑えられます。fail2banは鍵認証の代わりではなく、2つ目の防御層です。

fail2banの仕組み

fail2banは3つの部分から成ります。

  • フィルター(filter):ログの中から、認証失敗の行を見つけて、そこからIPアドレスを取り出す正規表現の集まりです。フィルターは /etc/fail2ban/filter.d/ にあります。
  • アクション(action):違反者に対して何をするかを決めます。iptables、nftables、ufw、firewalld にルールを追加します。アクションは /etc/fail2ban/action.d/ にあります。
  • ジェイル(jail):フィルター、アクション、ログの取得元、しきい値を組み合わせたものです。たとえば sshd ジェイルはSSHのログを監視します。

1つのIPから findtime の間に maxretry 回一致があると、そのアドレスは bantime の間ブロックされます。期間が過ぎると、BANは自動的に解除されます。

fail2banのインストール

DebianやUbuntuでは次のとおりです。

sudo apt update
sudo apt install fail2ban

RHEL、Rocky、AlmaLinuxでは、パッケージはEPELリポジトリにあります。

sudo dnf install epel-release
sudo dnf install fail2ban

自動起動を有効にして、サービスの状態を確認します。

sudo systemctl enable --now fail2ban
sudo systemctl status fail2ban

DebianやUbuntuでは、SSH用のジェイルが /etc/fail2ban/jail.d/defaults-debian.conf を通じて既定で有効になっています。RHEL系では、インストール後に何も有効になっていないため、ジェイルを手動で有効にする必要があります。

設定ファイルの場所:jail.conf と jail.local

主要な設定ファイルは /etc/fail2ban/jail.conf ですが、直接編集してはいけません。パッケージを更新すると上書きされてしまうためです。独自の設定は /etc/fail2ban/jail.local か、/etc/fail2ban/jail.d/*.local の個別ファイルに書きます。fail2banは次の順に読み込み、後から読み込まれたものが前の設定を上書きします。

  1. jail.conf
  2. jail.d/*.conf
  3. jail.local
  4. jail.d/*.local

jail.conf を丸ごと jail.local にコピーしないでください。古い既定値が固定されてしまいます。jail.local には変更する項目だけを書きます。

SSH用のfail2ban設定:最小限のjail.local

ファイルを作成します。

sudo nano /etc/fail2ban/jail.local

次の内容を追加します。

[DEFAULT]
# 決してBANしないアドレス(自分のIPなど)
ignoreip = 127.0.0.1/8 ::1 203.0.113.10
bantime  = 1h
findtime = 10m
maxretry = 5
# ログの取得元:systemdのジャーナルまたはファイル
backend  = systemd

[sshd]
enabled  = true
port     = ssh
maxretry = 3

サービスを再起動して、ジェイルが起動したことを確認します。

$ sudo systemctl restart fail2ban
$ sudo fail2ban-client status
Status
|- Number of jail:      1
`- Jail list:   sshd

各パラメーターの意味

パラメーター意味例
enabledジェイルを有効にするかどうかtrue
port違反者をブロックするポートssh、2222、ssh,2222
maxretryBANされるまでに許容する失敗の回数3
findtime失敗を数える時間の枠10m
bantimeBANの期間。-1 は無期限1h、1d
ignoreipBANしないアドレスやサブネット10.0.0.0/8
backendログの取得元systemd、auto
logpathファイルを使う場合のログファイルのパス/var/log/auth.log
banactionBANに使うファイアウォールnftables-multiport、ufw

時間は s、m、h、d、w の単位を付けて書けます。単位のない数値は秒として扱われます。

backend:systemdかファイルか

Debian 12やUbuntu 24.04では、rsyslogがインストールされていないと /var/log/auth.log が存在しないことがあります。SSHのログはsystemdのジャーナルにしか残りません。その場合は backend = systemd が必要です。そうしないと、ログファイルが見つからないというエラーでfail2banが起動しません。rsyslogがある場合は、ファイルを使う方法もあります。

[sshd]
enabled  = true
backend  = auto
logpath  = /var/log/auth.log

RHEL系のシステムでは、対応するファイルは /var/log/secure です。

標準以外のポートのSSH

sshdが、たとえばポート2222で待ち受けている場合は、ジェイルにそのポートを指定してください。指定しないと、fail2banはポート22をブロックし、攻撃は2222で続いてしまいます。

[sshd]
enabled = true
port    = 2222

違反者のすべてのポートを一度にブロックするには、banaction で iptables-allports または nftables-allports のアクションを指定します。

ファイアウォールの選び方:iptables、nftables、ufw、firewalld

Debianでは既定で banaction = nftables が使われます(古いバージョンではiptables)。RHELでは firewalld です。サーバーでufwを設定している場合は、BANがufwに表示されるようにすると管理しやすくなります。

[DEFAULT]
banaction = ufw

firewalldの場合は次のとおりです。

[DEFAULT]
banaction = firewallcmd-rich-rules

ルールが実際に追加されたかは、sudo nft list ruleset | grep f2b または sudo iptables -L -n | grep f2b で確認できます。fail2banは f2b- という接頭辞のチェーンを作成します。

動作の確認:fail2ban-client status

fail2banの主要な管理ツールは fail2ban-client です。特定のジェイルの状態は次のように確認します。

$ sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed: 2
|  |- Total failed:     147
|  `- Journal matches:  _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
   |- Currently banned: 4
   |- Total banned:     38
   `- Banned IP list:   45.148.10.12 92.118.39.7 185.224.128.40 218.92.0.112

ここには、現在の時間枠内の失敗回数、BANされているIPの数、そしてそのアドレスが表示されます。実際に動作を確かめるには、別のマシン(ignoreip に含まれていないもの)から間違ったパスワードで数回ログインしてみてください。3回目の試行の後には接続できなくなるはずです。

fail2ban自身のログは /var/log/fail2ban.log にあります。

$ sudo tail -n 3 /var/log/fail2ban.log
2026-10-14 09:12:41,118 fail2ban.filter  [812]: INFO    [sshd] Found 218.92.0.112
2026-10-14 09:12:44,302 fail2ban.filter  [812]: INFO    [sshd] Found 218.92.0.112
2026-10-14 09:12:47,551 fail2ban.actions [812]: NOTICE  [sshd] Ban 218.92.0.112

fail2banでIPのBANを解除する

自分自身や同僚をBANしてしまった場合は、サーバーのコンソール(ホスティングのパネルや別のIPからのSSH)から解除します。

sudo fail2ban-client set sshd unbanip 203.0.113.25

すべてのジェイルのBANをまとめて解除するには次のとおりです。

sudo fail2ban-client unban --all

フィルターが発動するのを待たずに、手動でアドレスをBANすることもできます。

sudo fail2ban-client set sshd banip 198.51.100.7

同じ問題を繰り返さないために、自分の固定IPやオフィスのサブネットを ignoreip に追加してください。

繰り返し違反するIPへの段階的なBAN

多くのボットは、BANが解除されるとすぐに戻ってきます。バージョン0.11以降のfail2banには、繰り返し違反するIPに対して期間を延ばす機能があります。

[DEFAULT]
bantime = 1h
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 4w

同じIPが再びBANされるたびに、期間は前回より長くなりますが、4週間を超えることはありません。古いバージョンの代替策は、recidive ジェイルです。これはfail2banのログ自体を読み、何度も引っかかったアドレスを長期間ブロックします。

[recidive]
enabled  = true
logpath  = /var/log/fail2ban.log
bantime  = 1w
findtime = 1d
maxretry = 5

フィルターの検証:fail2ban-regex

ジェイルは動いているのに誰もBANされない場合は、フィルターがログの行を実際に見つけているかを確認してください。ファイルのログの場合は次のとおりです。

sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

systemdのジャーナルの場合は次のとおりです。

sudo fail2ban-regex systemd-journal sshd

出力の Lines: ... matched の行を確認してください。一致がゼロなら、フィルターがログの形式に合っていないか、ログの取得元が間違っています。再起動の前に、設定全体の構文を確認しておくと安心です。

sudo fail2ban-client -t

よくあるエラー

  • サービスが起動しない:「Have not found any log file for sshd jail」:/var/log/auth.log がありません。backend = systemd を設定するか、rsyslogをインストールしてください。
  • BANは表示されるのに攻撃が続く:ポートの指定が違っているか(SSHのポートを変更した場合など)、より前にある許可ルールがファイアウォールのBANを上書きしています。port の設定と nft list ruleset の出力を確認してください。
  • 変更が反映されない:jail.conf を編集したのに、jail.local や jail.d/*.local に別の値が設定されています。実際に有効な値は sudo fail2ban-client get sshd maxretry で確認できます。
  • 自分自身をBANしてしまった:コンソールからBANを解除し、IPを ignoreip に追加してください。
  • Dockerのあるサーバーでfail2banが攻撃を検知しない:コンテナのポートは、INPUTをバイパスするDOCKERチェーンを通じて公開されます。こうしたサービスには、アクションで chain = DOCKER-USER を指定します。

SSHをさらに守るための設定

fail2banは、/etc/ssh/sshd_config の基本的な設定と組み合わせると効果が高まります。

PasswordAuthentication no
PermitRootLogin no
MaxAuthTries 3

変更後は sudo sshd -t で設定を確認し、サービスを再起動します。新しい設定で鍵認証のログインが成功することを確認するまで、現在のセッションは閉じないでください。さらに、ファイアウォールで、SSHへのアクセスを必要なアドレスだけに制限することもできます。

まとめ

fail2banの設定は、いくつかの手順にまとめられます。パッケージをインストールし、[sshd] セクションを持つ jail.local を作成し、正しいbackendとポートを選び、maxretry、findtime、bantime を設定します。自分のアドレスは ignoreip に追加し、fail2ban-client status sshd で動作を確認します。鍵認証のみのログインと組み合わせれば、SSHをパスワードの総当たりから確実に守れます。サーバーの防御とfail2banは、Linuxコースで実践的に解説しています。

よくある質問

パスワード認証を無効にしていても、fail2banは必要ですか?

必須ではありませんが有用です。何千件もの無駄な試行をログから減らし、負荷を抑えます。また、誰かがパスワード認証を誤って再び有効にしてしまった場合の保険にもなります。

すべてのジェイルでBANされているIPをまとめて確認するにはどうすればよいですか?

sudo fail2ban-client banned を実行すると、ジェイルごとにBANされたアドレスの一覧が表示されます。1つのジェイルだけを確認するには fail2ban-client status sshd を使います。

サーバーを再起動しても、BANは保持されますか?

はい。fail2banはBANの情報をSQLiteのデータベース(/var/lib/fail2ban/fail2ban.sqlite3)に保存し、起動時に有効なブロックを復元します。ただし dbpurgeage によって、それより前に削除されている場合は除きます。

SSH以外のサービスもfail2banで守れますか?

はい。nginx、Apache、Postfix、Dovecotなどのフィルターが同梱されています。jail.local で対応するジェイルを有効にするだけで済みます。たとえば [nginx-http-auth] に enabled = true を設定します。

fail2banとファイアウォールのアクセス制限の違いは何ですか?

ファイアウォールはアドレスを静的に許可または拒否します。一方fail2banは、ログに不審な動きを残したアドレスを動的にBANします。両者を組み合わせて、信頼できるアドレスは許可リストに、それ以外はfail2banで管理するのが一般的です。

動画でこのテーマを学ぶ

このテーマはコース「Linux: с нуля до уверенного администрирования」で実践とともに詳しく解説しています。

コースへ