← Back to Blog
Journal

公開直後から始まる認証試行――fail2banでメールサーバーを守る運用設計

fail2banセキュリティCentOS Stream 9メールサーバー運用

はじめに

前回の記事では、CentOS Stream 9 上に Postfix + Dovecot のメールサーバーを構築し、mail-tester で 10/10 を達成しました。その末尾で触れたとおり、公開してまもなく、ログには見知らぬ IP からの認証試行が並び始めました。誰にも教えていないサーバなのに、です。

これは特別に狙われたわけではありません。インターネットに公開されたサーバは、公開しただけで自動スキャンの対象になります。そして防御の要件は「人がログを目視すること」ではなく自動化です。本記事では、fail2ban による検知と自動遮断の設計・運用を、構築編に続く運用編として実録します。なお、本記事に登場する設定値はすべて例示値で、ドメインは example.com、IP アドレスは文書用予約アドレス(192.0.2.0/24 等)に置き換えています。

背景・課題

まず「公開=攻撃対象」を数字で確認します。情報通信研究機構(NICT)がダークネット(未使用の IP アドレス空間)約28万 IP アドレスで観測した2025年のサイバー攻撃関連通信は約7,010億パケットで過去最多、1 IP アドレス当たりでは年間約250万パケット――およそ13秒に1回、何かの探索パケットが届く計算です(情報通信研究機構, 2026)。同レポートによれば、観測された通信の約55%は調査・探索目的と推定されるスキャンです。学術研究でも、インターネット全域を対象とする大規模な水平スキャンが恒常的に行われている実態は、10年以上前の時点で報告されています(Durumeric et al., 2014)。

つまり、筆者のサーバに来た認証試行は「発見された」のではなく「全数走査に引っかかった」だけです。この頻度に人力で応じるのは非現実的で、検知と遮断の自動化が必要です。

fail2ban はこの目的の定番ツールです。仕組みは3段構成で、(1) ログファイルを監視し、(2) フィルタ(正規表現)で認証失敗などの行をマッチさせ、(3) 条件を超えた送信元 IP をアクション(ファイアウォールルール)で遮断します。この監視対象とパラメータの組を jail と呼びます(Fail2ban, 2026a)。

CentOS Stream 9 では EPEL リポジトリから導入します。fail2ban パッケージは firewalld 連携の fail2ban-firewalld を含み、/etc/fail2ban/jail.d/00-firewalld.conf が既定の遮断アクションを banaction = firewallcmd-rich-rules に設定します(Fedora Project, 2026)。設定の変更は jail.conf を直接編集せず、jail.local または jail.d/ 配下のファイルで上書きするのが作法です(Fail2ban, 2026a)。

本論

何が来ているか――ログの実観測

まず敵を知るところからです。筆者の環境に届いていた試行は3種類でした(日時・IP はマスクし、文書用アドレスに置換しています)。

Postfix への SMTP 認証(SASL)の失敗。/var/log/maillog に warning として記録されます(Postfix, 2026)。

Aug 17 02:14:31 mail postfix/smtpd[12345]: warning: unknown[192.0.2.10]: SASL LOGIN authentication failed: authentication failure

Dovecot への IMAP ログイン失敗。同じく maillog に残ります。

Aug 17 02:15:02 mail dovecot[3456]: imap-login: Disconnected: Connection closed (auth failed, 3 attempts in 10 secs): user=<info>, method=PLAIN, rip=192.0.2.20, lip=203.0.113.5, TLS

sshd へのパスワード試行。/var/log/secure に残ります。

Aug 17 02:16:44 mail sshd[23456]: Failed password for invalid user admin from 192.0.2.30 port 51022 ssh2

存在しないユーザー名(admin、info、test など)への辞書的な試行が大半でした。fail2ban のフィルタがこれらの行に実際にマッチするかは、導入前に fail2ban-regex で確認できます(Fail2ban, 2026c)。

# sshd フィルタが /var/log/secure の何行にマッチするか確認
fail2ban-regex /var/log/secure /etc/fail2ban/filter.d/sshd.conf

# SASL 認証失敗は postfix フィルタの auth モードが対象
fail2ban-regex /var/log/maillog 'postfix[mode=auth]'

jail設計――サービスごとに認証モデルが違うから、厳しさも変える

fail2ban の主要パラメータは3つです(Fail2ban, 2026a)。

  • maxretry: 何回失敗したら遮断するか(既定 5)
  • findtime: 失敗を数える時間窓(既定 10分)
  • bantime: 遮断を続ける時間(既定 10分)

重要なのは、この値を「おすすめ設定」からコピーするのではなく、サービスごとの認証モデルから導くことです。

sshd は、筆者の環境では公開鍵認証のみでパスワード認証を無効にしています。つまりパスワード試行はその時点ですべて不審であり、正規ユーザーを誤って遮断するリスクはほぼありません。maxretry を小さく、bantime を長く振れます。

一方、メール(postfix-sasl / dovecot)は事情が違います。正規ユーザーがパスワードを打ち間違える、古い端末が誤った設定のまま再試行し続ける、といった「悪意のない失敗」が現実に起こります。厳しくしすぎると自分のユーザーを閉め出すため、maxretry は既定程度に残し、bantime は中程度にします。なお SASL 認証失敗を扱う jail は postfix-sasl で、実体は postfix フィルタの auth モードです(filter = postfix[mode=auth]。Fail2ban, 2026a)。

# /etc/fail2ban/jail.local(値はすべて例示。実運用値は環境に応じて決める)
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 198.51.100.0/24

[sshd]
enabled  = true
maxretry = 3
findtime = 10m
bantime  = 24h

[postfix-sasl]
enabled  = true
maxretry = 5
findtime = 20m
bantime  = 6h

[dovecot]
enabled  = true
maxretry = 5
findtime = 20m
bantime  = 6h

findtime には限界もあります。多数の送信元に試行を分散し、1ホストあたりの頻度を閾値以下に抑える「低速分散型」のブルートフォースが送信元単位・時間窓ベースの検知をすり抜けることは、8年分の実ログ分析で示されています(Javed & Paxson, 2013)。fail2ban の閾値検知はまさに送信元単位なので、この種の攻撃は原理的に守備範囲外です。findtime を延ばせば拾える範囲は広がりますが、誤遮断も増えるトレードオフがあります。だからこそ主防御はあくまで認証強度(公開鍵認証・強いパスワード)であり、fail2ban は総当たりの効率を削る第二層です。

再犯者への対応も用意されています。1つは recidive jail で、fail2ban 自身のログを監視し、繰り返し遮断された IP を全ポート対象で長期遮断します(既定で findtime 1d・bantime 1w。Fail2ban, 2026a)。もう1つは bantime.increment(既定は無効)で、再遮断のたびに遮断時間を段階的に延ばします(Fail2ban, 2026a)。では永久 ban はどうかというと、動的 IP は後日別の利用者に再割り当てされるため巻き添えの可能性があり、遮断リストも肥大化し続けます。「長期遮断+再犯で延長」までに留めるのが、効果と副作用のバランス点だと筆者は考えています。

自分を締め出さない――遮断より先に退路を設計する

自動遮断の最大の事故は、攻撃者ではなく自分を閉め出すことです。これまでの記事で一貫してきた「ロールバック手段を先に用意する」規律は、ここでは3点になります。

第1に ignoreip です。管理に使う固定 IP や信頼ネットワークを列挙しておけば、そこからの失敗は遮断対象になりません(Fail2ban, 2026a)。第2に、反映前のテストと解除手順です。fail2ban-client には設定を読み込んで検証する起動オプションがあり、リロード前に設定ミスを検出できます(Fail2ban, 2026b)。誤って遮断した場合の解除コマンドも、事故が起きる前に手に馴染ませておきます。

fail2ban-client -t                             # 設定の事前検証
fail2ban-client status sshd                    # jail の状態と ban 数の確認
fail2ban-client set sshd unbanip 192.0.2.30    # 誤 ban の解除

第3に、最後の命綱です。すべてのネットワーク経路を失っても、VPS・クラウドのシリアルコンソールからはネットワーク遮断と無関係にログインできます。FreeBSDのアップグレード記事で「作業前に EC2 シリアルコンソールを確保する」と書いたのと同型の規律で、遮断の仕組みを入れる前に、遮断が及ばない入口が生きていることを確認しておきます。

運用と効果測定――防御は観測とセットで機能する

導入して終わりではなく、効いているかを見続けます。fail2ban-client status <jail> は現在の ban 数・累計・監視対象ログを表示します(Fail2ban, 2026b)。筆者は週次でこの数字と認証失敗数を記録し、傾向の変化(急増・急減)だけを見る定点観測にしています。目的は数字の絶対値ではなく、「観測していれば異変に気づける」状態を保つことです。構築編で書いた「壊れたら気づけるまで作る」と同じ教訓が、防御側にも成り立ちます。ban の推移を可視化するダッシュボードは、次の課題として温めています。

実践への応用・考察

本記事の設計判断は2点に集約されます。

1つ目は「サービスごとに認証モデルが違うので、jail の厳しさも変える」です。maxretry・bantime・findtime は独立したチューニングノブではなく、認証方式・正規ユーザーの誤操作確率・想定する攻撃形態から従属的に決まる値です。この導出過程さえ持っておけば、新しいサービスを公開するときも同じ枠組みで jail を設計できます。

2つ目は「遮断より先に退路を確保する」です。ignoreip・反映前の検証・解除手順・シリアルコンソールという4段の退路は、fail2ban に限らず、ファイアウォールや SELinux のような「自分も対象になりうる防御機構」全般に通じる規律です。

最後に、限界の明記を。fail2ban は万能ではありません。低速分散型には原理的に効きませんし(Javed & Paxson, 2013)、遮断できるのは「失敗し続けた」送信元だけです。主防御は認証そのものの強度であり、fail2ban の価値は総当たり効率の低下・ログのノイズ削減・観測可能性の向上にあります。過大な安心感を持たず、この位置づけで使うのが正しい距離感だと考えています。

まとめ

  • 公開サーバへの自動スキャンは前提条件。ダークネット観測では 1 IP アドレス当たり年間約250万パケットという実態がある(情報通信研究機構, 2026)
  • fail2ban はログ監視→フィルタ→遮断の3段構成。CentOS Stream 9 では EPEL から導入し、firewalld 連携が既定になる
  • jail のパラメータはサービスの認証モデルから導く。公開鍵前提の SSH は厳しく、正規ユーザーの誤操作がありうるメールはバランスを取る
  • 低速分散型は守備範囲外。主防御は認証強度で、fail2ban は第二層
  • 遮断より先に退路(ignoreip・事前検証・解除手順・シリアルコンソール)を設計する

構築編・運用編を通じて、メールサーバーは「建てて終わり」ではなく「観測しながら運用する」対象になりました。次に何かを公開するときも、この枠組みをそのまま再利用するつもりです。

参考文献

学術論文

公式ドキュメント

政府・公的資料