Fail2Banの再インストールと設定の見直し

コンピューターに不正にアクセス
©いらすとや.

メールサーバやウェブサーバをインターネットに公開していると、どうしても迷惑さん達がたくさんやってくる。
メールサーバやウェブサーバでログを録って、Fail2Banでそのログをリアルタイムで監視する。
ログインに失敗したとか何か悪さしようとしているログが記録されしだい、FailBanはただちにそのログを検知して指定された動作をする。多くの場合はそのログに記録されたIPアドレスをパケットフィルタに登録して、その後しばらく(指定した期間)はそのIPアドレスからの通信を受け付けないようにする。なお、Fail2Banという名前だからといってかならず「ログイン失敗」→「Banする(ハブる)」という用途にしか使ってはいけないということはない。

「がとらぼ」の中の人はずいぶん長くFail2Banを利用している(でも詳しくはない)が、突然1台のホストのFail2Banが調子が悪くなった。ログにどんどん認証失敗のログが溜まっているのに殆ど反応しない。完全に反応しないというのではなく中途半端が一番困る。で、自分でFail2Banのフィルタールールを作って登録して動作テストを行ったのだが、やはり全く反応しないわけではないが「問題発生のログ」に殆ど反応しない。Fail2Banのログに何か異常が出ていれば対応のしようもあるのだが問題なし。Fail2Banを再起動しても変わらず。

Fail2Ban関係で変わったといえば、Fail2Banの最新版の0.11.2が出たのが昨年2020年11月。これは半年以上前なので関係なさそう。
FreeBSDのPortsでFail2Banの最新版が出たのが2021年6月15日、問題の発生しているホストでPorts/PKGを最新版に更新したのが7月前半。これっぽい。
FreeBSDのPortsのFail2Banの最新版0.11.2_1の変更点の注意書きは、「PKG/PortsでイントールしたFail2Banを稼働させるためにディレクトリが足りなくてもユーザーの責任でなんとかしろ云々」(意味不明)
まぁ、ports/PKGで何か足りなくてもユーザーでどうにかしてねっていうのはFail2Banに限らずports/PKG全般そうじゃないかとは思うけど、何か問題が発生してるのかな?
とりあえず、FreeBSDのports/PKGでインストールしたFail2Banは多くのファイルがports/PKGの削除時に自動的に削除される。更新時も殆どのファイルが一時的に削除されて新しい版のファイルが置き直される。ユーザーが作成した設定ファイル・フィルタファイル・アクションファイルはFail2Banのディレクトリに残る。
ただし、/var/db/fail2Banに作成されるsqlite3のデータベースファイルはports/PKGを削除・更新しても消されずに残る。Fail2Banで大きな変更があってデータの構成が変わった際は注意。「がとらぼ」の人は大きな変更があったらFail2Banを停止してsqlite3ファイルを削除してfail2Banを改めて立ち上げるようにしている。

今回の動作異常は

  1. Fail2Banを停止
  2. Fail2Banを削除
  3. Pythonを再ビルド&再インストール
  4. Fail2Banの設定ディレクトリ/usr/local/etc/fail2banを退避
  5. /var/db/fail2ban ディレクトリを削除
  6. Fail2Banをビルド&インストール
  7. Fail2Banの再設定
  8. Fail2Banの起動
以上で結果的に直ってしまった。(Fail2Banの再インストールだけではダメだった)
ただ、Fail2Banはバージョン更新で意外と多くが変わるようなので設定ファイルも1から見直すべき。

FreeBSDのPorts/PKGではFreeBSD用にパッチの当たった状態でFail2Banがインストールされるため/usr/local/etc/fail2banのfail2ban.confはFreeBSD向けのPath設定になっている。メインの初期設定のjail.confもFreeBSDでよく使われるアプリのログのPathが記載されたpaths-freebsd.confを読み込む設定が最初から入っている。

[INCLUDES]

#before = paths-distro.conf
before = paths-freebsd.conf

fail2ban.confとjail.confを含め/usr/local/etc/fail2banにある設定ファイルはports/PKGを更新すると一旦削除されて新しいファイルに置き換えられるためユーザーが編集してはいけない。
jail.confの設定を変更したいなら同じディレクトリにjail.localというファイルを新規で作成して、その中に変更したい(または追加したい)内容だけを書くとその設定が優先で使用される。(オーバーライド)
そして、jail.confには初期値があるだけでなく設定の書き方の参考にもなるのでしっかり見る。

たとえは、Postfixであればjail.confの[Postfix]セクション(Jail)に設定が書かれているがこの設定は有効化されていない状態。 なので /usr/local/etc/fail2ban/jail.local (無ければ作成)には
[postfix]
enabled  = true

と書いてやればjail.confの[postfix]セクションに書かれた設定でそのルールが有効化される。(ただし、アクションなど他の設定が未指定だと機能するか不明)

また、Fail2Banの0.10まではではPostfix用の設定は分かれていなかったような記憶があるが、少なくともFail2Ban 0.11系ではPostfixの設定は複数存在する。 Postfix用のフィルターファイルは /usr/local/etc/fail2ban/filter.d/postfix.conf の1つなのでそこにいろいろ書かれている。また、セクションが複数あるだけでなく 0.10からはmodeもあるのでさらに細分化されている。 jail.localには使用するセクションをenabled = trueにするだけでなく使用するモードも書く。例: mode = more
たとえばPostfixでSMTP認証を実装するのにSASLを使っているとすると、fail2Banには[postfix-sasl]というセクションが用意されているので有効化する。fail2ban 0.9系まではPostfixのSASL関係のログを検知するフィルタは存在せず、0.10で[postfix]の中にSASL関係のログを検知するフィルタが入り、0.11で[postfix]からSASL関係のログを検知するフィルタが外れて[postfix-sasl]に入った。バージョン毎に違うため要確認。

jail.localの例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 192.168.0.0/24 fd00::/16
bantime  = 6h
findtime  = 12h
maxretry = 3
destemail = foobar@example.com
action = pf[name=%(__name__)s, bantime="%(bantime)s", actiontype=<allports>]    #←パケットフィルタpfでBanする
         %(mta)s-whois[name=%(__name__)s, sender="%(sender)s", dest="%(destemail)s"] #←IPアドレスの素性をwhoisで引いてメールする
         webhook[]    #←この行はpfのフィルタリングを実行すると共にwebhookで通知する (新規にwebhookアクションを作った場合)
         #アクションは必要に応じて複数設定可、それぞれ1行で書く


[postfix]
enabled  = true

[postfix-sasl] #(SASLの認証等を使っているなら)jail.confに書かれているpostfixフィルタのオプションモードの有効化 jail.confは変更せずにjail.localで指定
enabled  = true
bantime = 12h
maxretry = 1

本来はセクション別にでも監視対象のログファイルを指定してやるところだが、メジャーなアプリケーションは必要無い場合がある。
postfixのログの場合、jail.confで before = paths-freebsd.conf が指定されていて、そのpaths-freebsd.confの中でさらに before = paths-common.conf が指定されていて paths-common.conf の中で postfix_log = %(syslog_mail_warn)s と指定されている。戻って、 paths-freebsd.conf の中で postfix_log = %(syslog_mail_warn)s と指定されているため、jail.confの[postfix]セクションで指定されている logpath = %(postfix_log)s は logpath = /var/log/maillog ということになる。これが初期値なので jail.local でログファイルを指定する必要はないということになる。
postfixのログの出力先を変更しているということであれば、logpath = hoge という設定をjail.localの[postfix]セクションに追加する。

Webhook用のアクションを作る

/usr/local/etc/fail2ban/action.d/webhook.conf (新規)
1
2
3
4
5
[Definition]

actionban = /usr/local/bin/curl -X POST \
            -d '{"name":"fail2ban-<name>", "server":"<fq-hostname>", "address":"<ip>"}' \
            https://example.com/webhook/listener.php

この例では https://example.com/webhook/listener.php がwebhookの受け手。(この記事では省略)
<name>, <fq-hostname>, <ip> はfail2banで使われる変数。

# service fail2ban start    #Fail2Banの起動  

動作確認

# fail2ban-client status
Status
|- Number of jail:      5
`- Jail list:   dovecot, postfix, postfix-sasl, rainloop, recidive

fail2ban-clientコマンドに引数 status を付けると稼働中のセクション(Jail=牢獄)のリストが表示される。設定で有効にしたセクション名が全て表示されていて不足・過剰がないこと。
この例ではdovecot, postfix, postfix-sasl, rainloop, recidiveの5つのセクションが有効であることが判る。

# fail2ban-client status postfix-sasl
Status for the jail: postfix-sasl
|- Filter
|  |- Currently failed: 0
|  |- Total failed:     0
|  `- File list:        /var/log/maillog
`- Actions
   |- Currently banned: 2
   |- Total banned:     2
   `- Banned IP list:   192.168.59.101 192.168.59.142

statusの後にセクション名を追加するとそのセクションの状態が表示される。
この例ではpostfix-sasl (SMTP認証)では/var/log/maillogを監視していて、現在は2つのIPアドレスをBanした状態で、そのBan済みのIPアドレスは192.168.59.101, 192.168.59.142であることが判る。ここで表示されるIPアドレスはFail2Banで管理しているIPリストなので別途パケットフィルタの設定が正しく行われていなければこの通りに「弾く」ことはできない。パケットフィルタ側でも現在BanしているIPアドレスリストを表示してFail2Ban側と同じIPアドレスがBanされていることを確認する。

最近のfail2ban-clientコマンドではかなり多くのことができる。 --help を付けて実行すると使い方が表示される。