CentOS + Docker + iptables(DOCKER-USER)生产环境防火墙方案
目标
实现:
- Docker 正常使用 iptables
- Docker 端口映射正常
- 使用 iptables 限制指定 IP 访问
- 不影响 Docker NAT
- 服务器重启后规则不丢失
- Docker 服务正常访问
推荐方案:
iptables-services
+
Docker 默认 iptables
+
DOCKER-USER 链控制访问一、整体架构
公网
↓
iptables DOCKER-USER
↓
Docker NAT
↓
Container
Docker 会自动维护:
- nat
- FORWARD
- DOCKER
- DOCKER-USER
其中:
DOCKER-USER
是专门给用户写自定义规则的。
二、正确启动顺序(重要)
正确顺序:
1. 启动 iptables
2. 启动 docker
3. docker 创建 DOCKER / DOCKER-USER 链
4. 写入白名单规则
注意:
DOCKER-USER 链必须在 Docker 启动后才存在
三、安装 iptables-services
CentOS 7
yum install -y iptables-services
CentOS 8
dnf install -y iptables-services
四、关闭 firewalld(推荐)
Docker 和 firewalld 容易冲突。
systemctl stop firewalld
systemctl disable firewalld
五、启动 iptables
systemctl enable iptables
systemctl start iptables
查看状态:
systemctl status iptables
六、确认 Docker 使用 iptables
查看:
cat /etc/docker/daemon.json
不要出现:
{
"iptables": false
}
正确应该是:
{
"iptables": true
}
或者不写。
七、启动 Docker
systemctl enable docker
systemctl start docker
八、确认 DOCKER-USER 存在
iptables -L -n
应该看到:
Chain DOCKER
Chain DOCKER-USER
九、启动容器
示例:
docker run -d \
--name nginx \
-p 8080:80 \
nginx
Docker 会自动:
- 创建 NAT
- 映射端口
- 添加 FORWARD 规则
不要手工改 Docker 链。
十、配置白名单访问(核心)
示例需求
开放:
8080
只允许:
1.1.1.1
2.2.2.2
访问。
1. 放行已建立连接(必须)
iptables -I DOCKER-USER 1 \
-m state --state RELATED,ESTABLISHED \
-j ACCEPT
2. 放行白名单 IP
iptables -I DOCKER-USER 2 \
-s 1.1.1.1 \
-p tcp --dport 8080 \
-j ACCEPT
iptables -I DOCKER-USER 3 \
-s 2.2.2.2 \
-p tcp --dport 8080 \
-j ACCEPT
3. 拒绝其他 IP
iptables -A DOCKER-USER \
-p tcp --dport 8080 \
-j DROP
十一、查看规则顺序
iptables -L DOCKER-USER -n --line-numbers
应该类似:
1 ACCEPT state RELATED,ESTABLISHED
2 ACCEPT tcp -- 1.1.1.1 tcp dpt:8080
3 ACCEPT tcp -- 2.2.2.2 tcp dpt:8080
4 DROP tcp -- 0.0.0.0/0 tcp dpt:8080
iptables:
从上往下匹配
顺序非常重要。
十二、多个端口限制
例如:
- 80
- 443
- 8080
统一控制:
iptables -I DOCKER-USER 2 \
-s 1.1.1.1 \
-p tcp \
-m multiport --dports 80,443,8080 \
-j ACCEPT
iptables -A DOCKER-USER \
-p tcp \
-m multiport --dports 80,443,8080 \
-j DROP
十三、保存规则(非常重要)
否则重启后会丢失。
保存方式
service iptables save
或者:
iptables-save > /etc/sysconfig/iptables
十四、服务器重启后的恢复流程
服务器启动:
1. iptables 服务启动
2. 加载 /etc/sysconfig/iptables
3. docker 启动
4. docker 自动补充 DOCKER 链
5. DOCKER-USER 链恢复
6. 白名单继续生效
结果:
Docker 正常
规则不丢
端口正常
白名单正常
十五、查看 Docker 自动规则
查看 filter:
iptables -L -n
查看 nat:
iptables -t nat -L -n
十六、常见问题
1. 为什么不用 INPUT 链?
Docker 大量流量走:
FORWARD
不是 INPUT。
因此:
iptables -A INPUT ...
很多时候无效。
正确做法:
DOCKER-USER
2. 为什么不要关闭 Docker iptables?
不要:
{
"iptables": false
}
否则:
- NAT 失效
- 端口映射异常
- overlay 网络异常
- 容器通信失败
3. 为什么不要直接 DROP FORWARD?
错误:
iptables -P FORWARD DROP
可能导致:
- Docker 网络全部异常
- 容器互通失败
- 映射端口失效
4. DOCKER-USER 规则丢了怎么办?
重启 Docker:
systemctl restart docker
十七、生产环境推荐
推荐:
公网
↓
iptables 白名单
↓
docker
↓
container
更高级推荐:
公网
↓
Nginx / HAProxy
↓
Docker 内网容器
Docker 不直接暴露公网。
十八、最终推荐方案(企业生产标准)
推荐:
iptables-services
+
docker 默认 iptables
+
DOCKER-USER 白名单
适用于:
- Docker
- Kubernetes
- Rancher
- Harbor
- Swarm
等生产环境。
十九、完整命令(可直接执行)
安装
yum install -y iptables-services
关闭 firewalld
systemctl stop firewalld
systemctl disable firewalld
启动 iptables
systemctl enable iptables
systemctl start iptables
启动 docker
systemctl enable docker
systemctl start docker
启动容器
docker run -d -p 8080:80 nginx
添加白名单
iptables -I DOCKER-USER 1 \
-m state --state RELATED,ESTABLISHED \
-j ACCEPT
iptables -I DOCKER-USER 2 \
-s 1.1.1.1 \
-p tcp --dport 8080 \
-j ACCEPT
iptables -I DOCKER-USER 3 \
-s 2.2.2.2 \
-p tcp --dport 8080 \
-j ACCEPT
iptables -A DOCKER-USER \
-p tcp --dport 8080 \
-j DROP
保存规则
service iptables save
二十、验证
查看规则
iptables -L DOCKER-USER -n --line-numbers
测试白名单 IP
curl http://服务器IP:8080
非白名单 IP
应该无法访问。