Fail2ban 监控登录失败的日志文件,并暂时禁止容易失败的源 IP 地址访问主机。这是一种防御密码猜测暴力攻击的方法。在暴露于互联网的主机上安装 fail2ban 非常有用。
Debian 12 上的 fail2ban 版本是 1.0.2。
root@posti:~# fail2ban-client version
1.0.2
要查看 fail2ban 是否正在运行,请使用 fail2ban-client 向服务器发送 ping 命令。如果正在运行,fail2ban 服务器会回答 "pong"。
root@posti:/etc/fail2ban# fail2ban-client ping
Server replied: pong
root@posti:/etc/fail2ban#
Fail2ban 会将过滤器、操作和监控文件收集到一个 jail 中。发行版中附带了多个监狱。过滤器指定如何检测身份验证失败,动作定义如何禁止和解除禁止。
如果在查找时间内检测到来自同一 IP 号的登录失败次数至少达到 maxretry,入侵尝试就会触发封禁。然后该 IP 将被禁用 bantime 秒。禁令生效 bantime 秒后,禁令解除,IP 可以再次访问主机。Fail2ban 可以处理 IPv4 和 IPv6。
更多信息可查阅 /usr/share/doc/fail2ban/ 目录下的文件。
Debian GNU/Linux 系统默认安装 Fail2ban,并通过合理设置启用 sshd jail。这在文件 /etc/fail2ban/jail.d/defaults-debian.conf 中完成。这是默认情况下唯一可用的监狱。其他监狱必须由系统管理员启用。
因此,如果您只想监控 ssh 登录并禁止行为不端的入侵者,则无需额外配置。
遗憾的是,在 Debian 12 上,默认设置下的 fail2ban 可能无法工作。Debian 12 将 rsyslog 软件包标记为可选项,这意味着它可能未被安装,因此日志只能被收集到 journald [wiki.debian.org/Rsyslog]。
在 ISPConfig 系统上,由于 ISPConfig 自动安装程序安装了 rsyslog,而且 ISPConfig 完美服务器教程也指示安装 rsyslog,因此 fail2ban 可以工作。
使用 rsyslog,日志文件会出现在 /var/log/ 目录中,因此 fail2ban 默认配置会找到日志文件。如果没有安装 rsyslog,则必须修改 fail2ban 配置,以便从 systemd 日志中读取日志。在 jail.local 的默认部分添加 backend = systemd,如下所示
[DEFAULT] backend = systemd
文档建议将自己的所有修改都放在 .local 文件中。这样可以避免发行版提供的文件被维护者升级或修改时出现问题 [阅读文件 /usr/share/doc/fail2ban/README.Debian.gz]。
例如,在 /etc/fail2ban/jail.local 文件(如果该文件不存在,则创建该文件)中添加以下内容,即可启用 pure-ftpd jail
[pure-ftpd] enabled = true
方括号中的监狱名称为该jail设置的起始部分。
完成修改后,使用命令强制重读配置文件
systemctl reload fail2ban
现在jail应该正在运行,可以用 fail2ban-client 验证:
root@posti:/etc/fail2ban# fail2ban-client status pure-ftpd Status for the jail: pure-ftpd |- Filter | |- Currently failed: 0 | |- Total failed: 106 | `- File list: /var/log/syslog `- Actions |- Currently banned: 0 |- Total banned: 4 `- Banned IP list: root@posti:/etc/fail2ban#
由于 jail.local 只有该jail的 "启用 "设置,所有其他设置都是发行版的默认设置。通常,它们都有很好的值,因此无需进一步配置。如果需要,该 jail 的 jail.local 部分可以包含覆盖 .conf 文件中设置的设置。
本例更改了 pure-ftpd jail 的 findtime、maxretry 和 bantime:
[pure-ftpd] enabled = true findtime = 2h maxretry = 6 bantime = 1d
Fail2ban-client 以秒为单位显示时间,但可以在配置文件中以更简单的格式输入时间,例如 10h 而不是 36000 秒。man jail.conf 在 "TIME ABBREVIATION FORMAT" 一章中解释了用户友好的时间输入格式。
fail2ban-client 有将用户友好时间格式转换为秒格式的选项。
# fail2ban-client --str2sec 1d3h7m
97620
要确定应激活哪些 jails,可查看主机上运行的服务创建的日志。一个能创建日志摘要的工具(如 logwatch 或 pflogsumm)会很有帮助。阅读原始日志既耗时又乏味。
检查主机上运行的服务是否有可用的 jail,也许可以读取 jail.conf。
一旦日志显示了有趣或令人担忧的内容,就该进行检查了。例如,pflogsumm 发送的电子邮件摘要中有这样几行:
136 unknown[91.224.92.40]: SASL LOGIN authentication failed: UGFzc3... 136 hostname srv-91-224-92-40.serveroffer.net does not resolve to a... 123 unknown[193.32.162.23]: SASL LOGIN authentication failed: UGFzc... 123 hostname mail.whatami.co does not resolve to address 193.32.162.23
这显示 IP 91.224.92.40 登录电子邮件失败 136 次,还有另一个类似的情况。Fail2ban 本应阻止这么多次尝试。要了解为什么没有发生这种情况,请检查 fail2ban 日志。
root@posti:/etc/apt/apt.conf.d# grep 91.224.92.40 /var/log/fail2ban.log | head 2024-02-18 00:01:38,718 fail2ban.filter [996]: INFO [postfix-sasl] Found 91.224.92.40 - 2024-02-18 00:01:38 2024-02-18 00:11:50,261 fail2ban.filter [996]: INFO [postfix-sasl] Found 91.224.92.40 - 2024-02-18 00:11:50 2024-02-18 00:21:54,337 fail2ban.filter [996]: INFO [postfix-sasl] Found 91.224.92.40 - 2024-02-18 00:21:54 2024-02-18 00:32:14,232 fail2ban.filter [996]: INFO [postfix-sasl] Found 91.224.92.40 - 2024-02-18 00:32:14 2024-02-18 00:42:37,921 fail2ban.filter [996]: INFO [postfix-sasl] Found 91.224.92.40 - 2024-02-18 00:42:37 2024-02-18 00:53:06,796 fail2ban.filter [996]: INFO [postfix-sasl] Found 91.224.92.40 - 2024-02-18 00:53:06 2024-02-18 01:03:35,293 fail2ban.filter [996]: INFO [postfix-sasl] Found 91.224.92.40 - 2024-02-18 01:03:35 2024-02-18 01:14:03,765 fail2ban.filter [996]: INFO [postfix-sasl] Found 91.224.92.40 - 2024-02-18 01:14:03 2024-02-18 01:24:24,628 fail2ban.filter [996]: INFO [postfix-sasl] Found 91.224.92.40 - 2024-02-18 01:24:24 2024-02-18 01:34:43,876 fail2ban.filter [996]: INFO [postfix-sasl] Found 91.224.92.40 - 2024-02-18 01:34:43 root@posti:/etc/apt/apt.conf.d#
该 IP 每隔 10 分钟尝试连接一次,而 fail2ban jail postfix-sasl 确实检测到了它。
最好的办法是找出该 IP 是否属于主机的合法用户,该用户只是在智能手机或其他设备上设置了旧密码,并定期尝试连接。我使用 geoiplookup,它可以显示 IP 来自哪个国家。我的用户来自我的国家,所以外国用户往往是坏人。geoiplookup 来自 Debian 软件包 geoip-database 和 geoip-bin。
$ geoiplookup 91.224.92.40 GeoIP Country Edition: LT, Lithuania
要找出 IP 未被封禁的原因,请检查该JAIL的查找时间:
root@posti:/etc/apt/apt.conf.d# fail2ban-client get postfix-sasl findtime 600 root@posti:/etc/apt/apt.conf.d#
我最近看到过这种慢速攻击,攻击者知道查找时间是 10 分钟,因此试图通过延长登录时间来避免被禁用。在这种情况下,这种方法奏效了。要使登录失败导致禁言,可增加监狱的查找时间,例如增加到 10 小时。添加到 [postfix-sasl] 部分的 jail.local 文件中:
findtime = 10h
这样,在 systemctl reload fail2ban 之后,JAIL的查找时间就会延长:
root@posti:/etc/fail2ban# fail2ban-client get postfix-sasl findtime 36000 root@posti:/etc/fail2ban#
入侵者的另一种入侵方式是持久性。即使入侵者被禁言,只要等到禁言结束,就可以继续猜密码。禁用时间可以延长,但这会给合法用户带来麻烦,因为他们可能会输错密码,然后在禁用时间结束前无法访问自己的账户。有一种针对惯犯的JAIL叫 recidive。它的工作原理是在 fail2ban 日志中查找重复禁用的 IP,然后长时间禁用,例如一周。
以下列表来自 logwatch 报告:
--------------------- pam_unix Begin ------------------------
sshd:
Authentication Failures:
unknown (212.70.149.150): 59 Time(s)
在日志文件中搜索该 IP 会显示
2024-02-21 03:42:39,121 fail2ban.filter [895]: INFO [sshd] Found 212.70.149.150 - 2024-02-21 03:42:38 2024-02-21 03:42:39,508 fail2ban.actions [895]: NOTICE [sshd] Ban 212.70.149.150 2024-02-21 03:52:38,386 fail2ban.actions [895]: NOTICE [sshd] Unban 212.70.149.150 2024-02-21 03:54:33,560 fail2ban.filter [895]: INFO [sshd] Found 212.70.149.150 - 2024-02-21 03:54:33 2024-02-21 03:54:35,364 fail2ban.filter [895]: INFO [sshd] Found 212.70.149.150 - 2024-02-21 03:54:35 2024-02-21 04:00:37,017 fail2ban.filter [895]: INFO [sshd] Found 212.70.149.150 - 2024-02-21 04:00:36 2024-02-21 04:00:39,021 fail2ban.filter [895]: INFO [sshd] Found 212.70.149.150 - 2024-02-21 04:00:38 2024-02-21 04:06:43,036 fail2ban.filter [895]: INFO [sshd] Found 212.70.149.150 - 2024-02-21 04:06:42 2024-02-21 04:06:45,039 fail2ban.filter [895]: INFO [sshd] Found 212.70.149.150 - 2024-02-21 04:06:44 2024-02-21 04:06:45,426 fail2ban.actions [895]: NOTICE [sshd] Ban 212.70.149.150 2024-02-21 04:16:44,302 fail2ban.actions [895]: NOTICE [sshd] Unban 212.70.149.150 2024-02-21 04:19:04,868 fail2ban.filter [895]: INFO [sshd] Found 212.70.149.150 - 2024-02-21 04:19:04
Fail2ban 如期工作,发现错误登录并发出 10 分钟的禁令。在禁止期间,违规者无法访问该主机,但在禁止解除后仍可继续访问。这似乎是严重企图入侵的情况。补救措施是使用低最大重试次数和长禁用时间的循环监狱。
我喜欢使用较短的初始禁言时间,比如 10 分钟。如果一个真正的用户被禁用了,他只需等待这段时间,希望能利用这段时间找到正确的密码,然后再试一次。当天再次被禁言的用户会被禁言一周。在 jail.conf 文件中可以找到 recidive jail 的默认值,其中 bantime 为 1 周,findtime 为 1 天。但我将 maxretry 设置为 2,罪犯被禁用的速度更快了。我在文件 jail.local 中添加了
[recidive] enabled = true maxretry = 2
在我看来,禁言时间超过 1 周是不值得的。最终,旧的 IP 地址会被到处禁用或列入黑名单,因此违规者会得到一个新的 IP。旧 IP 会给一些无辜的新互联网用户,他们不应该因为该 IP 的前所有者所犯的坏事而受到惩罚。
启动操作系统或重启 fail2ban 后,状态会恢复,因此禁令会继续,直到禁令时间结束。因此,测试和故障排除可能涉及重启。
要测试配置,有一个测试选项:
fail2ban-server --test
要知道某个 IP 是否被禁用,最新版本的 fail2ban 可以做到
# fail2ban-client banned 43.131.9.186
[['recidive']]
该命令会显示给定 IP 当前被禁用的监狱列表。
旧版本的 fail2ban 没有该命令。可以像这样逐一测试每个监狱:
# fail2ban-client status recidive | tr " " "\n" | grep 43.163.219.232
43.163.219.232
如果输出显示了 IP,那么它就在被禁 IP 的列表中。使用 tr 命令可以将被禁 IP 号码列表(一长行)分成每行一个 IP。
要查看某个 IP 的情况,请在 fail2ban.log 中查找:
root@posti:/etc/mysql# grep 43.131.9.186 /var/log/fail2ban.log | cut --characters=-80
2024-03-06 09:00:40,295 fail2ban.filter [3574846]: INFO [sshd] Found 2024-03-06 09:02:53,954 fail2ban.filter [3574846]: INFO [sshd] Found 2024-03-06 09:02:55,958 fail2ban.filter [3574846]: INFO [sshd] Found 2024-03-06 09:04:34,193 fail2ban.filter [3574846]: INFO [sshd] Found 2024-03-06 09:04:36,195 fail2ban.filter [3574846]: INFO [sshd] Found 2024-03-06 09:04:36,388 fail2ban.actions [3574846]: NOTICE [sshd] Ban 43 2024-03-06 09:04:36,626 fail2ban.filter [3574846]: INFO [recidive] Fo 2024-03-06 09:14:35,180 fail2ban.actions [3574846]: NOTICE [sshd] Unban 2024-03-06 09:15:10,073 fail2ban.filter [3574846]: INFO [sshd] Found 2024-03-06 09:16:55,919 fail2ban.filter [3574846]: INFO [sshd] Found 2024-03-06 09:16:58,522 fail2ban.filter [3574846]: INFO [sshd] Found 2024-03-06 09:18:44,972 fail2ban.filter [3574846]: INFO [sshd] Found 2024-03-06 09:20:30,018 fail2ban.filter [3574846]: INFO [sshd] Found 2024-03-06 09:20:30,499 fail2ban.actions [3574846]: NOTICE [sshd] Ban 43 2024-03-06 09:20:30,620 fail2ban.filter [3574846]: INFO [recidive] Fo 2024-03-06 09:20:30,899 fail2ban.actions [3574846]: NOTICE [recidive] Ba 2024-03-06 09:20:32,021 fail2ban.filter [3574846]: INFO [sshd] Found 2024-03-06 09:30:29,289 fail2ban.actions [3574846]: NOTICE [sshd] Unban
fail2ban 配置的详细转储显示了可供检查的设置:
# fail2ban-client -vvv -d
也许您自己的主机会被禁用,或者您想确保某些外国主机即使行为不端也不会被禁用。这些 IP 地址可以列入白名单。默认情况下,白名单中没有任何内容,您可以通过以下方式验证
root@posti:~# fail2ban-client get sshd ignoreip
No IP address/network is ignored
root@posti:~
可以在每个 jails 部分设置 ignoreip,但这一设置会影响所有 jails,因此最好将其设置在 DEFAULT 部分。最好将忽略设置为内部子网,这样所有自己的主机都不会被禁止。这是 jail.local 开头的内容:
[DEFAULT] ignoreip = 92.237.123.96/27
默认部分可以有影响所有 jail 的其他设置。例如,可以在这里添加 findtime = 10h。
要测试禁言时会发生什么,请手动设置禁言。首先使用禁言时间较短的监狱进行测试,这样如果错误禁言,最终也能恢复正常。例如
# fail2ban-client set sshd banip 8.8.4.4</>
如果某个 IP 行为恶劣,但你又无法让 fail2ban 检测到它并发出禁令,那么在 recidive jail 中设置手动禁令可以在一周内清除该 IP。
# fail2ban-client set recidive banip 8.8.4.4
使用 CIDR 符号禁止子网:
fail2ban-client set recidive banip 5.188.87.0/24
取消禁用是可能的,但要考虑到如果不良行为继续,该 IP 将再次被禁用。因此,你应该找出问题所在(例如通过阅读日志),并修复不良行为。
# fail2ban-client set recidive unbanip 8.8.4.4
该 IP 可能在多个监狱中被禁用。要解除一个 IP 在所有监区的封禁,请使用
# fail2ban-client unban 8.8.4.4
不过,我很少需要这样做。我的禁用时间是 10 分钟,但重置监狱的禁用时间是 1 周,所以我只从重置监狱解禁 IP,其他监狱的禁用时间都已过期。如果不使用循环监牢,IP 可能会同时在多个监牢中被禁用,所以这个功能很有用。
要解禁所有 IP 地址,请执行以下操作
fail2ban-client unban --all
Fail2ban 增加了猜测密码的难度,但并不能完全阻止破解者尝试访问主机。对于 SSH,强制使用 SSH 密钥可提供更多保护,防止使用密码登录。对于其他服务,如果只知道密码,多因素身份验证可以防止登录。