nginx-http-auth
我已经在 Amazon Linux 2 上设置了 Fail2Ban,并使用以下覆盖配置启用了内置监狱:
[nginx-http-auth]
enabled = true
action = iptables[name=HTTPS, port=https, protocol=tcp]
logpath = <snip>/logs/*error*.log
findtime = 15m
bantime = 15m
maxretry = 5
该操作正在触发,我收到以下条目iptables -S
:
-A f2b-HTTPS -s 120.<snip>.122/32 -j REJECT --reject-with icmp-port-unreachable
但是,我可以继续从被禁止的 IP 发出新的 HTTPS 请求,这些请求会收到来自 Nginx 的 401 响应。我已从两个 IP 地址复制 - 我的手机和另一个 EC2 主机。
以下是完整输出iptables -L
:(注意:Nginx 在 Docker 内部运行,另外两个与本地网络隔离的容器也在运行)
Chain INPUT (policy ACCEPT)
target prot opt source destination
f2b-HTTPS tcp -- anywhere anywhere tcp dpt:https
Chain FORWARD (policy DROP)
target prot opt source destination
DOCKER-USER all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-1 all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain DOCKER (2 references)
target prot opt source destination
ACCEPT tcp -- anywhere ip-192-168-208-2.ap-southeast-2.compute.internal tcp dpt:webcache
Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target prot opt source destination
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
DROP all -- !ip-192-168-192-0.ap-southeast-2.compute.internal/20 anywhere
DROP all -- anywhere !ip-192-168-192-0.ap-southeast-2.compute.internal/20
DROP all -- !ip-192-168-176-0.ap-southeast-2.compute.internal/20 anywhere
DROP all -- anywhere !ip-192-168-176-0.ap-southeast-2.compute.internal/20
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
RETURN all -- anywhere anywhere
Chain DOCKER-ISOLATION-STAGE-2 (2 references)
target prot opt source destination
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
RETURN all -- anywhere anywhere
Chain DOCKER-USER (1 references)
target prot opt source destination
RETURN all -- anywhere anywhere
Chain f2b-HTTPS (1 references)
target prot opt source destination
REJECT all -- 120.<snip>.122 anywhere reject-with icmp-port-unreachable
RETURN all -- anywhere anywhere
为什么 iptable 规则没有阻止 HTTPS 请求?
我是否需要以某种方式更改我的 fail2ban 配置才能使其正常工作?
答案1
作为@tater 在上面的评论中指出,fail2ban 默认将自身插入到 INPUT 链中,但到 Docker 容器的流量使用 FORWARD 链进行路由,该链的路由不会触及 INPUT 链。您可以在此处看到:
$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
f2b-HTTPS tcp -- anywhere anywhere tcp dpt:https
...
我们可以测试通过在 FORWARD 链中插入类似的 fail2ban 规则来使 fail2ban 与 Docker 协同工作,如下所示(注意:这是不是长期解决方案):
$ sudo iptables -I FORWARD 1 -p tcp -j f2b-HTTPS
用英语来说,这个命令的意思是“在 FORWARD 链中,在位置 1(即第一条规则),对于 TCP 协议上的所有流量,插入对该f2b-HTTPS
链的引用”,其效果是包括该位置上该链的所有规则。
完成后,FORWARD 链应该在顶部包含新规则:
$ sudo iptables -L
...
Chain FORWARD (policy DROP)
target prot opt source destination
f2b-HTTPS tcp -- anywhere anywhere
DOCKER-USER all -- anywhere anywhere
...
然后使用 fail2ban 在 f2b-HTTPS 链下自动管理的规则来拒绝发往 Docker 的流量。
但是,我们希望 fail2ban 自动为我们执行此操作,而不是必须创建我们自己的 iptables 规则。解决方案是在以下文件中的 jail 配置中添加第二个操作jail.d/
:
action = iptables[actname=iptables-input, name=HTTPS, port=https, protocol=tcp]
iptables[actname=iptables-forward, name=HTTPS-DOCKER, chain=FORWARD, port=8080, protocol=tcp]
可能只需添加chain=FORWARD
到我原来的规则就足够了,但我决定同时保留 INPUT 规则。
笔记:规则中的端口iptables-forward
是 8080,因为这是我的 Docker 容器正在监听的位置,并且它是 iptables 在 FORWARD 规则上匹配的目标转发端口(似乎),而不是入站端口。
我在解决这个问题时还发现了另外两件事:
- 安装时,fail2ban 默认不启用。要启用它,请运行:
sudo systemctl enable fail2ban
- 如果你的系统在禁令生效期间重新启动,fail2ban 会将其规则插入到 FORWARD 链的顶部前Docker 将其规则插入 FORWARD 链的顶部。这意味着 Docker 规则将覆盖 fail2ban 规则,并且禁令将不起作用。(您可以通过执行 来模拟此操作
sudo service docker restart
。)为了克服这个问题,您需要在 Docker 建立其网络后启动 fail2ban。我通过更改“/etc/lib/systemd/system/fail2ban.service”来实现这一点:
- 将“docker.service”添加到“After:”列表中
- 删除 PartOf=firewalld.service 行
[Service]
在等待端口 443 打开的部分中添加以下内容:ExecStartPre=/bin/bash -c '(while ! nc -z -v -w1 localhost 443 > /dev/null; do echo "Waiting for port 443 to open..."; sleep 2; done); sleep 2'
- (注意:您还需要
nc
安装)