我在 Raspbian Buster 上安装了 fail2ban 0.10.2-2.1 来保护 ssh(如果可行,还有 apache)。默认安装仅启用 sshd jail,但对我来说这似乎不起作用。fail2ban-client 报告 jail 正在运行:
$ 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:
但是,当我检查 iptables 规则是否已创建时,显示没有创建任何链,也没有禁止任何内容:
$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
据我所知,我预计 f2b-sshd 链会在该列表中。我检查了日志文件,即使我将 fail2ban.conf 配置为 outout DEBUG 级别,我也没有看到任何 iptables 操作:
2020-02-25 22:36:44,325 fail2ban.server [28901]: INFO --------------------------------------------------
2020-02-25 22:36:44,325 fail2ban.server [28901]: INFO Starting Fail2ban v0.10.2
2020-02-25 22:36:44,327 fail2ban.server [28901]: DEBUG Creating PID file /var/run/fail2ban/fail2ban.pid
2020-02-25 22:36:44,327 fail2ban.server [28901]: DEBUG Starting communication
2020-02-25 22:36:44,332 fail2ban.database [28901]: INFO Connected to fail2ban persistent database '/var/lib/fail2ban/fail2ban.sqlite3'
2020-02-25 22:36:44,337 fail2ban.jail [28901]: INFO Creating new jail 'sshd'
2020-02-25 22:36:44,381 fail2ban.jail [28901]: INFO Jail 'sshd' uses pyinotify {}
2020-02-25 22:36:44,382 fail2ban.filter [28901]: DEBUG Setting usedns = warn for FilterPyinotify(Jail('sshd'))
2020-02-25 22:36:44,382 fail2ban.filter [28901]: DEBUG Created FilterPyinotify(Jail('sshd'))
2020-02-25 22:36:44,393 fail2ban.filterpyinotify[28901]: DEBUG Created FilterPyinotify
2020-02-25 22:36:44,393 fail2ban.jail [28901]: INFO Initiated 'pyinotify' backend
2020-02-25 22:36:44,396 fail2ban.filter [28901]: INFO maxLines: 1
2020-02-25 22:36:44,397 fail2ban.server [28901]: DEBUG prefregex: '^<F-MLFID>(?:\\[\\])?\\s*(?:<[^.]+\\.[^.]+>\\s+)?(?:\\S+\\s+)?(?:kernel: \\[ *\\d+\\.\\d+\\]\\s+)?(?:@vserver_\\S+\\s+)?(?:(?:(?:\\[\\d+\\])?:\\s+[\\[\\(]?sshd(?:\\(\\S+\\))?[\\]\\)]?:?|[\\[\\(]?sshd(?:\\(\\S+\\))?[\\]\\)]?:?(?:\\[\\d+\\])?:?)\\s+)?(?:\\[ID \\d+ \\S+\\]\\s+)?</F-MLFID>(?:(?:error|fatal): (?:PAM: )?)?<F-CONTENT>.+</F-CONTENT>$'
2020-02-25 22:36:44,413 fail2ban.server [28901]: DEBUG failregex: '^[aA]uthentication (?:failure|error|failed) for <F-USER>.*</F-USER> from <HOST>( via \\S+)?\\s*(?: \\[preauth\\])?\\s*$'
...SNIP...
2020-02-25 22:36:44,513 fail2ban.server [28901]: DEBUG failregex: '^<F-MLFFORGET><F-NOFAIL>Accepted publickey</F-NOFAIL></F-MLFFORGET> for \\S+ from <HOST>(?:\\s|$)'
2020-02-25 22:36:44,518 fail2ban.server [28901]: DEBUG failregex: '^<F-NOFAIL>Connection from</F-NOFAIL> <HOST>'
2020-02-25 22:36:44,524 fail2ban.datetemplate [28901]: DEBUG constructed regex (?:^|\b|\W)((?P<Y>(?:202|201)\d)(?P<_sep>[-/.])(?P<m>1[0-2]|0[1-9]|[1-9])(?P=_sep)(?P<d>3[0-1]|[1-2]\d|0[1-9]|[1-9]| [1-9])(?:T| ?)(?P<H>2[0-3]|[0-1]\d|\d):(?P<M>[0-5]\d|\d):(?P<S>6[0-1]|[0-5]\d|\d)(?:[.,](?P<f>[0-9]{1,6}))?(?:\s*(?P<z>Z|UTC|GMT|[+-][01]\d(?::?\d{2})?))?)(?=\b|\W|$)
2020-02-25 22:36:44,525 fail2ban.datetemplate [28901]: DEBUG constructed regex ^(?:\W{0,2})?((?P<Y>(?:202|201)\d)(?P<_sep>[-/.])(?P<m>1[0-2]|0[1-9]|[1-9])(?P=_sep)(?P<d>3[0-1]|[1-2]\d|0[1-9]|[1-9]| [1-9])(?:T| ?)(?P<H>2[0-3]|[0-1]\d|\d):(?P<M>[0-5]\d|\d):(?P<S>6[0-1]|[0-5]\d|\d)(?:[.,](?P<f>[0-9]{1,6}))?(?:\s*(?P<z>Z|UTC|GMT|[+-][01]\d(?::?\d{2})?))?)(?=\b|\W|$)
2020-02-25 22:36:44,526 fail2ban.datetemplate [28901]: DEBUG constructed regex (?:^|\b|\W)(?iu)((?:(?P<a>mon|tue|wed|thu|fri|sat|sun) )?(?P<b>jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec) (?P<d>3[0-1]|[1-2]\d|0[1-9]|[1-9]| [1-9]) ?(?P<H>[0-2]?\d):(?P<M>[0-5]\d|\d):(?P<S>6[0-1]|[0-5]\d|\d)(?:\.(?P<f>[0-9]{1,6}))?(?: (?P<Y>(?:202|201)\d))?)(?=\b|\W|$)
...SNIP...
2020-02-25 22:36:44,544 fail2ban.datetemplate [28901]: DEBUG constructed regex ^(?:\W{0,2})?(?iu)((?:(?P<z>Z|UTC|GMT|[+-][01]\d(?::?\d{2})?) )?(?:(?P<a>mon|tue|wed|thu|fri|sat|sun) )?(?P<b>jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec) (?P<d>3[0-1]|[1-2]\d|0[1-9]|[1-9]| [1-9]) ?(?P<H>[0-2]?\d):(?P<M>[0-5]\d|\d):(?P<S>6[0-1]|[0-5]\d|\d)(?:\.(?P<f>[0-9]{1,6}))?(?: (?P<Y>(?:202|201)\d))?)(?=\b|\W|$)
2020-02-25 22:36:44,545 fail2ban.datetemplate [28901]: DEBUG constructed regex (@[0-9a-f]{24})(?=\b|\W|$)
2020-02-25 22:36:44,545 fail2ban.datetemplate [28901]: DEBUG constructed regex ^(?:\W{0,2})?(@[0-9a-f]{24})(?=\b|\W|$)
2020-02-25 22:36:44,546 fail2ban.server [28901]: INFO Jail sshd is not a JournalFilter instance
2020-02-25 22:36:44,549 fail2ban.filter [28901]: INFO Added logfile: '/var/log/auth.log' (pos = 111389, hash = 88b5563c0ca8a36a0cc3a0fa6c6110a8a17ca4aa)
2020-02-25 22:36:44,550 fail2ban.filterpyinotify[28901]: DEBUG New <Watch wd=1 path=/var/log mask=1073745280 proc_fun=None auto_add=False exclude_filter=<function WatchManager.<lambda> at 0x754a8e40> dir=True >
2020-02-25 22:36:44,551 fail2ban.filterpyinotify[28901]: DEBUG Added monitor for the parent directory /var/log
2020-02-25 22:36:44,551 fail2ban.filterpyinotify[28901]: DEBUG New <Watch wd=2 path=/var/log/auth.log mask=2 proc_fun=None auto_add=False exclude_filter=<function WatchManager.<lambda> at 0x754a8e40> dir=False >
2020-02-25 22:36:44,552 fail2ban.filterpyinotify[28901]: DEBUG Added file watcher for /var/log/auth.log
2020-02-25 22:36:44,552 fail2ban.filter [28901]: DEBUG Seek to find time 1582666004.5494933 (2020-02-25 22:26:44), file size 111470
2020-02-25 22:36:44,566 fail2ban.filter [28901]: DEBUG Position 111389 from 111470, found time 1582666603.0 (2020-02-25 22:36:43) within 1 seeks
2020-02-25 22:36:44,568 fail2ban.filter [28901]: INFO encoding: UTF-8
2020-02-25 22:36:44,569 fail2ban.filter [28901]: INFO maxRetry: 5
2020-02-25 22:36:44,570 fail2ban.filter [28901]: INFO findtime: 1800
2020-02-25 22:36:44,571 fail2ban.actions [28901]: INFO banTime: 1800
2020-02-25 22:36:44,572 fail2ban.filter [28901]: DEBUG Setting usedns = warn for FilterPyinotify(Jail('sshd'))
2020-02-25 22:36:44,574 fail2ban.filter [28901]: DEBUG Add '10.0.0.0/8' to ignore list ('10.0.0.21/8')
2020-02-25 22:36:44,575 fail2ban.filter [28901]: DEBUG Add '127.0.0.0/8' to ignore list ('127.0.0.1/8')
2020-02-25 22:36:44,576 fail2ban.filter [28901]: DEBUG Add '::1' to ignore list ('::1')
2020-02-25 22:36:44,577 fail2ban.CommandAction [28901]: DEBUG Created <class 'fail2ban.server.action.CommandAction'>
2020-02-25 22:36:44,578 fail2ban.CommandAction [28901]: DEBUG Set actionstart = '<iptables> -N f2b-sshd\n<iptables> -A f2b-sshd -j RETURN\n<iptables> -I INPUT -p tcp -m multiport --dports ssh -j f2b-sshd'
2020-02-25 22:36:44,579 fail2ban.CommandAction [28901]: DEBUG Set actionstop = '<iptables> -D INPUT -p tcp -m multiport --dports ssh -j f2b-sshd\n<iptables> -F f2b-sshd\n<iptables> -X f2b-sshd'
2020-02-25 22:36:44,579 fail2ban.CommandAction [28901]: DEBUG Set actionflush = '<iptables> -F f2b-sshd'
2020-02-25 22:36:44,579 fail2ban.CommandAction [28901]: DEBUG Set actioncheck = "<iptables> -n -L INPUT | grep -q 'f2b-sshd[ \\t]'"
2020-02-25 22:36:44,580 fail2ban.CommandAction [28901]: DEBUG Set actionban = '<iptables> -I f2b-sshd 1 -s <ip> -j <blocktype>'
2020-02-25 22:36:44,580 fail2ban.CommandAction [28901]: DEBUG Set actionunban = '<iptables> -D f2b-sshd -s <ip> -j <blocktype>'
2020-02-25 22:36:44,580 fail2ban.CommandAction [28901]: DEBUG Set name = 'sshd'
2020-02-25 22:36:44,581 fail2ban.CommandAction [28901]: DEBUG Set bantime = '1800'
2020-02-25 22:36:44,581 fail2ban.CommandAction [28901]: DEBUG Set port = 'ssh'
2020-02-25 22:36:44,581 fail2ban.CommandAction [28901]: DEBUG Set protocol = 'tcp'
2020-02-25 22:36:44,581 fail2ban.CommandAction [28901]: DEBUG Set chain = '<known/chain>'
2020-02-25 22:36:44,581 fail2ban.CommandAction [28901]: DEBUG Set actname = 'iptables-multiport'
2020-02-25 22:36:44,582 fail2ban.CommandAction [28901]: DEBUG Set blocktype = 'REJECT --reject-with icmp-port-unreachable'
2020-02-25 22:36:44,582 fail2ban.CommandAction [28901]: DEBUG Set returntype = 'RETURN'
2020-02-25 22:36:44,582 fail2ban.CommandAction [28901]: DEBUG Set lockingopt = '-w'
2020-02-25 22:36:44,582 fail2ban.CommandAction [28901]: DEBUG Set iptables = 'iptables <lockingopt>'
2020-02-25 22:36:44,583 fail2ban.CommandAction [28901]: DEBUG Set blocktype?family=inet6 = 'REJECT --reject-with icmp6-port-unreachable'
2020-02-25 22:36:44,583 fail2ban.CommandAction [28901]: DEBUG Set iptables?family=inet6 = 'ip6tables <lockingopt>'
2020-02-25 22:36:44,584 fail2ban.jail [28901]: DEBUG Starting jail 'sshd'
2020-02-25 22:36:44,585 fail2ban.filterpyinotify[28901]: DEBUG [sshd] filter started (pyinotifier)
2020-02-25 22:36:44,587 fail2ban.jail [28901]: INFO Jail 'sshd' started
我尝试从 pyinotify 切换到 gamin 和轮询模式,但无济于事。我尝试创建单独的配置文件,并添加对 filter.d 文件的明确引用,但似乎没有任何帮助。
正则表达式匹配器确实报告找到了匹配项:
$ fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
Running tests
=============
Use failregex filter file : sshd, basedir: /etc/fail2ban
Use maxlines : 1
Use datepattern : Default Detectors
Use log file : /var/log/auth.log
Use encoding : UTF-8
Results
=======
Failregex: 19 total
|- #) [# of hits] regular expression
| 6) [1] ^[iI](?:llegal|nvalid) user <F-USER>.*?</F-USER> from <HOST>(?: port \d+)?(?: on \S+(?: port \d+)?)?\s*$
| 20) [18] ^<F-MLFFORGET><F-NOFAIL>Accepted publickey</F-NOFAIL></F-MLFFORGET> for \S+ from <HOST>(?:\s|$)
`-
Ignoreregex: 0 total
Date template hits:
|- [# of hits] date format
| [1143] {^LN-BEG}(?:DAY )?MON Day %k:Minute:Second(?:\.Microseconds)?(?: ExYear)?
`-
Lines: 1143 lines, 0 ignored, 19 matched, 1124 missed
[processed in 0.81 sec]
Missed line(s): too many to print. Use --print-all-missed to print all 1124 lines
根据文档,我认为 fail2ban 的默认安装至少应该创建 iptables 链,但它没有这样做。我在这里遗漏了什么?
答案1
答案有两个方面。首先,fail2ban 的工作方式发生了变化。较新版本的 fail2ban 不会立即在防火墙配置中创建链,而只会在第一次触发时创建。这解释了为什么新安装的 fail2ban 不会在 iptables -L 中显示链。
为了测试 iptables 链的创建,我们可以使用来fail2ban-client
添加禁令(-vvv 增加详细程度,这可能有助于您调试命令中的问题):
$ sudo fail2ban-client -vvv set sshd banip 192.0.2.0
运行此命令后,iptables 会显示(应该显示)此监狱的链:
$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
f2b-sshd tcp -- anywhere anywhere multiport dports ssh
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain f2b-sshd (1 references)
target prot opt source destination
REJECT all -- 192.0.2.0 anywhere reject-with icmp-port-unreachable
RETURN all -- anywhere anywhere
我们可以按如下方式解除 IP 禁令:
$ sudo fail2ban-client -vvv set sshd unbanip 192.0.2.0
现在 iptables 中的规则已被删除,但 f2b-sshd 链仍然存在:
$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
f2b-sshd tcp -- anywhere anywhere multiport dports ssh
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain f2b-sshd (1 references)
target prot opt source destination
RETURN all -- anywhere anywhere
简而言之,要测试您的 fail2ban 安装,您必须:
- 仅使用 sshd 配置(默认)安装 fail2ban
- 用于
sudo fail2ban-client status sshd
检查状态 - 用于
fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
检查正则表达式匹配。 - 用于
sudo fail2ban-client -vvv set sshd banip 192.0.2.0
生成 sshd 禁令 - 用于
sudo iptables -L
验证 f2b-sshd 链是否已创建并且其中包含禁止规则。 - 用于
sudo fail2ban-client -vvv set sshd unbanip 192.0.2.0
解除禁令。
我还注意到有一个选项可以恢复“按需链创建”行为,请检查有关详细信息,请参阅此 github 问题
我希望这有帮助。