Docker和UFW不兼容问题
Docker 和 UFW 默认情况下不兼容,因为它们都会尝试修改相同的 iptables 规则集。当 Docker 映射容器端口到宿主机时,它会自动修改 iptables 规则以允许流量通过,而 UFW 的规则则不会影响这些由 Docker 管理的端口,导致 UFW 的规则看起来没有生效。
为了解决这个问题,可以通过以下步骤让 UFW 控制 Docker 的端口:
-
禁用 Docker 修改 iptables 的能力:在 Docker 的配置文件中设置
iptables
为false
。对于使用systemd
的系统,可以创建一个docker.service.d
目录下的override.conf
文件来覆盖默认的 Docker 启动配置,而不是修改/etc/default/docker
文件。例如:mkdir -p /lib/systemd/system/docker.service.d cat << EOF > /lib/systemd/system/docker.service.d/override.conf [Service] ExecStart= ExecStart=/usr/bin/dockerd EOF cat << EOF > /etc/docker/daemon.json { "hosts": ["fd://"], "dns": ["8.8.8.8", "8.8.4.4"], "iptables": false } EOF systemctl daemon-reload && systemctl restart docker
这样,Docker 就不会尝试管理 iptables 规则了,而是由 UFW 接管。
-
配置 UFW 以允许 Docker 流量:修改 UFW 的配置文件
/etc/ufw/after.rules
,在文件末尾添加以下规则,以确保 Docker 容器的流量可以通过 UFW:# BEGIN UFW AND DOCKER *filter :ufw-user-forward - [0:0] :ufw-docker-logging-deny - [0:0] :DOCKER-USER - [0:0] -A DOCKER-USER -j ufw-user-forward -A DOCKER-USER -j RETURN -s 10.0.0.0/8 -A DOCKER-USER -j RETURN -s 172.16.0.0/12 -A DOCKER-USER -j RETURN -s 192.168.0.0/16 -A DOCKER-USER -p udp -m udp --sport 53 --dport 1024:65535 -j RETURN -A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 192.168.0.0/16 -A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 10.0.0.0/8 -A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 172.16.0.0/12 -A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 192.168.0.0/16 -A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 10.0.0.0/8 -A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 172.16.0.0/12 -A DOCKER-USER -j RETURN -A ufw-docker-logging-deny -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[UFW DOCKER BLOCK] " -A ufw-docker-logging-deny -j DROP COMMIT # END UFW AND DOCKER
然后重启 UFW 以应用更改:
sudo systemctl restart ufw
现在,UFW 应该能够控制 Docker 容器的端口了。
-
允许特定端口的访问:如果需要允许外部访问某个容器的特定端口,可以使用
ufw route
命令,例如:ufw route allow proto tcp from any to any port 80
这将允许外部网络访问所有 Docker 容器内部服务端口为 80 的服务。如果只想允许访问特定容器,可以指定容器的内部 IP 地址:
ufw route allow proto tcp from any to 172.17.0.2 port 80
其中
172.17.0.2
是容器的内部 IP 地址。
通过这些步骤,你应该能够使 UFW 控制 Docker 容器的端口,同时保持系统的安全性。
ufw相关命令
ufw status numbered
ufw delete 2
ufw allow from 192.168.1.100 to any port 22 proto tcp
ufw allow from 192.168.1.0/24 to any port 21 proto tcp
ufw allow 80/tcp
ufw reload
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。