我使用“经典”配置设置了一个由 Docker 引擎在 Swarm 模式下运行的 Traefik 实例(见下文,为简洁起见,我只放置了相关的 [to me] 部分。如果需要,请随时询问更多详细信息)。
已安装 Fail2Ban 以及 firewalld(CentOS 发行版)。到目前为止,我通过观察 Traefik 访问日志进行了简单的过滤器/监狱配置,主要用于阻止 DOS 和暴力破解。
我的问题:当我尝试使用Nikto或Hydra时,我可以看到我尝试使用的 IP 已被列入黑名单:
# fail2ban-client status symfony-auth
Status for the jail: symfony-auth
|- Filter
| |- Currently failed: 3
| |- Total failed: 906
| `- File list: /var/log/traefik/access.log
`- Actions
|- Currently banned: 1
|- Total banned: 2
`- Banned IP list: 37.19.218.169
但是 iptables 规则部分没有任何变化,我可以看到给定的 IP 没有被阻止。此外,如果我尝试从被禁止的 IP 在网站上导航,即使它被禁止,我也可以做到。
我必须补充一点,我00-firewalld.conf file
有关于此发行版操作的默认说明:
# cat /etc/fail2ban/jail.d/00-firewalld.conf
# This file is part of the fail2ban-firewalld package to configure the use of
# the firewalld actions as the default actions. You can remove this package
# (along with the empty fail2ban meta-package) if you do not use firewalld
[DEFAULT]
banaction = firewallcmd-rich-rules[actiontype=<multiport>]
banaction_allports = firewallcmd-rich-rules[actiontype=<allports>]
backend=systemd
最后,我没有任何时差,比如这里说的。
# tail /var/log/messages
Jul 12 13:28:05 ....
# timedatectl
Local time: Mon 2021-07-12 13:30:18 UTC
Universal time: Mon 2021-07-12 13:30:18 UTC
RTC time: Mon 2021-07-12 13:30:13
Time zone: UTC (UTC, +0000)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
那为什么我的封禁IP还能访问目标网站呢?感谢您的线索和启示。
片段
特拉菲克docker-compose.yml
记录部分
version: "3.3"
services:
reverse-proxy:
image: "traefik:v2.4"
command:
# Log configuration
#- "--log.level=DEBUG"
- "--log.filepath=/var/log/traefik/traefik.log"
- "--accesslog.filepath=/var/log/traefik/access.log"
卷部分:
# ...
volumes:
# To persist certificates
- traefik-certificates:/letsencrypt
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- /var/log/traefik:/var/log/traefik/
# ...
Fail2Ban
我的过滤器
/etc/fail2ban/filter.d/my_filter.conf
[Definition]
failregex = ^<HOST>.*"(GET|POST|HEAD).*" (404|444|403|400|301) .*$
ignoreregex =
我的监狱
[my_jail]
enabled = true
port = http,https
filter = my_filter
logpath = /var/log/traefik/access.log
maxretry = 10
客户状态
# fail2ban-client status
Status
|- Number of jail: 2
`- Jail list: sshd, my_jail
可能有3个原因:
您的
firewalld
后端(iptables
?)不适合处理此问题,请参阅https://github.com/fail2ban/fail2ban/issues/1609#issuecomment-303085942(或https://github.com/firewalld/firewalld/issues/44#issuecomment -408211978)了解详情。很快,firewalld 的新 nftables 后端可以正确处理这个问题,所以你可能需要切换到这个,或者......这也可能导致我们接下来的两个原因(前者比后者更相关):
如果您的网络子系统有一些白名单规则(我猜是这样),例如 conntrack 规则绕过在 fail2ban 链之前已经建立的连接,然后将规则添加到 fail2ban 表,拒绝 IP,不会影响这个已建立连接(例如在保持活动的情况下),然后只有新连接将被拒绝......在这种情况下,要么确保在身份验证失败后拒绝网络服务器中的连接,要么重新排序链(在白色之前的 fail2ban 链)列出规则),或使用额外命令终止连接
actionban
,例如ss -K dst "[<ip>]"
或conntrack -D -s <ip>
等。请参阅https://github.com/fail2ban/fail2ban/pull/3018/commits/8f6a8df3a45395620e434fd15b4ede694a1d00aa(或https://github.com/fail2ban/失败2禁令/提交/bbfff1828061514e48395a5dbc5c1f9f81625e82) 对于 ufw 的类似问题;因为它是 dockerized,你可能必须定义
chain = DOCKER-USER
或类似的,只是动作firewallcmd-rich-rules
不适合那个(根本没有参数chain
)......使用另一个禁止动作(例如原生网络过滤器,如 iptables/ipset 或 nftables)支持那。无论如何,考虑到 docker 和 firewalld 的所有预定义链/表,您必须检查传入流量(包括已建立的)如何到达 fail2ban 为禁止 IP 创建的结果链/表。
或者,简单地对本地网络过滤器子系统(如 iptables+ipset 或 nftables)使用禁止操作(例如,为 fail2ban 链使用适当的目标表,例如,
DOCKER-USER
而不是INPUT
)。