现场是这样的。CentOS 7.9 上跑 Docker,为了限制某个 IP 访问容器,把规则加到了 INPUT 链,规则计数一直是零,容器端口照样被访问,宿主机自己的服务倒是被挡住了。

中间走过弯路,把「docker 在启动时会把 FORWARD 的默认策略改成 ACCEPT,自己加的 DROP 被绕过」当成主因,改完现象没变。

原因不止一个,得分开看。容器的入站流量经过 PREROUTING 与 FORWARD,不经过宿主机 INPUT 链;DOCKER-USER 链才是官方留给自定义规则的位置,写在 INPUT 里等于写错了层;规则没加 -m conntrack,只匹配了新连接,回包仍然被放行。

第一件事是看规则命中的计数是不是零

iptables -vnL INPUT --line-numbers | head -20

随后确认容器流量实际走哪条链

iptables -t filter -vnL FORWARD | head -20

接着把限制规则写进 DOCKER-USER

iptables -I DOCKER-USER -s 203.0.113.9 -p tcp --dport 8080 -j DROP

末了在新连接上复测并看计数

iptables -vnL DOCKER-USER | grep 8080

怎么算真的好了,看的是同一批现象。DOCKER-USER 里该规则的包计数持续增长,被限制的 IP 访问返回超时,其他来源访问仍然正常。

容易忽略的是,DOCKER-USER 的规则要在 docker 启动之后存在,重启会重建链,持久化要用 iptables-save 或者 firewalld 的直通规则。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。

作者 9823189