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

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

为什么容器不通

其它规则层面的问题

修复(三选一,推荐 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 验证。

不正确,有两处问题,其中第一处是致命的——照现在这样 ufw reload/ufw enable 会直接报错、整段规则都加载不了。

问题1(致命):链名写错了

你加的是 -A ufw-forward ...,但 UFW 根本没有 ufw-forward 这条链。看你自己文件顶部声明的三条链就知道:

:ufw-after-input - [0:0]
:ufw-after-output - [0:0]
:ufw-after-forward - [0:0]

FORWARD 相关的链只有 ufw-before-forwardufw-after-forward(还有 ufw-user-forward)。往不存在的 ufw-forward 追加,iptables-restore原子执行的,一旦这条报错,整个 after.rules 全部回滚不加载,ufw 还会进入报错状态。

这是我上一条回复给你的示例里写错了链名,抱歉,应改成 ufw-after-forward

问题2(逻辑):只开了"容器↔容器",没开"容器→外网"

就算链名改对,你第一条是:

-s 172.16.0.0/12 -d 172.16.0.0/12 -j ACCEPT

源和目的限定在 172.16/12,只放行容器互访。容器访问外网时目的 IP 是公网地址,不匹配这条;而外网回程的 NEW 包也进不来。所以"上不了外网/DNS"这个最常见的症状仍然没解决。

正确写法

把三行替换成两行(链名对 + 放开 egress):

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

应用与验证

sudo ufw reload          # 或 sudo ufw disable && sudo ufw enable
sudo systemctl restart docker
sudo iptables -S ufw-after-forward     # 确认两条规则真的进去了、没报错

进容器测:

ping -c3 223.5.5.5       # 通外网 IP
wget -qO- https://www.baidu.com | head # 通 DNS+HTTP

补充提醒

需要我把它收敛成"只放行到特定外网/指定端口"的最小权限版本,告诉我你的容器实际要访问哪些目标即可。

 


Revision #2
Created 2026-09-04 02:46:06 UTC by Admin
Updated 2026-09-04 03:28:19 UTC by Admin