daemon.json不能写具体iptables规则,仅能通过"iptables": false开关禁用Docker自动管理iptables,将控制权交由firewalld或手动iptables统一管控。
直接在 daemon.json 里不能“指定 iptables 规则”,它不支持写具体规则语句。它的作用是控制 docker 守护进程是否**参与管理** iptables —— 关键在于开关和策略层级的协调,而不是代替你写 iptables -a。
关闭 Docker 自动操作 iptables
这是最常用、也最推荐的做法,尤其当你已启用 firewalld 或手动维护 iptables:
- 编辑
/etc/docker/daemon.json - 添加或确认包含:
{"iptables": false} - 重启 Docker:
sudo systemctl restart docker
这样 Docker 就不再自动增删 DOCKER、DOCKER-USER 等链,也不会插 NAT 或 FORWARD 规则。所有网络策略交由 firewalld 或你手动配置的 iptables 统一管控。
用 DOCKER-USER 链做前置过滤(推荐替代方案)
如果你仍想保留 Docker 的网络自动配置能力(比如容器互通、端口映射),但又需要加访问控制,就别动 Docker 的规则,而是利用它预留的 DOCKER-USER 链:
- Docker 启动时会自动创建
DOCKER-USER链,并确保它在所有 Docker 规则之前执行 - 你可以安全地往里面加规则,比如只允许某 IP 访问容器端口:
sudo iptables -I DOCKER-USER -i eth0 ! -s 192.168.1.100 -p tcp --dport 8080 -j DROP - 这类规则不会被 Docker 覆盖,firewalld 重启后也不会丢失(只要保存了 iptables 规则)
配合 firewalld 的正确姿势
启用 firewalld 后,Docker 容器端口映射失效或“绕过防火墙”,根本原因是两者规则打架。解决路径很明确:
- 保持
"iptables": true(默认),但确保 firewalld 使用iptables后端(不是 nftables) - 或者更稳妥:设
"iptables": false,然后用 firewalld 显式开放容器实际使用的宿主机端口
例如容器跑在-p 8080:80,就在 firewalld 中执行:sudo firewall-cmd --add-port=8080/tcp --permanent && sudo firewall-cmd --reload - 注意:firewalld 不感知容器内部端口,只管宿主机监听端口
其他相关参数(辅助控制)
虽然不直接写规则,但这些 daemon.json 设置会影响网络行为:
-
"icc": false:禁止容器间通过 IP 互访(默认 true) -
"ip-forward": false:关闭内核 IP 转发(影响容器访问外网,慎用) -
"userland-proxy": false:禁用用户态代理,改用 iptables REDIRECT(对端口性能敏感时可选)


















