在搭建服务的时候,我很疑惑为何不用设定UFW规则就能从外部网络访问,后来发现Docker跟UFW是冲突的,Docker会无视UFW的设定径行开放端口。 这篇文章记录如何整合二者一起使用。
Docker版本:24.0.2
UFW版本:0.36.2
UFW为Ubuntu和Debian系发行版默认使用的防火墙前端。 Docker会绕过UFW自行建立iptables规则,因此导致UFW设定的规则失效,变成外部网络能直接访问Docker容器开放的端口。
这会造成安全性问题,比方说用docker-compose跑Nextcloud,会导致除网页界面外,连数据库容器的通讯端口跟着暴露到公开网络,之后再用UFW封锁是无效的。
若是编辑 /etc/docker/daemon.json
,把Docker自动调整iptables的功能关闭会使问题更复杂,Docker容器无法对外连线,要手动设定规则。
另一个选项是放弃UFW,改用与Docker相性较好的Firewalld。 但... 那个是Redhat和SUSE系在用的。
因此我们还是想办法整合UFW和Docker吧,让UFW负责管理整个网络和Docker的连线规则。
2. Docker配合UFW运作的解决方法
现代问题需要现代手段,使用chaifeng撰写的ufw-docker指令稿能解决这问题。 他的 Github 有详细原理解释,这边直接讲解法。
如果已经修改过 /etc/docker/daemon.json
停用iptables,請將相關段落刪除。
编辑
/etc/default/ufw
,将DEFAULT_FORWARD_POLICY="ACCEPT"
修改为DEFAULT_FORWARD_POLICY="DROP"
。安装此脚本修改UFW设定文件,再重启UFW与Docker服务。
sudo wget -O /usr/local/bin/ufw-docker https://github.com/chaifeng/ufw-docker/raw/master/ufw-docker
sudo chmod +x /usr/local/bin/ufw-docker
sudo ufw-docker install
sudo systemctl restart ufw
sudo systemctl restart docker
在采用chaifeng的脚本后,来看实际例子学习新的UFW管理方式。
现在这里有个容器,它将容器内部的8080 TCP端口映射到实体机的8081 TCP端口:
8f4q1aqia searxng/searxng:latest "/sbin/tini -- /usr/…" 2 hours ago Up 2 hours 0.0.0.0:8081->8080/tcp, :::8081->8080/tcp searxng
因为上面的脚本使用了
ufw-user-forward
规则,UFW挡住了所有外部连线,我们就得分别开启「容器的8080 TCP端口」和「实体机的8081 TCP端口」:这样子外部网络能访问此容器,该容器也能对外连接了,由UFW接管Docker的连接规则。
如果仍有容器的通訊埠能繞過UFW存取,那麼請重開機試試。
3. 如何移除ufw-docker指令稿
编辑
/etc/ufw/after.rules
,将# BEGIN UFW AND DOCKER
至# END UFW AND DOCKER
之间的规则移除。移除指令稿
sudo rm /usr/local/bin/ufw-docker
3.重开机。