MENU

CentOS + Docker + iptables(DOCKER-USER)生产环境防火墙完整方案

May 21, 2026 • Linux运维工作

CentOS Docker 使用 DOCKER-USER + iptables 限制容器端口访问方案

1. 适用场景

本文适用于以下场景:

  • CentOS 服务器使用 Docker 部署服务
  • Docker 容器通过 -pports 暴露端口
  • 需要限制容器暴露端口只允许指定服务器或指定 IP 访问
  • 不希望关闭 Docker 自动管理 iptables
  • 不希望影响 Docker NAT、端口映射、容器访问公网
  • 需要服务器重启后规则仍然生效

推荐方案:

iptables-services
+
Docker 默认 iptables 管理
+
DOCKER-USER 链做访问控制

2. 为什么使用 DOCKER-USER

Docker 启动容器并映射端口时,会自动写入 iptables 规则,例如:

  • nat
  • filter
  • DOCKER
  • DOCKER-USER

其中:

DOCKER 链:Docker 自动维护,不建议手工修改
DOCKER-USER 链:Docker 预留给用户自定义访问控制

Docker 的转发流量大致会经过:

FORWARD
  ↓
DOCKER-USER
  ↓
DOCKER
  ↓
容器

因此,在 DOCKER-USER 链中写规则,可以在 Docker 自动放行容器端口之前,先做访问控制。


3. 重要原则

3.1 不建议关闭 Docker iptables

不要在 /etc/docker/daemon.json 中配置:

{
  "iptables": false
}

否则可能导致:

  • Docker NAT 失效
  • 容器端口映射异常
  • 容器访问外网异常
  • Docker bridge 网络异常
  • Docker Compose 网络异常

推荐保持 Docker 默认配置:

{
  "iptables": true
}

或者不配置该项。


3.2 不要直接修改 DOCKER 链

不建议直接修改:

DOCKER

因为该链由 Docker 自动维护,Docker 重启、容器启动或停止时都可能改写。

应使用:

DOCKER-USER

3.3 不要只写 INPUT 链

Docker 暴露端口的访问流量很多情况下走的是:

FORWARD

而不是:

INPUT

所以只写 INPUT 链经常无法限制 Docker 映射端口。


3.4 DOCKER-USER 不只影响入站

DOCKER-USER 作用于 FORWARD 链,因此它不仅影响外部访问容器,也会影响容器访问公网。

容器访问公网路径大致是:

容器
  ↓
docker0 / br-xxxx
  ↓
FORWARD
  ↓
DOCKER-USER
  ↓
外网

所以规则里必须先放行 Docker bridge 的出站流量,否则会出现:

宿主机可以访问公网 IP 和端口
但容器里面访问不通

4. 推荐启动顺序

推荐顺序:

1. 启动 iptables 服务
2. 启动 Docker 服务
3. Docker 自动创建 DOCKER / DOCKER-USER 链
4. 写入 DOCKER-USER 访问控制规则
5. 保存 iptables 规则

原因:

DOCKER-USER 链通常由 Docker 创建
Docker 未启动前,该链可能不存在

5. 安装和初始化

5.1 安装 iptables-services

CentOS 7:

yum install -y iptables-services

CentOS 8:

dnf install -y iptables-services

5.2 停止 firewalld

如果决定使用 iptables-services 管理规则,建议关闭 firewalld:

systemctl stop firewalld
systemctl disable firewalld

查看状态:

systemctl status firewalld

5.3 启动 iptables

systemctl enable iptables
systemctl start iptables

查看状态:

systemctl status iptables

5.4 启动 Docker

systemctl enable docker
systemctl start docker

查看状态:

systemctl status docker

5.5 确认 DOCKER-USER 存在

iptables -L -n

应能看到类似内容:

Chain DOCKER
Chain DOCKER-USER

也可以单独查看:

iptables -L DOCKER-USER -n --line-numbers

6. 示例需求

假设服务器上有 Docker 容器暴露端口:

8080

要求:

允许 1.1.1.1 访问 8080
允许 2.2.2.2 访问 8080
拒绝其他 IP 访问 8080
允许容器正常访问公网

7. 推荐规则模板

7.1 清理旧的 DOCKER-USER 自定义规则

如果之前 DOCKER-USER 规则较乱,可以先清空该链:

iptables -F DOCKER-USER

如果提示链不存在,说明 Docker 可能未启动,先执行:

systemctl restart docker

然后再次检查:

iptables -L DOCKER-USER -n --line-numbers

7.2 添加规则:放行容器出站

默认 Docker bridge:

iptables -I DOCKER-USER 1 -i docker0 -j ACCEPT

Docker Compose 或自定义 bridge 网络通常是 br-xxxx,建议放行:

iptables -I DOCKER-USER 2 -i br+ -j ACCEPT

这两条用于保证容器可以正常访问外网,例如:

  • DNS
  • HTTP / HTTPS
  • yum / apt
  • curl
  • API 调用
  • 连接外部数据库或服务

7.3 添加规则:放行已建立连接

iptables -I DOCKER-USER 3 \
  -m state --state RELATED,ESTABLISHED \
  -j ACCEPT

作用:

允许已经建立的连接继续返回数据

7.4 添加规则:放行白名单 IP

允许 1.1.1.1 访问容器暴露的 8080

iptables -I DOCKER-USER 4 \
  -s 1.1.1.1 \
  -p tcp --dport 8080 \
  -j ACCEPT

允许 2.2.2.2 访问容器暴露的 8080

iptables -I DOCKER-USER 5 \
  -s 2.2.2.2 \
  -p tcp --dport 8080 \
  -j ACCEPT

7.5 添加规则:拒绝其他 IP

iptables -A DOCKER-USER \
  -p tcp --dport 8080 \
  -j DROP

7.6 添加默认 RETURN

建议在链末尾保留:

iptables -A DOCKER-USER -j RETURN

说明:

未被本链拦截的流量返回给 Docker 后续链处理

如果 DOCKER-USER 链中原本已有 RETURN,无需重复添加。


8. 完整命令示例

以下命令可按需修改白名单 IP 和端口后使用。

# 清空 DOCKER-USER 旧规则
iptables -F DOCKER-USER

# 放行 Docker 默认 bridge 出站
iptables -A DOCKER-USER -i docker0 -j ACCEPT

# 放行 Docker Compose / 自定义 bridge 出站
iptables -A DOCKER-USER -i br+ -j ACCEPT

# 放行已建立连接
iptables -A DOCKER-USER \
  -m state --state RELATED,ESTABLISHED \
  -j ACCEPT

# 放行白名单 IP 访问 8080
iptables -A DOCKER-USER \
  -s 1.1.1.1 \
  -p tcp --dport 8080 \
  -j ACCEPT

iptables -A DOCKER-USER \
  -s 2.2.2.2 \
  -p tcp --dport 8080 \
  -j ACCEPT

# 拒绝其他 IP 访问 8080
iptables -A DOCKER-USER \
  -p tcp --dport 8080 \
  -j DROP

# 其他流量交还 Docker 后续规则处理
iptables -A DOCKER-USER -j RETURN

9. 多端口示例

如果要限制多个端口,例如:

80,443,8080

只允许 1.1.1.12.2.2.2 访问:

iptables -F DOCKER-USER

iptables -A DOCKER-USER -i docker0 -j ACCEPT
iptables -A DOCKER-USER -i br+ -j ACCEPT

iptables -A DOCKER-USER \
  -m state --state RELATED,ESTABLISHED \
  -j ACCEPT

iptables -A DOCKER-USER \
  -s 1.1.1.1 \
  -p tcp \
  -m multiport --dports 80,443,8080 \
  -j ACCEPT

iptables -A DOCKER-USER \
  -s 2.2.2.2 \
  -p tcp \
  -m multiport --dports 80,443,8080 \
  -j ACCEPT

iptables -A DOCKER-USER \
  -p tcp \
  -m multiport --dports 80,443,8080 \
  -j DROP

iptables -A DOCKER-USER -j RETURN

10. 查看规则

查看规则顺序:

iptables -L DOCKER-USER -n --line-numbers

查看规则命中计数:

iptables -L DOCKER-USER -n -v --line-numbers

预期类似:

Chain DOCKER-USER
num  target  prot opt source      destination
1    ACCEPT  all  --  0.0.0.0/0   0.0.0.0/0    in docker0
2    ACCEPT  all  --  0.0.0.0/0   0.0.0.0/0    in br+
3    ACCEPT  all  --  0.0.0.0/0   0.0.0.0/0    state RELATED,ESTABLISHED
4    ACCEPT  tcp  --  1.1.1.1     0.0.0.0/0    tcp dpt:8080
5    ACCEPT  tcp  --  2.2.2.2     0.0.0.0/0    tcp dpt:8080
6    DROP    tcp  --  0.0.0.0/0   0.0.0.0/0    tcp dpt:8080
7    RETURN  all  --  0.0.0.0/0   0.0.0.0/0

11. 保存规则

规则验证无误后保存。

CentOS 7 常用:

service iptables save

或者:

iptables-save > /etc/sysconfig/iptables

确认文件已写入:

cat /etc/sysconfig/iptables

12. 服务器重启后是否失效

只要已经保存到:

/etc/sysconfig/iptables

并且启用了 iptables 服务:

systemctl enable iptables

服务器重启后会自动加载规则。

推荐重启后的顺序:

1. iptables 服务启动
2. 加载 /etc/sysconfig/iptables
3. Docker 服务启动
4. Docker 自动恢复 DOCKER / DOCKER-USER 相关链
5. DOCKER-USER 中的白名单规则继续生效

如果重启后发现 DOCKER-USER 链异常,可执行:

systemctl restart docker

然后检查:

iptables -L DOCKER-USER -n --line-numbers

13. 清理混乱规则并重新配置

13.1 最安全方式:只清理 DOCKER-USER

推荐:

iptables -F DOCKER-USER

然后重新按本文第 8 节添加规则。

这种方式不会影响 Docker 自动生成的 NAT 规则。


13.2 清理 filter 表

如果整个 filter 表规则混乱,可以先备份:

iptables-save > /root/iptables-backup-$(date +%F-%H%M%S).rules

再清理 filter 表:

iptables -F
iptables -X

然后重启 Docker:

systemctl restart docker

再重新写入 DOCKER-USER 规则。


13.3 不建议清理 nat 表

不要轻易执行:

iptables -t nat -F
iptables -t nat -X

因为 Docker 的端口映射和 MASQUERADE 依赖 nat 表。

如果已经误清理 nat 表,需要重启 Docker:

systemctl restart docker

必要时重启相关容器。


14. 验证方法

14.1 验证白名单访问

在白名单服务器执行:

curl http://服务器IP:8080

应可以访问。


14.2 验证非白名单访问

在非白名单服务器执行:

curl http://服务器IP:8080

应无法访问或连接超时。


14.3 验证容器访问公网

进入容器:

docker exec -it 容器名 sh

测试 IP 连通性:

ping 8.8.8.8

测试域名解析和 HTTPS:

curl https://www.baidu.com

如果宿主机能访问外网,但容器不能访问,优先检查:

iptables -L DOCKER-USER -n -v --line-numbers

确认是否有以下放行规则:

-i docker0 -j ACCEPT
-i br+ -j ACCEPT

15. 常见问题

15.1 宿主机能访问公网,容器不能访问公网

原因通常是 DOCKER-USER 拦截了容器出站流量。

解决:

iptables -I DOCKER-USER 1 -i docker0 -j ACCEPT
iptables -I DOCKER-USER 2 -i br+ -j ACCEPT

15.2 白名单规则不生效

检查规则顺序:

iptables -L DOCKER-USER -n --line-numbers

白名单 ACCEPT 必须在 DROP 前面。


15.3 Docker 端口映射失效

检查 nat 表:

iptables -t nat -L -n

检查 Docker 服务:

systemctl status docker

如有必要:

systemctl restart docker

15.4 Docker Compose 网络访问异常

Docker Compose 通常使用 br-xxxx 网桥。

确认是否有:

iptables -A DOCKER-USER -i br+ -j ACCEPT

15.5 不知道容器使用哪个网桥

查看网络接口:

ip addr

常见接口:

docker0
br-xxxxxxxxxxxx

也可以查看 Docker 网络:

docker network ls
docker network inspect 网络名

16. 生产环境建议

16.1 最推荐

Docker 保持默认 iptables 管理
iptables-services 做持久化
DOCKER-USER 做访问控制
不要手工修改 DOCKER 链
不要关闭 Docker iptables

16.2 更安全的架构

如果条件允许,不建议容器端口直接暴露公网。

更推荐:

公网
  ↓
Nginx / HAProxy / SLB
  ↓
Docker 内网服务

Docker 端口可以只监听本地:

docker run -p 127.0.0.1:8080:80 nginx

然后由 Nginx 做:

  • IP 白名单
  • TLS
  • 访问日志
  • 限流
  • WAF

17. 最终可执行模板

请将以下内容中的 IP 和端口替换为实际值。

# 1. 确认 Docker 已启动
systemctl start docker

# 2. 清空 DOCKER-USER 旧规则
iptables -F DOCKER-USER

# 3. 放行容器出站
iptables -A DOCKER-USER -i docker0 -j ACCEPT
iptables -A DOCKER-USER -i br+ -j ACCEPT

# 4. 放行已建立连接
iptables -A DOCKER-USER \
  -m state --state RELATED,ESTABLISHED \
  -j ACCEPT

# 5. 放行白名单访问容器端口
iptables -A DOCKER-USER \
  -s 1.1.1.1 \
  -p tcp --dport 8080 \
  -j ACCEPT

iptables -A DOCKER-USER \
  -s 2.2.2.2 \
  -p tcp --dport 8080 \
  -j ACCEPT

# 6. 拒绝其他来源访问该端口
iptables -A DOCKER-USER \
  -p tcp --dport 8080 \
  -j DROP

# 7. 其他流量交还 Docker 处理
iptables -A DOCKER-USER -j RETURN

# 8. 查看规则
iptables -L DOCKER-USER -n -v --line-numbers

# 9. 保存规则
service iptables save

18. 回滚方法

如果规则配置后出现异常,可恢复备份:

iptables-restore < /root/iptables-backup.rules

或者临时清空 DOCKER-USER:

iptables -F DOCKER-USER
iptables -A DOCKER-USER -j RETURN

然后重启 Docker:

systemctl restart docker

19. 注意事项

  • 修改前一定要备份 iptables。
  • 远程操作时,谨慎执行 DROP 规则,避免误封 SSH。
  • Docker 主机不要随意清理 nat 表。
  • Kubernetes 节点不要直接套用本文清理规则,kube-proxy、Calico、Flannel 等也依赖 iptables。
  • 白名单规则必须写在 DROP 规则前面。
  • 容器出站放行规则必须写在 DROP 规则前面。
Last Modified: May 22, 2026