SSD Nodes Learn Hosting plans →
ガイド Matt Connor著者 Matt Connor

Ubuntu 24.04でFail2banを導入しSSHボットを止める

Ubuntu 24.04ではapt installだけでSSH保護が有効です。fail2ban-client status sshdの確認方法と、Total failedが0のままになる場合の修正方法を説明します。

Fail2ban の実際の動作

Fail2ban はログを読み取るデーモンです。SSH の認証メッセージを監視し、短い時間内に 1 つのアドレスから複数回の認証失敗が発生すると、ファイアウォールコマンドを実行して、そのアドレスを一定時間ブロックします。これが基本的な仕組みです。設定は 1 つのファイルに約 30 行記述するだけで、Ubuntu 24.04 では、編集しなくても保護が有効になる単一の apt コマンドでインストールできます。

Fail2ban の機能と限界を明確に理解してください。Fail2ban はユーザーを認証せず、暗号化も行いません。また、1 回だけのログイン試行を阻止するものではなく、同じ送信元からの繰り返し試行だけを阻止します。これはロックではなく、ノイズフィルターおよびレート制限機能です。ポート 22 に対する常時のバックグラウンドスキャンによって CPU、ネットワーク帯域幅、ログ領域が浪費されるのを防ぎ、攻撃者が 1 つのアドレスから順番に接続する必要がある場合に、その攻撃を遅らせることが目的です。

Fail2ban が置き換えられないもの

Fail2ban は第 3 層であり、第 1 層ではありません。サーバーが SSH パスワード認証を受け付ける状態のままだと、数千のアドレスに分散したボットネットが推測を続けられます。各アドレスの試行回数が ban のしきい値を下回り、ban が発動しないためです。これに対する本当の防御は、鍵のみの認証です。これにより、試行回数に関係なくパスワード推測が不可能になります。鍵のみの認証に Fail2ban を追加すると、2 つの効果があります。ログからブルートフォース攻撃によるノイズを減らせます。また、スキャナーを早期に排除し、ポートへの攻撃を止められます。Fail2ban は多層防御の一部として扱ってください。鍵認証とファイアウォールの後段に配置し、決してそれらの前段には置きません。

前提条件と Ubuntu 24.04 の実情

root または sudo を使用でき、SSH がすでに動作している Ubuntu 24.04 の VPS が必要です。SSH は、できれば鍵認証を使用してください。Fail2ban のメモリ使用量は少なく、数十 MB 程度です。制限値を調整する必要はありません。

ここからは、古いガイドが必ず誤って説明している部分です。長年、標準的な手順として「Fail2ban をインストールし、Ubuntu が /var/log/auth.log への書き込みを停止したため backend = systemd を追加する」と案内されてきました。この説明が当てはまるのは、一部のイメージだけです。標準の Ubuntu 24.04 サーバーまたはクラウドイメージには、通常 rsyslog もインストールされます。デフォルトのルールは auth,authpriv.* を /var/log/auth.log に書き込むため、多くの VPS では SSH の失敗が systemd journal とそのファイルの両方に記録されます。最小構成のイメージ(Ubuntu 24.04 minimal cloud image には rsyslog が含まれていません)や、ほとんどのコンテナでは、SSH のログは journal にのみ記録されます。その場合、テキストファイルは実際に存在しません。いずれの場合も、Ubuntu 24.04 の Fail2ban パッケージはこの状況に対応済みです。パッケージは /etc/fail2ban/jail.d/defaults-debian.conf を配置します。upstream のデフォルトではなく、このファイルがサーバーで実際に使用されます。

[DEFAULT]
banaction = nftables
banaction_allports = nftables[type=allports]
backend = systemd

[sshd]
enabled = true

ここは注意して読んでください。設定に触れる前に、2 つの疑問が解消されます。backend = systemd は、SSH jail が journal を読み取ることを意味します。そのため、使用しているイメージが auth.log に書き込むかどうかは関係ありません。banaction = nftables は、ban を nftables で適用することを意味します。nftables は Ubuntu 24.04 が実際に使用するファイアウォールであり、旧式の iptables ではありません。また、[sshd] enabled = true は、最初のブート時から jail が有効であることを意味します。つまり、Ubuntu 24.04 の標準的な apt install fail2ban は、初期状態で SSH のブルートフォース攻撃を ban します。主な作業は、その動作を確認し、ポリシーを調整し、自分自身を締め出さないようにすることです。

古い auth.log の問題は、今でも次の 3 つの状況で発生します。Fail2ban を apt ではなく pip でインストールしたため、defaults-debian.conf が存在しない場合。systemd journal を読み取れない非特権コンテナ内にいる場合。古いチュートリアルに従い、動作しているデフォルト設定を上書きする backend = auto を独自の jail.local に貼り付けた場合です。1 つ目と 3 つ目が SSH の ban を壊すのは、rsyslog がないイメージ(minimal image など)だけです。rsyslog が動作している環境では、file backend が /var/log/auth.log を検出して正常に動作します。各失敗モードの具体的な状態については、failure-modes セクションで説明します。

手順 1: インストールし、すでに禁止処理が行われていることを確認します

sudo apt update
sudo apt install -y fail2ban

Ubuntu 24.04 には Fail2ban 1.0.2 が収録されています。パッケージは python3-systemd を必須依存関係として導入するため、journal バックエンドに必要なものはすべてそろっています。サービスは自動的に有効化され、起動します。

sudo systemctl status fail2ban

active (running) になることを確認します。次に、すでに機能している jail を確認します。

sudo fail2ban-client status sshd

公開 VPS を数分間でも到達可能な状態にしていると、失敗回数がすでに記録され、アドレスが禁止されていることがよくあります。インターネットからはポート 22 に対するスキャンが継続的に行われるためです。これで、標準設定が機能していることを確認できます。ここから行うのは、設定をゼロから構築することではなく、調整することです。

手順 2: jail.conf ではなく jail.local を編集する

Fail2ban は、/etc/fail2ban/jail.conf にアップストリームのデフォルト設定を保持しています。このファイルは編集しないでください。ファイル先頭の警告にもあるとおり、パッケージのアップグレードで置き換えられる可能性があり、変更内容が失われます。Fail2ban はファイルを固定された順序で読み込みます。最初に jail.conf、次にアルファベット順で jail.d/*.conf、続いて jail.local、最後にアルファベット順で jail.d/*.local を読み込みます。同じ設定に複数の値がある場合は、最後に読み込まれた値が有効になります。そのため、jail.local はパッケージに含まれる defaults-debian.conf を上書きします。ただし、jail.d/ に配置した *.local ファイルはその後に読み込まれ、さらに上書きします。どの値が有効か確認できるよう、上書き設定は 1 か所にまとめてください。.local ファイルはユーザーが管理するファイルであり、パッケージのアップグレードによって変更されることはありません。同じ規則はフィルターにも適用され、*.local ファイルが提供済みの filter.d/*.conf を上書きします。

そのため、必要な少数の設定だけを上書きする小さな jail.local を作成し、jail.conf とパッケージに含まれる jail.d/defaults-debian.conf は参照用として変更せずに残します。

手順 3: /etc/fail2ban/jail.local を作成する

sudo nano /etc/fail2ban/jail.local

次の内容を記述し、ignoreip 行のアドレスを自分のパブリック IP に変更します。

[DEFAULT]
# Ubuntu 24.04 already sets these two in jail.d/defaults-debian.conf.
# Pinning them here documents the dependency and survives if that
# file is ever removed or changed by an upgrade.
backend   = systemd
banaction = nftables

# Ban for one hour ...
bantime  = 1h
# ... if an address fails ...
maxretry = 5
# ... 5 times within 10 minutes.
findtime = 10m

# Never ban these. PUT YOUR OWN IP HERE.
ignoreip = 127.0.0.1/8 ::1 10.0.0.24

# Longer bans for repeat offenders: 1h, 2h, 4h ... up to a week.
bantime.increment = true
bantime.maxtime   = 1w

[sshd]
enabled = true

各行には役割があります。

  • bantime、findtime、maxretry はポリシーを指定します。配布時のデフォルト値である bantime は 10 分にすぎないため、1 時間の方が妥当です。10 分以内に 1 つのアドレスから 5 回失敗すると、ban の対象になります。実際のユーザーがパスワードを 1 回か 2 回入力し間違えることはありますが、10 分間に 5 回失敗するのはスクリプトによる動作です。
  • ignoreip は安全策です。Fail2ban に自分のサーバーから締め出されないよう、接続元のパブリックアドレスをここに記述します。IP が変わる自宅回線を使用している場合は、ここを省略するのではなく、最後に説明する VPN 方式を選ぶ理由になります。
  • bantime.increment = true は、ban が繰り返されるたびに期間を延長します。1 時間、2 時間、4 時間と延長し、bantime.maxtime まで続きます。繰り返し接続してくるアドレスは、段階的に長く締め出されます。

ホワイトリストに登録するアドレスは、サーバーではなく、SSH で接続するマシンから確認します。

curl -s ifconfig.me

ここで、使用するポートと ban ポリシーに合わせて調整した jail.local を生成し、ファイルに貼り付けることができます。

ToolFail2ban jail generator

ステップ 4: 再起動し、journal を読み取っていることを確認する

sudo fail2ban-client -t
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd

-t は最初に設定テストを実行するため、jail.local の入力ミスがあっても、サービスを停止したままにせず、ここで明確に失敗します。正常な jail の状態は次のようになります。

Status for the jail: sshd
|- Filter
|  |- Currently failed: 0
|  |- Total failed:     14
|  `- Journal matches:  _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
   |- Currently banned: 1
   |- Total banned:     3
   `- Banned IP list:   203.0.113.66

Fail2ban が実際にログインログを読み取っていることを示す数値は Total failed です。0 より大きい場合、または別のマシンから意図的にログインを失敗させたときに増える場合は、journal が読み取られており、作業は完了です。何度ログインを失敗させても 0 のままで、ignoreip に指定したアドレスからテストしていないことも確認できている場合は、下記の失敗パターンに進んでください。

Journal matches の行では、引き続き sshd.service が指定されていることに注意してください。Ubuntu では SSH の unit は実際には ssh.service ですが、付属の filter は _COMM=sshd にも一致します。また、OpenSSH 24.04 は失敗を sshd というプロセス名で記録するため、一致します。この点が問題になるのは、新しい OpenSSH(9.8 以降)を使用している場合だけです。この場合、接続ごとの worker は sshd-session です。該当するケースについては、失敗パターンで説明します。

手順 5: 実際の ban を確認するか、テスト用に強制的に発生させる

公開 VPS では、実際の ban は数分以内に自動で発生します。確認するには、ログを末尾から監視します。

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

ban は次のように記録されます。

2026-07-15 10:31:40,502 fail2ban.filter  [812]: INFO    [sshd] Found 203.0.113.66 - 2026-07-15 10:31:40
2026-07-15 10:31:44,118 fail2ban.actions [812]: NOTICE  [sshd] Ban 203.0.113.66

待機せずに一連の仕組みを確認するには、自分のアドレスではなく、ドキュメント用のアドレスを手動で ban します。203.0.113.66 はドキュメント用に予約された TEST-NET-3 に属するため、実在するホストでも、プロバイダーのネットワーク上のプライベートアドレスでもありません。

sudo fail2ban-client set sshd banip 203.0.113.66

1 と表示され、アドレスは fail2ban-client status sshd の Banned IP list に表示されます。次に、ファイアウォールに実際にブロックが存在することを確認します。Ubuntu 24.04 では iptables ではなく nftables を使用します。

sudo nft list table inet f2b-table

addr-set-sshd という set に 203.0.113.66 が格納され、f2b-chain という chain がその set 内の送信元をすべて拒否していることを確認できます。fail2ban-client ではアドレスが ban されたと表示されるのに nft list に何も表示されない場合、ban action とファイアウォールの設定が一致していません。failure modes にある nftables/iptables の注記を参照してください。

ステップ 6: 自分自身のアクセス禁止を解除し、ロックアウトから復旧する

誤って禁止したアドレス、特に自分のアドレスは、次のコマンドで削除します。

sudo fail2ban-client set sshd unbanip 203.0.113.66

成功すると 1 が返ります。すべての jail で、すべての禁止を解除するには次を実行します。

sudo fail2ban-client unban --all

すでに開いている SSH セッションが救済になるとは考えないでください。nftables の禁止ルールは、禁止されたアドレスから port 22 へのすべてのパケットを拒否します。確立済みの接続も対象です。そのため、禁止ルールが適用された時点で既存のセッションも停止します。自分自身を禁止し、ignoreip エントリもない場合は、禁止が期限切れになるまでロックアウトされます。SSH を経由しない VNC またはシリアルのプロバイダーの Web コンソールから復旧し、bantime が期限切れになるまで待つか、そこで禁止解除コマンドを実行してください。

手順 7: BAN を永続化し、段階的に強化する

Fail2ban は有効な BAN を /var/lib/fail2ban/fail2ban.sqlite3 の小さな SQLite データベースに保持するため、サービスの再起動やシステムの再起動後も BAN は維持されます。すでに追加した bantime.increment の行により、同じ違反を繰り返す接続元には、約 1 時間から 1 週間へとおおむね倍増する、段階的に長い BAN が適用されます。

これに加えてシステム全体に「3 回で BAN」というポリシーを適用するには、Fail2ban に付属する recidive jail を使用します。この jail は自身の /var/log/fail2ban.log を監視し、すべての jail で繰り返し BAN されたアドレスに長時間の BAN を適用します。現在の [DEFAULT] は systemd バックエンドを使用しているため、この jail が読み取るよう設計されたログファイルを明示的に指定します。

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

明示的な logpath を指定した backend = auto により、recidive は通常の fail2ban.log を読み取ります。カウント対象の Ban 行はこのファイルに実際に記録されるためです。グローバルに設定した systemd のデフォルトでは journal が参照されますが、そこには対象の行が記録されません。

ステップ 8: 鍵認証のみの SSH と組み合わせ、さらに VPN を使用する

Fail2ban は、鍵認証と組み合わせて初めて効果を発揮します。/etc/ssh/sshd_config.d/ 配下の drop-in ファイル(たとえば /etc/ssh/sshd_config.d/00-hardening.conf)で、次のように設定します。

PasswordAuthentication no
KbdInteractiveAuthentication no

次に sudo systemctl restart ssh。パスワード認証を無効にすると、ブルートフォース攻撃は成功しません。Fail2ban の役割は、ログのノイズを減らし、スキャナーを早期に排除することになります。さらに強固にするには、SSH をパブリックインターネットから完全に隔離します。自己ホスト型の WireGuard VPN の背後に SSH を配置し、ポート 22 へのアクセスをトンネル経由だけに制限します。到達できないポートに対してブルートフォース攻撃は実行できないため、Fail2ban は最前線ではなく、追加の防御策になります。

Fail2ban は SSH 専用ではありません。ログイン失敗を記録するサービスには、メールサーバー、nginx サイト、または 自己ホスト型の Vaultwarden パスワードマネージャーなど、いずれも jail を設定できます。Web ログインをクレデンシャルスタッフィングにさらしたくない場合に有効です。Web アプリを Let's Encrypt 証明書を使用する nginx サイトの背後に配置したら、SSH の jail が journal を参照するのと同じ方法で、アクセスログを Fail2ban のフィルターに指定します。

障害パターンと表示される正確な文字列

「sshd jail のログファイルが見つかりません」と表示され、Fail2ban が起動しない。 これは古い auth.log の問題です。Ubuntu 24.04 では、/var/log/auth.log が存在せず(rsyslog を含まないイメージ、たとえば最小構成のイメージやコンテナ)、かつ journal が読み取られていない場合にだけ発生します。つまり、defaults-debian.conf がなく pip を使用する構成、journal のないコンテナ、または jail.local に誤って貼り付けた backend = auto などです。/var/log/auth.log がないファイルバックエンドでは、sshd jail がログを見つけられず、デーモン全体が中断します。fail2ban.log には次のように表示されます。

ERROR   Failed during configuration: Have not found any log file for sshd jail

このエラーは致命的なため、サービスは起動せず、続いて fail2ban-client status が後続の症状を報告します。

ERROR  Failed to access socket path: /var/run/fail2ban/fail2ban.sock. Is fail2ban running?

この「socket path」の行は Fail2ban が壊れていることを示していません。1 つの jail がログを見つけられなかったため、起動していないことを示しています。Ubuntu パッケージがすでに設定している [DEFAULT] に backend = systemd を設定すれば、両方のメッセージを同時に解消できます。

Jail は有効だが、Total failed がまったく増えない。 デーモンは実行中で journal も読み取られています。しかし、実際の失敗が journalctl -u ssh に蓄積しているのに、カウンターは 0 のままです。まず、明らかな原因を除外します。自分の接続元アドレスが ignoreip に登録されているため、仕様上、自分の失敗は対象外になっています。該当しない場合は、接続ごとのワーカーが sshd-session(9.8 以降)である OpenSSH ビルドを使用している可能性があります。この場合、その journal _COMM は sshd-session であり、sshd ではないため、付属のマッチ条件に一致しません。[sshd] ブロックのマッチ条件を広げます。

[sshd]
enabled      = true
backend      = systemd
journalmatch = _SYSTEMD_UNIT=ssh.service + _COMM=sshd + _COMM=sshd-session

再起動し、ignoreip に含まれないアドレスから意図的にログインを失敗させ、Total failed が最終的に増えることを確認します。

自分自身を禁止してしまった: Connection refused。 ignoreip に自分のアドレスを追加しないまま、ログインを数回失敗させると、次の状態になります。

ssh: connect to host 10.0.0.10 port 22: Connection refused

サイレントタイムアウトではなく拒否されるのは、nftables action のデフォルトの reject verdict が機能しているためです。Step 6 と同じ方法で修正します。別の、禁止されていないアドレスから開いたセッション、またはプロバイダーのコンソールから unban してください。禁止されたアドレスからすでに開いているセッションも停止します。その後、再発防止のため自分のアドレスを ignoreip に追加します。

Fail2ban ではアドレスが禁止済みと表示されるが、接続できる。 status sshd のカウンターは増えるのに、そのアドレスから port 22 に到達できます。これは ban action と firewall の不一致です。Ubuntu 24.04 では、iptables 層のないホストで、動作している banaction = nftables を古いガイドからコピーした banaction = iptables-multiport で上書きした場合にほぼ必ず発生します。fail2ban.log には次のように表示されます。

fail2ban.actions [812]: ERROR  Failed to execute ban jail 'sshd' action 'iptables-multiport'

その上書きを削除し、パッケージが提供する nftables を使用します。ufw だけで firewall を管理し、禁止ルールを ufw に表示したい場合は、[DEFAULT] に banaction = ufw を設定します。再起動し、sudo nft list ruleset | grep f2b でルールが表示されることを確認します。

jail.local を編集した後、Fail2ban が起動しない。 タイプミス、余分な見出し、または不正な時間値があると、サービスは起動を拒否します。実行前に Fail2ban に設定を検査させます。

sudo fail2ban-client -t

問題のあるファイルと jail が示されます。たとえば Errors in jail 'sshd'. Skipping... のように表示されるため、推測ではなく該当箇所を修正できます。

FAQ

Ubuntu 24.04 の標準 Fail2ban インストールでは、実際に SSH 攻撃を禁止できますか?

はい。パッケージには /etc/fail2ban/jail.d/defaults-debian.conf が含まれており、sshd jail を有効にします。また、backend = systemd が設定されているため、イメージが /var/log/auth.log にログを書き込むかどうかに関係なく systemd journal を読み取ります。さらに banaction = nftables も設定されているため、Ubuntu の実際のファイアウォールを通じて禁止を適用します。標準の apt install fail2ban だけで、初回起動時から SSH を保護できます。sudo fail2ban-client status sshd で確認し、Total failed が 0 より大きい値になっていることを確認してください。

Fail2ban がサーバー上で何も禁止しないのはなぜですか?

よくある 3 つの原因を順に切り分けてください。まず、ignoreip に含まれるアドレスからテストしている可能性があります。このアドレスは設計上、除外されます。次に、古いガイドにある backend = auto を jail.local に貼り付けたため、動作する標準設定を上書きしている可能性があります。rsyslog がないイメージでは SSH の禁止が機能せず、auth.log も存在しないためです。あるいは、読み取る systemd journal がまったくないコンテナ内にいる可能性もあります。fail2ban-client status sshd の Total failed を確認してください。journalctl -u ssh に実際の失敗が表示されているのに値が増えない場合、jail は誤った場所を読み取っています。

自分の IP アドレスの禁止を解除するにはどうすればよいですか?

sudo fail2ban-client set sshd unbanip YOUR.IP.HERE を実行すると、成功時に 1 が返ります。すべての禁止を解除するには sudo fail2ban-client unban --all を実行します。SSH から締め出されている場合は、プロバイダーの Web コンソールまたは VNC コンソールを使用して同じコマンドを実行してください。禁止されると、アドレスから port 22 へのすべてのパケットが拒否されるため、すでに確立しているセッションも停止します。その後、アドレスを ignoreip に追加し、再発を防いでください。

jail.conf と jail.local の違いは何ですか?

jail.conf には Fail2ban の upstream の標準設定が含まれています。パッケージのアップグレードで置き換えられる可能性があるため、ここでの編集にはリスクがあります。Debian/Ubuntu パッケージは、jail.d/defaults-debian.conf を通じて独自の設定を上に重ねます。変更は jail.local に記述してください。このファイルは両方の後に読み込まれるため設定が優先され、アップグレードでも変更されません。jail.d/ 内にある *.local ファイルだけがさらに後に読み込まれます。そのため、そこに不要なファイルを残さないでください。jail.conf は参照用の読み取り専用ファイルとして残してください。

Fail2ban は鍵ベースの SSH 認証を置き換えますか?

いいえ。Fail2ban は 1 つのアドレスから繰り返される認証失敗をレート制限します。各アドレスがしきい値未満にとどまる、低速で分散した推測攻撃には効果がありません。鍵のみの認証(PasswordAuthentication no)を使用すれば、パスワード推測を完全に不可能にできます。そのうえで Fail2ban によりログのノイズを減らし、スキャナーを早期に排除できます。両方を使用し、可能であれば SSH を公開インターネットから完全に切り離してください。