Debian 10 + nftables + fail2ban

はじめに

インストールはこちら

nftablesを使ったアクセス制御はこちら

fail2banとは

ログを監視してTCPで提供されているサービスに過剰にアクセスしてくるIPアドレスを一定時間アクセスさせないようにするソフトウェア。

Debian 10での注意点

Debian 9まではiptablesで動いており、Debian 10でもデフォルトの設定はiptablesベースになっている。このため、nftablesを使ってアクセス制御をしている場合には、適宜設定変更をしてあげないといけない。

fail2banのインストールと設定

インストールする。

% sudo apt install fail2ban

設定ファイルは /etc/fail2ban以下におかれる構成は以下の通り。

% ls -1
action.d/ 
fail2ban.conf
fail2ban.d/
filter.d/
jail.conf
jail.d/
paths-arch.conf
paths-common.conf
paths-debian.conf
paths-opensuse.conf

jail.conf を編集する。 ignoreipで監視対象外のIPアドレスを指定し、banactionとbanaction_allportsでiptablesからnftablesを使うように設定を変更する。

% cd /etc/fail2ban
% sudo cp -p jail.conf jail.conf.org
% sudo vi jail.conf
% iff jail.conf.org jail.conf
54a55
> ignoreip = 127.0.0.1/8 ::1 XXX.XXX.XXX.XXX/24  # 監視対象外のIPアドレス
167,168c168,171
< banaction = iptables-multiport
< banaction_allports = iptables-allports
---
> #banaction = iptables-multiport
> banaction = nftables-multiport
> #banaction_allports = iptables-allports
> banaction_allports = nftables-allports

Debian 10では標準でsshがfail2banの監視対象となっている。どのポート(サービス)を監視するのかは jail.confにサービスと設定の一覧があるので、それを利用する。たとえば、 SMTP, SMTP AUTH, POP3, POP3Sなどをまとめて監視する postfix-sasl は /etc/jail.conf に以下のように定義されている。

[postfix-sasl]

filter   = postfix[mode=auth]
port     = smtp,465,submission,imap,imaps,pop3,pop3s
# You might consider monitoring /var/log/mail.warn instead if you are
# running postfix since it would provide the same log lines at the
# "warn" level but overall at the smaller filesize.
logpath  = %(postfix_log)s
backend  = %(postfix_backend)s

これを有効にする場合には以下のように /etc/jail.d/以下にファイルをおき、有効にする。

% cd jail.d/
% sudo touch postfix-sasl.conf
% sudo vi postfix-sasl.conf

postfix-sasl.confの内容は以下のように記載する。

[postfix-sasl]
enabled = true


繰り返しBanされるIPを長期間Banする。

% sudo touch recidive.conf
% sudo vi recidive.conf

recidive.conf内容は以下のとおり。

[recidive]
enabled = true

ただし、nftablesを使っている場合は上記の設定のままではうごかない(nftablesが /etc/services に記載されているポート名を参照しているため。postfix-saslの
ルールの場合 "465"というポート名が /etc/services に存在しない)

自分用のルールを /etc/jail.localとして記載する。

% sudo touch /etc/fail2ban/jail.local
% sudo vi /etc/fail2ban/jail.local

jail.localの内容を以下のようにする。(postfix-saslから 465, imap, imapsを除いている)

[postfix-sasl-custom]

filter   = postfix[mode=auth]
port     = smtp,submission,pop3,pop3s
logpath  = %(postfix_log)s
backend  = %(postfix_backend)s

postfix-sasl.confの内容を以下のように編集する。

[postfix-sasl-custom]
enabled = true

fail2banを再起動する。

% sudo systemctl stop fail2ban
% sudo systemctl start fail2ban

しばらくたつと、fail2banがnftablesに自動的にルールを追記してくれる。fail2banの再起動時のログをみる。

% tail /var/log/fail2ban.log
2019-11-18 14:19:22,813 fail2ban.server         [30494]: INFO    Starting Fail2ban v0.10.2
2019-11-18 14:19:22,819 fail2ban.database       [30494]: INFO    Connected to fail2ban persistent database '/var/lib/fail2ban/fail2ban.sqlite3'
2019-11-18 14:19:22,820 fail2ban.jail           [30494]: INFO    Creating new jail 'sshd'
2019-11-18 14:19:22,828 fail2ban.jail           [30494]: INFO    Jail 'sshd' uses pyinotify {}
2019-11-18 14:19:22,830 fail2ban.jail           [30494]: INFO    Initiated 'pyinotify' backend
2019-11-18 14:19:22,830 fail2ban.filter         [30494]: INFO      maxLines: 1
2019-11-18 14:19:22,852 fail2ban.server         [30494]: INFO    Jail sshd is not a JournalFilter instance
2019-11-18 14:19:22,853 fail2ban.filter         [30494]: INFO    Added logfile: '/var/log/auth.log' (pos = 10278741, hash = e1979e4153ef60220060b0b8d7d29f43e947154f)
2019-11-18 14:19:22,853 fail2ban.filter         [30494]: INFO      encoding: UTF-8
2019-11-18 14:19:22,854 fail2ban.filter         [30494]: INFO      maxRetry: 5
2019-11-18 14:19:22,854 fail2ban.filter         [30494]: INFO      findtime: 600
2019-11-18 14:19:22,855 fail2ban.actions        [30494]: INFO      banTime: 600
2019-11-18 14:19:22,857 fail2ban.jail           [30494]: INFO    Creating new jail 'recidive'
2019-11-18 14:19:22,857 fail2ban.jail           [30494]: INFO    Jail 'recidive' uses pyinotify {}
2019-11-18 14:19:22,860 fail2ban.jail           [30494]: INFO    Initiated 'pyinotify' backend
2019-11-18 14:19:22,863 fail2ban.server         [30494]: INFO    Jail recidive is not a JournalFilter instance
2019-11-18 14:19:22,863 fail2ban.filter         [30494]: INFO    Added logfile: '/var/log/fail2ban.log' (pos = 3405917, hash = 6fcbaf803079b747ecdbd1658eb6884f5241503f)
2019-11-18 14:19:22,865 fail2ban.filter         [30494]: INFO      encoding: UTF-8
2019-11-18 14:19:22,866 fail2ban.filter         [30494]: INFO      maxRetry: 5
2019-11-18 14:19:22,866 fail2ban.filter         [30494]: INFO      findtime: 86400
2019-11-18 14:19:22,866 fail2ban.actions        [30494]: INFO      banTime: 604800
2019-11-18 14:19:22,869 fail2ban.jail           [30494]: INFO    Creating new jail 'postfix-sasl-custom'
2019-11-18 14:19:22,870 fail2ban.jail           [30494]: INFO    Jail 'postfix-sasl-custom' uses pyinotify {}
2019-11-18 14:19:22,872 fail2ban.jail           [30494]: INFO    Initiated 'pyinotify' backend
2019-11-18 14:19:22,877 fail2ban.server         [30494]: INFO    Jail postfix-sasl-custom is not a JournalFilter instance
2019-11-18 14:19:22,878 fail2ban.filter         [30494]: INFO    Added logfile: '/var/log/mail.log' (pos = 11829048, hash = 5f203d2833f79fe76e8db1a83af3c1419b8708dd)
2019-11-18 14:19:22,879 fail2ban.filter         [30494]: INFO      encoding: UTF-8
2019-11-18 14:19:22,880 fail2ban.filter         [30494]: INFO      maxRetry: 5
2019-11-18 14:19:22,880 fail2ban.filter         [30494]: INFO      findtime: 600
2019-11-18 14:19:22,881 fail2ban.actions        [30494]: INFO      banTime: 600
2019-11-18 14:19:22,885 fail2ban.jail           [30494]: INFO    Jail 'sshd' started
2019-11-18 14:19:22,889 fail2ban.jail           [30494]: INFO    Jail 'recidive' started
2019-11-18 14:19:22,891 fail2ban.jail           [30494]: INFO    Jail 'postfix-sasl-custom' started
2019-11-18 14:19:29,395 fail2ban.filter         [30494]: INFO    [postfix-sasl-custom] Found 46.38.144.32 - 2019-11-18 14:19:29
〜省略〜

Debian 10 (buster)のnftablesでアクセス制御 - 発声練習で設定したとおりに/etc/nftable.confを設定しておくと、banしたIPアドレスが存在したときに fail2banが勝手に nftにルールを追加してくれる。たとえば以下のとおり。

# nft list ruleset
table inet filter {
	set f2b-postfix-sasl-custom {                                     # fail2banが自動追加
		type ipv4_addr                                                  # fail2banが自動追加
		elements = { 46.38.144.32, 46.38.144.179 }    # fail2banが自動追加
	}

	chain input {
		type filter hook input priority 0; policy accept;
		tcp dport { smtp, pop3, submission, pop3s } ip saddr @f2b-postfix-sasl-custom reject   # fail2banが自動追加
	}

	chain forward {
		type filter hook forward priority 0; policy accept;
	}

	chain output {
		type filter hook output priority 0; policy accept;
	}
}
〜 以下、略 〜

現時点でbanされているIPアドレスをみる場合は以下のコマンドで調べる。たとえば、私の環境では以下のようになった。

% sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed:	0
|  |- Total failed:	0
|  `- File list:	/var/log/auth.log
`- Actions
   |- Currently banned:	0
   |- Total banned:	0
   `- Banned IP list:	

% sudo fail2ban-client status postfix-sasl-custom
Status for the jail: postfix-sasl-custom
|- Filter
|  |- Currently failed:	5
|  |- Total failed:	66
|  `- File list:	/var/log/mail.log
`- Actions
   |- Currently banned:	5
   |- Total banned:	12
   `- Banned IP list:	46.38.144.57 46.38.144.146 92.118.38.38 46.38.144.17 92.118.38.55

トラブルシューティング: nftableへの切替設定ミス

nftablesでアクセス制限しているのに、/etc/jail.conf では iptables-multiport, iptables-allportを設定していると以下のようなエラーログが/var/log/fail2ban.logにでる。

2019-11-15 22:28:39,154 fail2ban.utils          [440]: Level 39 7f65406a1e68 -- exec: iptables -w -n -L INPUT | grep -q 'f2b-sshd[ \t]'
2019-11-15 22:28:39,154 fail2ban.utils          [440]: ERROR   7f65406a1e68 -- stderr: "iptables v1.8.2 (nf_tables): table `filter' is incompatible, use 'nft' tool."
2019-11-15 22:28:39,154 fail2ban.utils          [440]: ERROR   7f65406a1e68 -- stderr: ''
2019-11-15 22:28:39,154 fail2ban.utils          [440]: ERROR   7f65406a1e68 -- returned 1
2019-11-15 22:28:39,154 fail2ban.CommandAction  [440]: ERROR   Invariant check failed. Trying to restore a sane environment
2019-11-15 22:28:39,217 fail2ban.utils          [440]: Level 39 7f65406a1e68 -- exec: iptables -w -n -L INPUT | grep -q 'f2b-sshd[ \t]'
2019-11-15 22:28:39,218 fail2ban.utils          [440]: ERROR   7f65406a1e68 -- stderr: "iptables v1.8.2 (nf_tables): table `filter' is incompatible, use 'nft' tool."
2019-11-15 22:28:39,218 fail2ban.utils          [440]: ERROR   7f65406a1e68 -- stderr: ''
2019-11-15 22:28:39,218 fail2ban.utils          [440]: ERROR   7f65406a1e68 -- returned 1
2019-11-15 22:28:39,218 fail2ban.CommandAction  [440]: CRITICAL Unable to restore environment
2019-11-15 22:28:39,218 fail2ban.actions        [440]: ERROR   Failed to execute ban jail 'sshd' action 'iptables-multiport' info 'ActionInfo({'ip': '2
22.186.180.147', 'family': 'inet4', 'ip-rev': '147.180.186.222.', 'ip-host': None, 'fid': '222.186.180.147', 'failures': 9, 'time': 1573824514.0, 'matches': 'Nov 15 22:28:10 ホスト名 sshd[985]: Failed password for root from 222.186.180.147 port 3320 ssh2\n
〜省略〜
': 9, 'ipjailfailures': 9})': Error banning 222.186.180.147

トラブルシューティング: nftablesに設定しているルールセットと一致していないとき

デフォルトでは「chain input」であることが記載されているがnftablesに設定しているルールセットで「chain INPUT」と設定されていると以下のサイトのようなエラーがでる。

トラブルシューティング: jail.conf で設定されているルールのサービスが /etc/services に存在しない

fail2banがnftablesへのルールセットにルールを追加する際に'Error: Could not resolve service: Servname not found in nft services list'というエラーがでている。

2019-11-17 01:02:27,961 fail2ban.utils          [1958]: Level 39 7f4fa70e3e40 -- exec: nft add set inet filter f2b-postfix-sasl \{ type ipv4_addr\; \}
nft insert rule inet filter input tcp dport \{ smtp,465,submission,imap,imaps,pop3,pop3s \} ip saddr @f2b-postfix-sasl reject
2019-11-17 01:02:27,961 fail2ban.utils          [1958]: ERROR   7f4fa70e3e40 -- stderr: 'Error: Could not resolve service: Servname not found in nft services list'
2019-11-17 01:02:27,961 fail2ban.utils          [1958]: ERROR   7f4fa70e3e40 -- stderr: 'insert rule inet filter input tcp dport { smtp,465,submission,
imap,imaps,pop3,pop3s } ip saddr @f2b-postfix-sasl reject'
2019-11-17 01:02:27,961 fail2ban.utils          [1958]: ERROR   7f4fa70e3e40 -- stderr: ' ^^^^'
2019-11-17 01:02:27,961 fail2ban.utils          [1958]: ERROR   7f4fa70e3e40 -- returned 1
2019-11-17 01:02:27,962 fail2ban.actions        [1958]: ERROR   Failed to execute ban jail 'postfix-sasl' action 'nftables-multiport' info 'ActionInfo(
{'ip': '46.38.144.179', 'family': 'inet4', 'ip-rev': '179.144.38.46.', 'ip-host': None, 'fid': '46.38.144.179', 'failures': 5, 'time': 1573920146.0, 'matches': 
'Nov 17 00:58:02 ホスト名 postfix/smtpd[24572]: warning: unknown[46.38.144.179]: SASL LOGIN authentication failed: authentication failure\n 〜略〜', 'ipfailures': 5, 'ipjailfail
ures': 5})': Error starting action Jail('postfix-sasl')/nftables-multiport

/etc/servicesの行頭に列挙されたサービス名でないとエラーがでる。調べ方は以下のとおり。上の例では"465"がひっかからないのでエラーとなっている。

% grep ^smtp /etc/services
smtp		25/tcp		mail

% grep ^465 /etc/services