fail2banとは
公式 / github: https://github.com/fail2ban/fail2ban
Fail2Ban: ban hosts that cause multiple authentication errors
ログファイルを定期的に見て送信元IPアドレスをiptables等で一時的および恒久的に拒否するツールのこと。
ログの形式に対して対応できるので自作可能だが
標準で各種アプリケーションのログ監査と対処するルールがすでに用意されている。
例えば以下のとおり(0.11を参考)
- apache-auth.conf : 認証を試みるアクセスに対応
- sshd.conf : SSHブルートフォースアタックを検知
- postfix.conf : エラーコードに対応。また認証失敗も検知可能。
他にも様々なルールがデフォルトで用意されている。
インストール
導入は簡単。
Centos系なら yum install fail2ban-server
をepelで。
設定
主に設定するファイルは以下。 /etc/fail2ban
配下。
-
fail2ban.conf
... メイン設定。ログレベルなど。データベースはsqlite3を使用-
/var/lib/fail2ban/fail2ban.sqlite3
に保存。
-
-
jail.conf
... [INCLUDE]に注目。Centosならfedora系とみなして/etc/fail2ban/paths-fedora.conf
を参照している。- ここでログのデフォルトの設定を定義しているのでルール設定によっては参照される
-
paths-common.conf
も参照される -
ignoreip
の設定は必要。送信元IPアドレスで除外したい対象を指定。カスタマイズルールで用意可能だが、基本参照として用意するのはあり。 - ただしカスタマイズは別途jailを用意して上書き設定するのが基本
設定方法
今回の目的はpostfixのsasl認証に対してfail2banで制御したい。
ポート番号を開いてsasl認証を許しているとそれなりに認証を試みる動きはある。
その行動に対して動的にiptablesでREJECTしたい時のやり方です。
[postfix-sasl]
enabled = true
logpath = %(postfix_log)s
maxretry = 50
findtime = 600
bantime = 1800
backend = %(postfix_backend)s
基本IP単位で見るので、送信元IPアドレスが上記の条件を満たしたらfail2banのban候補になる。
-
enable
... ture or falseで有効/無効。 -
logpath
... これはpostfix_log
の定義を見る。望む設定と違うパスなら直接記載に変更 -
maxretry
... パターンの試行回数の閾値。今回だと50回に達したとき -
findtime
... maxretryの回数の時間幅。今回だと600秒=10分。よって10分で50回パターンにひっかかれば、という条件になる。 -
bantime
... この設定がきも。実際にアクセスを拒否する時間。1800なら秒なので30分一時的に拒否する。
この設定を起動時に読み込むようにしている。
今回は設定していないが通知先をメールアドレス宛に指定することも可能なのでslack連携などもできる。
/etc/fail2ban/filter.d/postfix-sasl.conf
今回用いたルールはfilter.d配下にあるpostfix-sasl.confを参照している。
一部抜粋。
[Definition]
_daemon = postfix(-\w+)?/(?:submission/|smtps/)?smtp[ds]
failregex = ^%(__prefix_line)swarning: [-._\w]+\[<HOST>\]: SASL ((?i)LOGIN|PLAIN|(?:CRAM|DIGEST)-MD5) authentication failed(:[ A-Za-z0-9+/:]*={0,2})?\s*$
ignoreregex = authentication failed: Connection lost to authentication server$
今回使用したルールより、エラーログパターンは
warning: SASL authentication failure: Password verification failed
に該当する送信元IPが対象。
ignoreregex
の設定により除外ルールも設定されている。
その数をカウントすることができる。
puppetで構成管理
lelutin/puppet-fail2ban: Manage fail2ban and its jails with puppet
今回はこちらを用いたでの設定が容易であった。
以下の設定を用意することで先ほどの設定を簡易にコントールすることができる。
class mail::fail2ban {
class { 'fail2ban':
ignoreip => ['127.0.0.1'],
loglvl => 'NOTICE',
}
$postfix_sasl_extra_params = {
'bantime' => 1800,
'maxretry' => 50,
'findtime' => 600,
}
$postfix_sasl_params = lookup('fail2ban::jail::postfix-sasl') + $postfix_sasl_extra_params
fail2ban::jail { 'postfix-sasl':
* => $postfix_sasl_params,
}
}
観測
インストールし設定後起動。
/var/log/fail2ban.log
を見る。
※ ログレベルのデフォルトは INFO
だが NOTICE
と最初はしぼらないほうが動きが見えてよい。
検知
2019-08-15 22:34:53,085 fail2ban.filter [950]: INFO [postfix-sasl] Found 91.xxx.yyy.zzz
2019-08-15 22:35:01,752 fail2ban.filter [950]: INFO [postfix-sasl] Found 126.xx.yyy.zzz
2019-08-15 22:35:01,768 fail2ban.filter [950]: INFO [postfix-sasl] Found 126.xx.yyy.zzz
2019-08-15 22:35:01,798 fail2ban.filter [950]: INFO [postfix-sasl] Found 126.xx.yyy.zzz
INFOレベルであれば検知した時点でログに記録される。
たくさん流れるようであればそれだけ試行回数を稼がれているということ。
その流量によって、さきほど用意した設定の値を書き換えるとよい。
このとき、bantimeが短ければ誤検知を防ぎやすいので調整するとよい。
fail2ban.filter
の動きを見る。
実際のban
banするとログは以下。
fail2ban.actions
を見る。
2019-08-22 10:18:05,975 fail2ban.actions [950]: NOTICE [postfix-sasl] Ban 188.xxx.yyy.zzz
2019-08-22 10:48:06,624 fail2ban.actions [950]: NOTICE [postfix-sasl] Unban 188.xxx.yyy.zzz
bantimeによるのでban解除も自動的に実行される。
bantimeが30分だったのでその時間の分だけ発動。
解除されればunban
と表記される。
ただし、しつこく同様の対象がいた場合はban/unbanが繰り返される。
恒久的にbanする
bantime -1
を使う。
これで恒久的に対象をbanすることができる。
基本的には解除はコマンドで可能なので様子見後導入するのはありだろう。
fail2ban-client
fail2ban-client status
で現在のbanのIPアドレスを調査可能。
引数はjail名
を指定する。
例えば今回用意した設定だと以下の稼働を得る。
$ sudo fail2ban-client status postfix-sasl
Status for the jail: postfix-sasl
|- Filter
| |- Currently failed: 1
| |- Total failed: 439
| `- Journal matches: _SYSTEMD_UNIT=postfix.service
`- Actions
|- Currently banned: 2
|- Total banned: 2
`- Banned IP list: 103.xx.y.zzz 113.xxx.yy.zz
Banned IP list
を見る。この値が実際にbanされた対象。
bantimeに応じてunbanされる。
また、設定の反映としてfail2ban-client reload
もある。
恒久的にIPは残るので個別削除も検討するときもある。
その場合は fail2ban-client set <JAIL> unbanip <IP>
ただし、上記は古い方法。
今はIPそのものを全てのjailに対して実行可能。
公式のトラブルシューティングより fail2ban-client unban <IP>
送信元IPアドレスを制御した状態とは
iptablesでデフォルトでREJECTをしているがDROPがよい場合はそちらも設定で変更可能。
今回の設定だと以下の表示をiptablesとして独自に用意される。
$ sudo iptables -L -n
Chain INPUT (policy ACCEPT)
target prot opt source destination
f2b-postfix-sasl tcp -- 0.0.0.0/0 0.0.0.0/0 multiport dports 0:65535
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain f2b-postfix-sasl (1 references)
target prot opt source destination
reject-with icmp-port-unreachable
REJECT all -- 113.xxx.yy.zz 0.0.0.0/0 reject-with icmp-port-unreachable
REJECT all -- 103.xx.y.zzz 0.0.0.0/0 reject-with icmp-port-unreachable
RETURN all -- 0.0.0.0/0 0.0.0.0/0
これが動的に変化する。
停止すればiptablesの上記の設定は一時的に消える。
fail2banを再起動してもiptalbesの設定は復活する。
まとめ
流れるログファイルさえあれば、どんなログでもban対象作成可能。
正規表現を使えるがルールが複雑化するので今あるルール設定でできることがないかという視点で十分と思われる。
参考サイト
CentOS7 fail2banでSSH, SMTPへの攻撃からサーバを守る - Qiita
Fail2BanでRainLoopへの不正アクセスをBANする - Qiita
fail2ban で Wordpress のログイン攻撃を防ぐ - Qiita
fail2banでslackに通知する - Qiita