docker bridge网络无防火墙功能,需通过宿主机防火墙(firewalld/ufw)或docker-user链控制访问;放行映射端口时须注意dnat与forward路径,docker-user链规则匹配容器端口而非宿主机端口,严禁修改docker自建链。

Docker Bridge 网络本身不自带防火墙功能,宿主机的系统防火墙(如 firewalld 或 ufw)才是控制外部访问的关键。但直接在 INPUT 链放行端口,往往不够——因为流量路径涉及 DNAT 和 FORWARD,规则位置错了就形同虚设。
下面分场景说明怎么加才真正生效:
只让外部访问某个映射端口(比如宿主机 8080 → 容器 80)
这是最常见需求。防火墙要放行的是宿主机监听的端口(8080),不是容器内部端口(80)。
- firewalld(CentOS/RHEL/Fedora):
必须加 --permanent 并 reloadsudo firewall-cmd --add-port=8080/tcp --permanent sudo firewall-cmd --reload
- ufw(Ubuntu/Debian):
仅允许端口还不够,必须开启 FORWARD 链转发sudo ufw allow 8080/tcp sudo ufw default allow forwarded sudo ufw reload
否则即使端口开了,Docker 的流量仍被 ufw 的 FORWARD 默认策略拦截。
按来源 IP 精细控制(比如只允许公司内网访问)
这类规则不能只靠 INPUT 链,因为映射流量实际走的是 FORWARD 路径。推荐用 DOCKER-USER 链——这是 Docker 官方预留的、在所有 Docker 自动规则前执行的链。
# 允许 192.168.10.0/24 访问宿主机 8080 映射的容器 sudo iptables -I DOCKER-USER -p tcp -s 192.168.10.0/24 --dport 8080 -j ACCEPT # 拒绝其他所有访问 sudo iptables -I DOCKER-USER -p tcp --dport 8080 -j DROP
⚠️ 注意:DOCKER-USER 规则匹配的是 DNAT 后的目标(即容器 IP 和端口),所以 --dport 应填容器内端口(如 80),不是宿主机端口(8080)。若想按原始请求地址和端口过滤,需配合 conntrack 模块:
sudo iptables -I DOCKER-USER -p tcp -m conntrack --ctorigdstport 8080 --ctorigdst 0.0.0.0/0 -j ACCEPT
避免冲突:别碰 Docker 自建的链
Docker 创建了 DOCKER、DOCKER-ISOLATION-STAGE-1 等链,这些是维持网络正常运转的基础。手动修改它们可能导致容器无法通信或端口映射失效。
- ✅ 正确做法:只往 DOCKER-USER 链加规则,或用 firewalld/ufw 管理宿主机入口。
- ❌ 错误做法:直接删改 DOCKER 链、清空 FORWARD 链、禁用 Docker 的 iptables 功能(
--iptables=false)——这会破坏桥接网络连通性。
验证是否生效
- 查看当前规则:
sudo iptables -L DOCKER-USER -n -v # 看自定义规则计数 sudo firewall-cmd --list-ports # firewalld 已开放端口 sudo ufw status verbose # ufw 状态及转发策略
- 测试访问:从外部机器
curl http://宿主机IP:8080,同时用tcpdump -i docker0 port 80确认流量是否到达虚拟网桥。
不复杂但容易忽略











