在 Debian 上部署 Docker 后,经常会遇到“防火墙把 Docker 容器流量也挡了”或者“Docker 自己改了 iptables 规则,导致 ufw/firewalld 失效”的问题。根本原因是:Docker 默认直接操作 iptables(底层 netfilter),而不是走 ufw / nftables 前端。
下面按常见场景说明如何“兼容”。
Debian 常见防火墙方案:
Docker 默认:
DOCKER / DOCKER-USER 链中写规则DOCKER-USER 链(官方推荐)Docker 预留了一个链:
DOCKER-USER
所有进入容器的流量都会经过它,你可以把防火墙规则写在这里。
示例(只允许 80/443 对外):
iptables -I DOCKER-USER -i eth0 -p tcp --dport 80 -j ACCEPT
iptables -I DOCKER-USER -i eth0 -p tcp --dport 443 -j ACCEPT
iptables -I DOCKER-USER -i eth0 -j DROP
⚠️ 不要直接改
DOCKER链,Docker 重启会覆盖
deny,但 Docker 端口还是能访问编辑:
sudo vim /etc/ufw/after.rules
在文件末尾加上:
# BEGIN UFW AND DOCKER
*docker
:ufw-user-forward - [0:0]
:ufw-docker-allow - [0:0]
-A ufw-user-forward -j ufw-docker-allow
-A ufw-docker-allow -o docker0 -j ACCEPT
COMMIT
# END UFW AND DOCKER
sudo ufw default deny routed
sudo systemctl restart ufw
Docker 默认不兼容 nftables 的前端规则
确保:
sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
然后:
sudo systemctl restart docker
需要在 Docker 中:
{
"iptables": false
}
然后自己写 nftables 规则(不推荐新手)
编辑或新建:
sudo vim /etc/docker/daemon.json
{
"iptables": true,
"bridge": "docker0"
}
如果你完全不想 Docker 动防火墙:
{
"iptables": false
}
⚠️ 但这样你需要自己保证容器能上网
# 看 Docker 写的规则
iptables -L DOCKER-USER -n -v
# 看 nat
iptables -t nat -L -n -v
# Docker 网络
docker network ls
Debian + Docker 防火墙兼容的核心:
- 不要指望 ufw 直接管 Docker
- 把规则写在
DOCKER-USER- 或明确让 Docker 用 iptables-legacy
如果你愿意,可以告诉我:
我可以给你一套可直接复制粘贴的配置。