DELOGs
[サーバ構築編#12] Ubuntuでfail2banの設定

サーバ構築編#12
Ubuntuでfail2banの設定

Ubuntuでデフォルトで動くファイヤーウォールツールfail2banの設定をしながら、ジャーナルログについても学習

初回公開日

最終更新日

サーバの新規構築は今回が最後となります。 最後はUbuntuでは、デフォルトで動いているファイヤーウォールツール「fail2ban」の設定をしながら、ジャーナルログについても学習します。 ここは運用が始まってから、見直す項目が多くなると思いますが、どんな仕組みでどう動くかは把握しておいて損はないと思います。

1.「fail2ban」とは?

「fail2ban」は、あるサービスのログを監視して、悪質なアクセスがあればその発信元のIPアドレスをBANする(ブロックする)サービスです。IPアドレスを監視というところが注目点になります。
例えば、オフィスや学校などのネットワークから、ある1人がパスワード連続ミス → そのIPがBANされ、全員が接続できなくなる可能性もあるわけです。
「fail2ban」は、シンプルな監視サービスで便利ですが、IPアドレス単位の監視ゆえに、誤ってBANすることもあるということを認識した上で設定・運用をしていく必要があります。
まずはデフォルトの設定を見ています。

fail2ban が動いてるか確認(デフォルト状態)

デフォルトで動いているはずですが、一応確認します。
bash
1sudo systemctl status fail2ban
bash
1● fail2ban.service - Fail2Ban Service 2 Loaded: loaded (/usr/lib/systemd/system/fail2ban.service; enabled; preset: enabled) 3 Active: active (running) since Wed 2025-03-19 09:23:21 JST; 4 days ago 4 Docs: man:fail2ban(1) 5 Main PID: 145177 (fail2ban-server) 6 Tasks: 5 (limit: 9440) 7 Memory: 22.1M (peak: 33.2M) 8 CPU: 5min 35.073s 9 CGroup: /system.slice/fail2ban.service 10 └─145177 /usr/bin/python3 /usr/bin/fail2ban-server -xf start
もし、デフォルトで起動していなけば:
bash
1sudo systemctl start fail2ban #起動 2sudo systemctl enable fail2ban #再起動後も自動で立ち上がるように

「jail(ジェイル)」の確認

「fail2ban」は、ログ監視を「jail(ジェイル)」という単位で管理して実施しています。デフォルトでどうなっているかを確認します。
bash
1sudo fail2ban-client status
bash
1Status 2|- Number of jail: 1 3`- Jail list: sshd
上記のようにSSH接続を一つの「jail」として、監視していることがわかります。
jailで定義すること
  • どのログファイルを監視するか
  • どのパターン(正規表現)で攻撃を検出するか
  • 何回失敗したら ban するか
  • 何分間 ban するか
○「sshd」jailだけの状態を見る
稼働中の特定のjailの状態を確認するには:
bash
1sudo fail2ban-client status sshd
私の環境(サーバ構築し始めてから2週間ほどの経過)では:
bash
1Status for the jail: sshd 2|- Filter 3| |- Currently failed: 0 4| |- Total failed: 13622 5| `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd 6`- Actions 7 |- Currently banned: 2 8 |- Total banned: 1216 9 `- Banned IP list: xxx.xxx.xxx.xxx xxx.xxx.xxx.xxx
こんな感じです。まだ、なんのサイトも公開していない状態で、この攻撃数です。。
  • Total failed: 13622 <-この jail が有効になってから記録された 累計ログインなどの失敗回数。13622回って…攻撃すごい
  • `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd <- テキストログではなく、ジャーナルで監視中
  • Total banned: 1216 <- 過去累計で BANしたIPアドレス数
systemd-journal(ジャーナル)について
systemd-journal(ジャーナル)とは、systemd によるログ管理の仕組みで、サービスのログをバイナリ形式で保存しているログデータベースです。
rsyslogとの比較:
項目rsyslogsystemd-journal
保存形式テキストファイルバイナリ形式
ログ保存先/var/log/*.log/var/log/journal/(またはメモリ)
読み方less や tailjournalctl コマンド
管理単位サービス単位で設定要systemd unit ごとに自動
journalctl コマンド(ログ確認)例:
bash
1sudo journalctl -u ssh -e --no-pager
  • ここは混乱しないようにしないといけません。ubuntu24.04ではsshdではなくsshで動いています。fail2bansshdとして監視しています。

2.SSH jail の設定内容を確認する

fail2ban が「sshd」jail を有効にしているということは、どこかにその定義があるはずです。 fail2ban の jail 設定は複数の場所にまたがって管理されるので、次の順に確認していくとわかりやすい!
まず、下記のコマンドでfail2bansshdが使われている場所をチェック:
bash
1sudo grep -Ri '\[sshd\]' /etc/fail2ban
bash
1/etc/fail2ban/filter.d/sshd.conf:# [sshd] 2/etc/fail2ban/filter.d/common.conf:# EXAMPLES: pam_rhosts_auth, [sshd], pop(pam_unix) 3/etc/fail2ban/action.d/abuseipdb.conf:# Example, for ssh bruteforce (in section [sshd] of `jail.local`): 4/etc/fail2ban/jail.conf:# [sshd] 5/etc/fail2ban/jail.conf:[sshd] 6/etc/fail2ban/jail.d/defaults-debian.conf:[sshd]
上記のような出力になります。#がついているところはコメンアウトされた状態で記載のある場所となりますので、現状では/etc/fail2ban/jail.conf/etc/fail2ban/jail.d/defaults-debian.confsshdの記載があることがわかります。
fail2banの構成
ディレクトリ内容
/etc/fail2ban/jail.confJailの定義(どのログを見る、何回失敗でBANなど)
/etc/fail2ban/jail.d/.conf、.localJailのカスタム定義、jail.confより優先される
/etc/fail2ban/filter.d/*.confフィルター定義(どんなログが「失敗」とみなされるか)
/etc/fail2ban/action.d/*.confアクション定義(BANする手段:iptables, nftablesなど)

デフォルトの設定(/etc/fail2ban/jail.conf)

というわけでまず、デフォルトの設定である/etc/fail2ban/jail.confを見てます。 ちなみ、この/etc/fail2ban/jail.confは直接編集などはせずに、/etc/fail2ban/jail.d/*.confのカスタム定義で設定を上書きする運用が推奨されているようです。なのであくまで参照だけにしましょう。
bash
1sudo less /etc/fail2ban/jail.conf
かなり長いテキストになっています。 [DEFAULT] セクションが上部にあります。これが、Fail2ban 全体に適用される「デフォルト設定」になります。 ピックアップします。
○基本動作設定
項目意味
bantime = 10mBANの時間(デフォルト10分)
findtime = 10m「何分間で何回失敗したか」をカウントする時間
maxretry = 5失敗許容回数(これを超えたらBAN)
maxmatches = %(maxretry)sログ上でのマッチ数上限。通常は maxretry と同じ
○ログ処理関連
項目意味
backend = autoログの監視方法。自動選択(systemd, polling など)
usedns = warnログ中のホスト名をどう扱うか(warnでDNS解決するけど警告も出す)
logencoding = autoログファイルのエンコーディング設定(自動)
○Jailの有効・モード設定
項目意味
enabled = falseデフォルトではjailは無効(各jailで個別に有効化する)
mode = normalフィルターの動作モード(defaultはnormal)
  • mode/etc/fail2ban/filter.d/*.confで定義されたものから選択。sshdなら/etc/fail2ban/filter.d/sshd.confに記述されているものから選択します。/etc/fail2ban/filter.d/sshd.confの内容は結構難しいです。。sshdのnormalモードだと「ログイン失敗」とか「異常な切断」がピックアップされて、さらに厳しくするなら、ddosaggressive というモードが用意されています。
○メール通知系設定
項目意味
sender = root@メールの送信元
mta = sendmailメール送信に使うMTA(sendmail)
destemail = root@localhost(コメントアウトされてるが使われる)通知先のメールアドレス(オーバーライド可能)
  • 私の環境だとメールサーバはpostfixなので、もしBANアクションで、メール通知も利用する場合は、このメール通知系は/etc/fail2ban/jail.d/*.confのカスタム定義で定義し直す必要があります。
○BANアクション系設定
項目意味
protocol = tcpBANする通信のプロトコル
chain = <known/chain>iptablesのチェイン指定
port = 0:65535BAN対象とするポート範囲(全部)
fail2ban_agent = Fail2Ban/%(fail2ban_version)s通信時のユーザーエージェント表記
banaction = iptables-multiportBANの際に使用するアクション(多ポート)
banaction_allports = iptables-allports全ポートBANのアクション
○アクションテンプレート(変数)
項目意味
action_実際のBANの基本アクション
action_mwBAN + メール通知(whoisあり)
action_mwlBAN + メール通知(whois + ログ行付き)
action_xarfBAN + abuse連絡メール(xarf形式)
action_cf_mwlCloudflare通報 + メール通知
action_blocklist_deblocklist.de に通報
action_abuseipdbabuseipdb に通報
action = %(action_)sデフォルトで使うアクションの指定
そして、下部の方に「sshd」の設定もあります。
less : jail.conf
1[sshd] 2 3# To use more aggressive sshd modes set filter parameter "mode" in jail.local: 4# normal (default), ddos, extra or aggressive (combines all). 5# See "tests/files/logs/sshd" or "filter.d/sshd.conf" for usage example and details. 6#mode = normal 7port = ssh 8logpath = %(sshd_log)s 9backend = %(sshd_backend)s
設定項目内容
portssh → 実際には /etc/services により 22番ポート
logpath%(sshd_log)s → /var/log/auth.log
backend%(sshd_backend)s → systemd
sshd_logsshd_backendは変数になっていて、/etc/fail2ban/paths-debian.conf → before = paths-common.conf として参照を定義されていて、実際には、/etc/fail2ban/paths-common.confに変数の定義があります。
bash : paths-common.conf
1syslog_authpriv = /var/log/auth.log 2default_backend = %(default/backend)s
  • default/backendとはこの後すぐに参照する/etc/fail2ban/jail.d/defaults-debian.confの[DEFAULT]セクションにあるbackendの定義を利用するという指定
いくつかのファイルをまたいで定義されているので、追いかけるのは少し大変です。

デフォルトのカスタム定義(/etc/fail2ban/jail.d/defaults-debian.conf)

前述の/etc/fail2ban/jail.confを上書きする定義ファイルを/etc/fail2ban/jail.d/*.confとして設置するのですが、/etc/fail2ban/jail.d/defaults-debian.confには、カスタム定義のデフォルト定義があります。
bash
1sudo cat /etc/fail2ban/jail.d/defaults-debian.conf
bash : defaults-debian.conf
1[DEFAULT] 2banaction = nftables 3banaction_allports = nftables[type=allports] 4backend = systemd 5 6[sshd] 7enabled = true
[DEFAULT] セクションは、Fail2ban 全体に適用される「デフォルト設定」を定義しています。
banaction = nftables
これは「IPアドレスをBANする方法」の定義です。
ここで指定している nftables は、現在のUbuntuで標準になっている ファイアウォール管理フレームワークです。UbuntuのファイアウォールといえばUFWですが、これは実際はnftables裏側で動いています。少し前はiptablesがありましたが、これの進化版がnftablesです。Ubuntu24.04 nftables標準採用しているので、fail2banもこれを使いますって定義になっています。
banaction_allports = nftables[type=allports]
こちらは全ポートに対してブロックする時に使うアクション定義です。
type=allports を指定することで、ブロック対象になったIPからの すべての通信(TCP/UDP問わず)を拒否する設定になります。
bash
1[sshd] 2enabled = true 3banaction = %(banaction_allports)s <-例えば、こんな感じで使用します
backend = systemd
これは、Fail2ban がどのようにログを読み取るかを定義しています。
ログファイルではなく、systemd-journal(バイナリログ)から直接監視するという意味になっています。
[sshd]セクションはenabled = trueとして「監視対象とする」とだけ定義しています。具体的な監視内容は、/etc/fail2ban/jail.confの定義に委ねている状態とわかります。
fail2banjailポートごとに設定をしていくことになります。[sshd]などのセクションはプロトコル名を指しているのではありません。ポートの別名としてセクション名を設定しているわけです。
ここまで大枠を理解したら、次に具体的に利用しているポートごとの設定を行っていきます。

3.「Jail」の設定を実施

前提ですが、私の環境ですと、
  • sshは22番ポートは利用していない。仮に2222ポートを利用しているとします。
  • あとは基本的にデフォルトポートです。
今回の目標ですが、下記を監視対象していきます。
  • ssh(22)
  • ssh(2222)
  • メール送信系Postfix
  • メール受信系Dovecot
  • http/https系Nginx
最初は少し弱めにして、運用を開始してから徐々に変更していく想定です。

ssh(2222)専用 jail の定義

bash
1sudo vi /etc/fail2ban/jail.d/sshd-main.local
bash : sshd-main.local
1[sshd-main] 2enabled = true 3port = 2222 4filter = sshd 5backend = systemd 6logpath = %(sshd_log)s 7maxretry = 5 8findtime = 10m 9bantime.increment = true 10bantime.factor = 1 11bantime = 10m
  • filter = sshd/etc/fail2ban/filter.d/sshd.confの内容をそのまま流用します
  • bantime.increment = trueで繰り返しBAN対象になるならBAN時間を延長します
  • bantime.factor = 1でBAN時間を倍倍にしていきます(bantime.formula = ban.Time * (1 << ban.Count) * banFactor)

ssh(22)専用 jail の定義(ハニーポット的に)

これは厳しめに
bash
1sudo vi /etc/fail2ban/jail.d/sshd-trap.local
bash : sshd-trap.local
1[sshd-trap] 2enabled = true 3port = 22 4filter = sshd 5backend = systemd 6logpath = %(sshd_log)s 7maxretry = 3 8findtime = 10m 9bantime.increment = true 10bantime.factor = 2 11bantime = 10d

postfix jail の定義

ここは私の環境([サーバ構築編#10]参照)ですとDovecotのLMTPを利用してSMTP 認証(SASL AUTH)も Dovecot 側で処理しているので、不要なのですが、一応設定しておきます。ポートはDovecotの定義と重複しますが、ログは違うので問題ないです。
bash
1sudo vi /etc/fail2ban/jail.d/postfix.local
bash : postfix.local
1[postfix] 2enabled = true 3filter = postfix 4port = smtp,submission,465 5logpath = %(postfix_log)s 6backend = systemd 7maxretry = 3 8findtime = 10m 9bantime.increment = true 10bantime.factor = 1 11bantime = 10m
  • filter = postfix/etc/fail2ban/filter.d/postfix.confの内容をそのまま流用します

dovecot jail の定義

前述のとおり、SMTP 認証(SASL AUTH)も Dovecot 側で処理しているのでポートにSMTP関連も含めます。
bash
1sudo vi /etc/fail2ban/jail.d/dovecot.local
bash : postfix.local
1[dovecot] 2enabled = true 3filter = dovecot 4port = pop3,pop3s,imap,imaps,submission,465,sieve 5logpath = %(dovecot_log)s 6backend = systemd 7maxretry = 3 8findtime = 10m 9bantime.increment = true 10bantime.factor = 1 11bantime = 10m
  • filter = postfix/etc/fail2ban/filter.d/dovecot.confの内容をそのまま流用します

nginx jail の定義

webサーバはNginxを利用中です。これも設定しておきます。Nginx用のフィルタを4つあります。
フィルター名概要
nginx-http-authHTTP Basic 認証の失敗ログを監視(管理者画面などへのブルートフォース防止)
nginx-botsearchボットが不審なURLにアクセスしてくるパターンを検出
nginx-bad-request不正なHTTPリクエスト(405, 400, etc)を検出
nginx-limit-reqNginx の limit_req モジュールで制限されたリクエストをトリガーに監視
このうちnginx-http-authnginx-botsearchを定義してみます。
Nginxは専用のテキストログを出力しているので、これを定義に利用します。 Nginx のように大量アクセスが想定されるサービスは、テキストログを使った polling の方がパフォーマンス的にも安定します。systemd-journalだと大量のアクセスログのようなものは扱いづらく、パフォーマンスに影響する可能性があるそうです。
bash
1sudo vi /etc/fail2ban/jail.d/nginx.local
bash : nginx.local
1[nginx-http-auth] 2enabled = true 3filter = nginx-http-auth 4port = http,https 5logpath = /var/log/nginx/*error.log 6backend = polling 7maxretry = 3 8findtime = 10m 9bantime = 1h 10 11[nginx-botsearch] 12enabled = true 13filter = nginx-botsearch 14port = http,https 15logpath = /var/log/nginx/*access.log 16backend = polling 17maxretry = 10 18findtime = 10m 19bantime = 1h

4. fail2banの再起動と動作確認

設定の反映

jailの設定を反映するために、fail2banを再起動します。
bash
1sudo systemctl restart fail2ban
fail2banの起動確認
bash
1sudo systemctl status fail2ban
読み込まれている jail の一覧確認
bash
1sudo fail2ban-client status
bash
1Status 2|- Number of jail: 7 3`- Jail list: dovecot, nginx-botsearch, nginx-http-auth, postfix, sshd, sshd-main, sshd-trap
上記のように設定したjailが読み込まれていればOKです。
あとはログを少し観察して、意図した通りにBANされるか、誤検出がないかを確認すれば安心です。

fail2banのログ

メインのログ/var/log/fail2ban.log:
bash
1sudo less /var/log/fail2ban.log
systemd journal 経由で fail2ban のログ確認:
bash
1sudo journalctl -u fail2ban -e --no-pager
リアルタイムで追いたいときは:
bash
1sudo journalctl -u fail2ban -f

IPごとの状態確認

現在BANされているIP一覧を確認するには、jailごとに見る:
bash
1sudo fail2ban-client status sshd-trap 2sudo fail2ban-client status sshd-main 3sudo fail2ban-client status dovecot 4sudo fail2ban-client status postfix 5sudo fail2ban-client status nginx-http-auth 6sudo fail2ban-client status nginx-botsearch
以上、fail2banの基本設定も完了です。 これで、サーバ構築は一旦完了です。運用を開始できるのではないかと思います。
前回の確認はこちら...
この記事の執筆・編集担当
DE

松本 孝太郎

DELOGs編集部/中年新米プログラマー

ここ数年はReact&MUIのフロントエンドエンジニアって感じでしたが、Next.jsを学んで少しずつできることが広がりつつあります。その実践記録をできるだけ共有していければと思っています。