Skip to main content

Docker 容器要出网/容器互访 FORWARD(转发)UFW详细配置

先说结论:这些规则本身没语法错误,但它们几乎都作用在 INPUT(进宿主机) 链上,而 Docker 容器要出网/容器互访走的是 FORWARD(转发) 链。UFW 默认 FORWARD 策略是 DROP,所以容器流量被丢了——这正是"容器内网络不通"的根因。

为什么容器不通

  • Anywhere ALLOW 172.18.0.0/16 是 INPUT 规则,不是 FORWARD 规则
    这条等价于 ufw allow from 172.18.0.0/16,只允许"容器网段 → 宿主机"的入站包。它不会放行"容器 → 外网""容器 → 容器"的转发流量,所以你以为开了 docker 网段,其实没开到点上。
  • UFW 默认转发策略为 DROP/etc/default/ufwDEFAULT_FORWARD_POLICY="DROP")。容器发包要经宿主机 FORWARD 链转发出去,没有 ACCEPT 规则命中就被丢。
  • 网段可能写错/写窄:你只放了 172.18.0.0/16。Docker 默认网桥是 172.17.0.0/16,compose 网络常是 172.18/19/20… 不一。容器若落在 172.17 或别的子网,这条也匹配不上。Docker 私有段整体是 172.16.0.0/12
  • IPv6 只有 DENY 没有放行:底部 8067,20828 (v6) DENY22 (v6) DENY,但没有任何 v6 的 docker 放行;若容器走 IPv6 同样不通。

其它规则层面的问题

  • Anywhere ALLOW 172.18.0.0/16 过宽:对该网段放开了所有端口访问宿主机,安全面偏大,建议按需收敛到具体端口。
  • 底部 22/tcp DENY Anywhere8067,20828/tcp DENY Anywhere 是冗余:UFW 默认 incoming 就是 deny,这两条不改变行为(无害,但可清理)。
  • .51–.57 那一大段重复端口组:只是啰嗦,功能没问题,可用地址段或 ufw allow from 192.168.6.48/29 to any port 8067,20828 之类合并。

修复(三选一,推荐 A)

A. 只给 Docker 转发放行(最小改动、安全)
编辑 /etc/ufw/after.rules,在 COMMIT 之前加入:

-A ufw-forward -s 172.16.0.0/12 -d 172.16.0.0/12 -j ACCEPT
-A ufw-forward -s 172.16.0.0/12 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A ufw-forward -d 172.16.0.0/12 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

然后:

sudo ufw reload
sudo systemctl restart docker

(更规范的做法是用 Docker 的 DOCKER-USER 链,但 UFW 激活时经 after.rulesufw-forward 更稳,不会被 docker 重启冲掉。)

B. 直接放开转发策略(最省事,安全性略降)
/etc/default/ufwDEFAULT_FORWARD_POLICY="ACCEPT",再:

sudo ufw disable && sudo ufw enable
sudo systemctl restart docker

C. 用 ufw 的 route(FORWARD)规则

sudo ufw route allow in on docker0 out on <你的外网网卡>
sudo ufw route allow in on <外网网卡> out on docker0

<外网网卡>ip route 里 default 那条的 dev 替换。)

改完先自查

grep FORWARD /etc/default/ufw
sudo iptables -L FORWARD -n -v --line-numbers | head
ip -br addr | grep -E 'docker|br-'      # 确认真实容器网段
docker network inspect <net> -f '{{range .IPAM.Config}}{{.Subnet}}{{end}}'

确认 FORWARD 里 docker 流量能命中 ACCEPT,再进容器 ping -c3 1.1.1.1 / wget -qO- https://www.baidu.com 验证。

需要的话,把 docker network inspect 的实际网段和 iptables -L FORWARD 贴给我,我帮你把放行规则精确到真实子网,避免整段 172.16/12 太宽。