### [Docker端口绕过UFW怎么办?在VPS上按发布规则、DOCKER-USER链和外部验收排查](https://www.jiyueip.com/article/13360) **Published:** 2026-07-30T04:44:01 **Author:** 斑斓助理 **Excerpt:** VPS启用UFW后,Docker发布的端口仍可能从公网访问。原因通常不在UFW命令本身,而在Docker创建的转发规则、默认FORWARD策略和网卡路径。本文给出只读确认、DOCKER-USER限制、IPv4/IPv6差异与外部验收步骤。 在 Linux VPS 上执行 `ufw deny 8080/tcp`,并不一定能阻止 Docker 通过 `-p 8080:80` 发布的端口。Docker 会为端口映射创建转发和地址转换规则,数据包可能在到达 UFW 预期链路前就被转发到容器。这个现象不是所有发行版和网络模式都相同,排查时应以实际规则和外部连接结果为准。 ## 先确认:端口是谁发布、从哪条路径进来 先不要改规则,记录容器、监听端口和 UFW 当前状态: ``` docker ps --format 'table {{.Names}} / {{.Ports}}' sudo ss -lntup sudo ufw status verbose ip -br addr ip route ``` 看到 `0.0.0.0:8080->80/tcp`,表示容器端口绑定在所有 IPv4 地址;如果是 `127.0.0.1:8080`,公网通常无法直接访问。IPv6 要单独看是否存在 `[::]:8080` 监听和安全组放行。 ## 从宿主机检查 Docker 与防火墙规则 Docker 使用 iptables 还是 nftables 兼容层,取决于系统和 Docker 配置。分别查看过滤、转发和 NAT 规则,不要只看 `ufw status`: ``` sudo iptables -S sudo iptables -t nat -S sudo iptables -S DOCKER-USER sudo iptables -S FORWARD sudo nft list ruleset ``` 重点看 `DOCKER-USER`、`FORWARD`、`DOCKER` 和 `DOCKER-ISOLATION` 链。Docker 文档建议把面向容器的额外过滤放在 `DOCKER-USER`,因为该链位于 Docker 自己的转发规则之前;但接口名称、反向代理、IPv6 和云平台安全组仍可能改变最终路径。 ## 先用绑定地址缩小暴露面 如果服务只供本机反代或运维访问,最稳妥的做法是不要绑定到公网: ``` docker run -d --name demo -p 127.0.0.1:8080:80 nginx:alpine ``` Compose 中写成 `127.0.0.1:8080:80` 同样的含义。修改前先确认没有其他服务占用端口,并用 `docker compose config` 展开最终配置。只改 UFW 规则而继续把端口绑定到 `0.0.0.0`,会让后续维护依赖多层规则,容易遗漏 IPv6 或新网卡。 ## 必须公网提供时,在 DOCKER-USER 做来源限制 若端口确实要公网访问,应先明确允许的来源网段,再在 `DOCKER-USER` 链中限制。下面示例只允许一个办公网段访问宿主机的 8080 端口;执行前请替换为实际网段,并确认已有远程管理白名单: ``` sudo iptables -I DOCKER-USER 1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT sudo iptables -I DOCKER-USER 2 -p tcp -s 203.0.113.0/24 -m conntrack --ctorigdstport 8080 -j ACCEPT sudo iptables -I DOCKER-USER 3 -p tcp -m conntrack --ctorigdstport 8080 -j DROP sudo iptables -S DOCKER-USER ``` 流量进入 `DOCKER-USER` 时通常已经完成 DNAT,直接写 `--dport 8080` 可能匹配到的是容器端口而不是宿主机原始端口。上例用 conntrack 的 `--ctorigdstport` 匹配最初访问的 8080;也要结合 `iptables -t nat -S DOCKER` 核对实际转换。对多端口、反向代理和跨网卡转发,可在确认公网网卡名称后增加入站接口条件,并先在控制台保留回滚入口。`203.0.113.0/24` 是文档示例网段,不是可直接使用的办公地址;conntrack 原始目标匹配还会增加规则处理开销,应只用于必要流量。 如果系统以 nftables 为主,应使用对应的 nft 规则或确认 iptables-nft 兼容层实际生效;不要同时维护两套互不相同的规则并把其中一套当成最终策略。 ## 别漏掉云安全组和 IPv6 VPS 的云安全组在宿主机之外,UFW 和 Docker 规则无法替代它。公网验收应分别从 IPv4 和 IPv6 网络测试: ``` nc -vz -w 3 SERVER_IPV4 8080 curl -4 -I --max-time 5 http://SERVER_IPV4:8080/ curl -6 -I --max-time 5 http://[SERVER_IPV6]:8080/ ``` 从另一条网络执行测试更有意义;在服务器本机访问 `127.0.0.1` 只能证明本地路径。若 IPv4 被拒绝而 IPv6 可访问,检查 `ufw status`、`ip6tables`、云安全组 IPv6 规则和容器是否发布了 IPv6。 ## 规则变更后的验收与回滚 - 用 `docker ps`、`ss -lntup` 确认映射和监听地址符合设计。 - 从允许和不允许的来源各测试一次,记录连接结果和时间。 - 查看计数器:`sudo iptables -vnL DOCKER-USER`,确认流量确实命中预期规则。 - 检查重启 Docker 或服务器后规则是否由声明式配置恢复,避免只在当前运行时有效。 - 保留原规则导出和控制台救援方式,远程操作不要在未验证 SSH 白名单时清空防火墙。 如果表现为“服务已启动但公网端口不通”,还要沿监听地址、系统防火墙、安全组、公网地址和路由逐层检查,可参考[VPS端口不通的分层排查方法](https://www.jiyueip.com/article/13241)。如果问题只发生在重启之后,再检查 Docker 重启策略和依赖顺序,而不是反复开放端口。 ## 常见问题 **UFW 显示 deny,为什么 Docker 端口仍能访问?** Docker 的转发和 NAT 规则可能改变数据包经过的链路。需要同时检查 DOCKER-USER、FORWARD、NAT、云安全组以及外部测试结果。 **把 Docker 的 iptables 选项关闭就能解决吗?** 不建议直接关闭。可能导致端口映射、出站访问或容器网络失效;应先理解现有网络设计,再用绑定地址或 DOCKER-USER 过滤实现最小暴露。 **只绑定 127.0.0.1 后,反向代理还能访问吗?** 如果反向代理运行在宿主机上,可以通过 127.0.0.1 访问;若反向代理在另一个容器中,应改用同一 Docker 网络和服务名,而不是假设容器内的 127.0.0.1 指向宿主机。 **iptables 规则重启后消失怎么办?** 将策略写入发行版支持的持久化机制或基础设施配置,并在重启 Docker、重启 VPS 后重新做 IPv4/IPv6 外部验收。 **Tags:** Docker部署, Linux服务器, VPS, VPS监控, 云服务器 **Categories:** 行业洞察 ---