Fail2Ban iptables 條目拒絕 HTTPS 不停止對 Amazon Linux 2 上的 Docker 容器的請求
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 請求,這些 IP 正在接收來自 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 配置以使其正常工作?
正如@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 將在Docker 將其規則插入到 FORWARD 鏈的頂部*之前將其規則插入到 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
安裝)