云服务器安全组与 ufw/iptables 配置顺序踩坑与排查 核心要点图解,安全组先于主机防火墙生效,主机防火墙先于 Docker 规则,顺序错位是端口不通的主因。;ufw 只是 iptables 前端,两者混用会互相覆盖,排查应先看 iptables-save 真实规则。;Docker 发布端口会绕过 ufw,放行必须在 DOCKER-USER 链或安全组完成。;规则持久化缺失会导致重启后失效,改完必须验证并保存。
云服务器安全组与 ufw/iptables 配置顺序踩坑与排查 · 核心要点一图读懂(AegisX)

核心要点(TL;DR)

  • 安全组先于主机防火墙生效,主机防火墙先于 Docker 规则,顺序错位是端口不通的主因。
  • ufw 只是 iptables 前端,两者混用会互相覆盖,排查应先看 iptables-save 真实规则。
  • Docker 发布端口会绕过 ufw,放行必须在 DOCKER-USER 链或安全组完成。
  • 规则持久化缺失会导致重启后失效,改完必须验证并保存。

不少运维在云服务器上放行端口时都遇到过这种场景:安全组明明加了 80 端口,ufw allow 80 也执行了,浏览器却依旧超时。反复重启服务、重装系统都无效,最后发现是安全组、ufw、iptables 与 Docker 规则的生效顺序被搞混了。本文按「四层链路」拆解配置顺序,给出可直接复制的排查命令与修复步骤,帮你一次定位问题。

一、先搞清四层链路:谁先谁后

数据包进入云服务器,会依次经过以下关卡,任何一层拦截都会表现为「端口不通」:

层级生效位置典型工具优先级
云安全组云平台虚拟网络层控制台/OpenAPI最先,包未到主机即被丢
主机防火墙内核 netfilter INPUT 链ufw / iptables其次
Docker 规则nat 表与 FORWARD 链docker-proxy / DOCKER-USER发布端口时绕过 INPUT
服务监听应用进程nginx / sshd最后,监听地址决定可达性

关键结论:安全组先于主机防火墙生效,主机防火墙先于 Docker 规则。顺序错位时,你在错误的一层反复放行,自然无效。

二、常见踩坑:规则顺序错位的四种表现

  • ufw 与 iptables 混用:手工 iptables -A 的规则在 ufw reload 后被清空,放行「自动消失」。
  • DROP 规则前置:默认策略为 DROP 时,后追加的 ACCEPT 永远不会命中,必须用 -I 插到链首。
  • Docker 绕过 ufw:容器发布端口走 FORWARD 链,ufw 的 INPUT 规则形同虚设,安全边界被悄悄打开。
  • 规则未持久化:只改了运行时规则,重启后回滚,表现为「昨天还好好的」。

三、分步排查:四条命令逐层收敛

第 1 步:确认服务监听地址

ss -lntp | grep -E ':80|:443'

若显示 127.0.0.1:80,说明服务只监听本地,外部必然不通,问题不在防火墙。

第 2 步:查看主机防火墙真实规则

ufw status verbose
iptables-save -t filter | head -50

注意默认策略与规则顺序,DROP 在前时后续 ACCEPT 无效。

第 3 步:确认包是否到达主机

tcpdump -i eth0 -nn port 80 -c 20

完全无 SYN 到达,说明被安全组或云网络拦截;有 SYN 无 SYN-ACK,说明主机防火墙或服务未响应。

第 4 步:检查 Docker 链

iptables -L DOCKER-USER -n -v
iptables -t nat -L DOCKER -n -v

观察命中计数是否增长,确认容器端口是否被 DOCKER-USER 拦截。

四、分步修复:按正确顺序重配

  1. 先定安全组:在云控制台只放行必要端口,来源限定业务 IP 段,避免 0.0.0.0/0 全开。
  2. 再配主机防火墙:二选一。用 ufw 时执行 ufw default deny incoming 后 ufw allow 22/tcp、ufw allow 80,443/tcp;用 iptables 时用 -I INPUT 插入放行规则,避免追加到 DROP 之后。
  3. 处理 Docker:在 DOCKER-USER 链放行,例如 iptables -I DOCKER-USER -p tcp --dport 8080 -s 10.0.0.0/8 -j ACCEPT,并在链尾显式 DROP 非预期流量。
  4. 持久化:Debian/Ubuntu 执行 netfilter-persistent save;CentOS 执行 iptables-save > /etc/sysconfig/iptables,随后重启验证。
防护建议:安全组与主机防火墙应保持「最小放行 + 来源收敛」的一致策略。若使用 AegisX,可将云安全组规则与主机防火墙基线纳入统一核查,减少两侧策略漂移带来的顺序踩坑。

五、上线检查清单

  • 安全组仅放行必要端口,来源非 0.0.0.0/0。
  • ufw 与 iptables 不混用,默认策略为 DROP 时放行规则置于链首。
  • Docker 端口在 DOCKER-USER 链或安全组层面限制。
  • 规则已持久化,重启后 iptables-save 输出一致。
  • 用 tcpdump 与 iptables -L -n -v 计数双重验证。

行动建议:把「安全组→主机防火墙→Docker 链→服务监听」固化为变更后的固定排查顺序,每次改规则后立即执行清单验证并保存,能避免绝大多数「放行了却不生效」的反复踩坑。

常见问题(FAQ)

安全组已经放行 80 端口,为什么网站还是打不开?

结论:问题多半在主机防火墙或服务监听,而非安全组。先在本机执行 ss -lntp | grep 80 确认服务确实监听在 0.0.0.0 而非 127.0.0.1;再执行 ufw status verbose 与 iptables-save -t filter 查看是否有 DROP 规则;若使用 Docker,检查 DOCKER-USER 链是否拦截。逐层排除后即可定位。

ufw 和 iptables 可以同时用吗?会不会冲突?

结论:可以共存但极易互相覆盖,不建议混用。ufw 本质是 iptables 的前端,它通过自己的链管理规则,你手工添加的 iptables 规则在 ufw reload 或重启后可能被清空。建议二选一:Ubuntu 系用 ufw 管理常规端口,复杂需求直接写 iptables 并配合 iptables-persistent 保存,避免两套规则交叉。

Docker 容器端口放行了 ufw 还是不通,怎么处理?

结论:Docker 发布端口时会插入自己的 NAT 与 FORWARD 规则,绕过 ufw 的 INPUT 链。正确做法是在 DOCKER-USER 链中加放行或限制规则,例如 iptables -I DOCKER-USER -p tcp --dport 8080 -j ACCEPT,也可在云安全组层面直接限制来源 IP。修改后用 iptables -L DOCKER-USER -n -v 核对命中计数。

iptables 规则重启后就没了,如何持久化?

结论:需要显式保存并配置开机恢复。Debian/Ubuntu 安装 iptables-persistent 后执行 netfilter-persistent save;CentOS 用 service iptables save 或 iptables-save > /etc/sysconfig/iptables。保存后重启验证 iptables-save 输出是否一致,避免只改了运行时规则。

如何快速判断是安全组还是主机防火墙拦截?

结论:用对端抓包与云监控对比即可分离。在服务器执行 tcpdump -i eth0 port 80 观察是否有 SYN 到达:完全无包说明被安全组或云网络拦截;有 SYN 无 SYN-ACK 说明主机防火墙或服务未响应。再结合 iptables -L -n -v 的计数增长确认具体链路。