- 系统:Ubuntu 22.04
- 要求:容器能访问外网,即允许请求http、https,但外部服务只允许指定ip访问容器A
- 踩坑:用Ubuntu自带的ufw是不能设置容器的访问规则的,倘若要用ufw的route规则,则需要关闭docker的iptables配置,如果关闭此配置,则容器无法请求外网。docker链是在UFW之前生效的。
步骤:
配置docker的daemon文件
添加:
bash
{
...
"iptables": true
}
重新加载daemon并重启docker
bash
1. sudo systemctl reload-daemon
2. sudo systemctl restart docker
配置容器的固定ip
在docker-compose.yaml文件中配置容器的固定ip,后续重启也不会改变。
yaml
services:
contanier:
...
networks:
engine_network:
ipv4_address: 172.20.0.3
检查docker是否启用ip_forwad
bash
cat /proc/sys/net/ipv4/ip_forward
如果输出为0,启用:
bash
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
检查docker 的iptables规则(此为重点!!!!)
注意: docker开启了iptables是默认有自己的规则的,它会绕过ufw,所以配置ufw是无效的。
可以验证下,执行:
bash
sudo iptables -L DOCKER -n -v
一般会看到类似:
Chain DOCKER (8 references)
pkts bytes target prot opt in out source destination
4 240 ACCEPT tcp -- !br-ab83bf174013 br-ab83bf174013 0.0.0.0/0 172.20.0.3 tcp dpt:<容器映射ip>
这条规则直接放行了所有ip对与容器A的访问,完全绕过了UFW。
解决方案:
-
检查是否有DOCKER-USER链
bashsudo iptables -L -n | grep "DOCKER"若没有则创建:
bashsudo iptables -N DOCKER-USER -
添加白名单规则
bash## 1. 获取容器A的ip CONTAINER_IP=$(docker inspect <容器名称> -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}') echo "容器 IP: $CONTAINER_IP" ## 2. 添加白名单:只允许指定IP访问容器A的端口 sudo iptables -I DOCKER-USER -p tcp --dport <容器端口> -s <指定IP> -d $CONTAINER_IP -j ACCEPT ## 3. 拒绝其它所有访问容器A的端口的请求 sudo iptables -A DOCKER-USER -p tcp --dport 11434 -d $OLLAMA_IP -j DROP ## 3.或者是提示用户连接被拒绝而不是超时 sudo iptables -A DOCKER-USER -p tcp --dport 11434 -d $OLLAMA_IP -j REJECT --reject-with tcp-reset -
永久保存规则
bash## 1. Ubuntu/debian使用iptables-persistent ## 安装(如果未安装) sudo apt install iptables-persistent -y ## 保存规则 sudo netfilter-persistent save ## 2. 或者手动保存 sudo iptables-save > /etc/iptables/rules.v4