核心在于分清“谁管哪一段流量”:Docker依赖宿主机防火墙(如firewalld、ufw)放行映射端口(如8080),而非容器内端口(如80);ufw用户须额外配置FORWARD链并设DEFAULT_FORWARD_POLICY="ACCEPT",容器内iptables仅按需启用且需加NET_ADMIN权限。

配置 Docker 容器防火墙规则,核心在于分清“谁管哪一段流量”:Docker 本身不内置防火墙,它依赖宿主机的防火墙(如 firewalld、ufw 或 iptables)控制外部访问,而容器内部若需精细过滤,则需在容器内启用 iptables 并赋予对应权限。实际操作中,90% 的问题出在宿主机防火墙未放行映射端口,或 ufw 未正确配置 FORWARD 链。
放行宿主机映射端口(最常见需求)
你运行 docker run -p 8080:80 nginx,对外提供服务的其实是宿主机的 8080 端口,不是容器里的 80。防火墙必须放开的是 8080。
-
firewalld(CentOS/RHEL/Fedora):执行
sudo firewall-cmd --add-port=8080/tcp --permanent && sudo firewall-cmd --reload -
ufw(Ubuntu/Debian):执行
sudo ufw allow 8080/tcp - 注意:别去放行 172.17.0.0/16 这类 docker0 网段——这等于绕过端口映射,直接暴露所有容器内网,极不安全。
ufw 用户必须额外配置转发链
ufw 默认会丢弃 FORWARD 流量,而 Docker 正是靠 FORWARD 链把请求从宿主机网卡转发到容器。只开端口不管转发,服务照样不通。
- 编辑
/etc/default/ufw,确保有DEFAULT_FORWARD_POLICY="ACCEPT" - 在
/etc/ufw/before.rules的*filter段末尾(COMMIT前)添加两行:
-A FORWARD -d 172.17.0.0/16 -i docker0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT -A FORWARD -s 172.17.0.0/16 -i eth0 -o docker0 -j ACCEPT
保存后执行 sudo ufw reload 生效。
在容器内配置 iptables(按需)
仅当容器自身需要过滤入站/出站流量(比如限制某 IP 访问、屏蔽扫描行为),才需在容器里用 iptables。默认容器无此权限,启动时要加参数:
- 最小权限方式:
docker run --cap-add NET_ADMIN --cap-add NET_RAW -p 8080:80 nginx - 进入容器:
docker exec -it <容器名> /bin/bash - 添加规则示例(允许 80 端口,拒绝其余):
iptables -A INPUT -p tcp --dport 80 -j ACCEPTiptables -A INPUT -j DROP - 规则重启即失效,如需持久化,需配合启动脚本或保存到文件(如
iptables-save > /etc/iptables/rules.v4)
避免踩坑的关键点
- Docker 启动时会自动写 iptables 规则(主要在 DOCKER 和 DOCKER-USER 链),不要直接删或清空整个 iptables,否则可能中断所有容器网络
- 确认端口是否真被监听:
ss -tlnp | grep :8080(宿主机视角) - 测试连通性时,先用
curl localhost:8080(本地环回),再从局域网其他机器测,排除 DNS 或客户端问题 - 生产环境建议只开放明确需要的端口,禁用 ufw/firewalld 的 default deny 不够细粒度,应结合应用层认证和反向代理做二次防护


















