解决Docker跟UFW防火墙冲突问题

在搭建服务的时候,我很疑惑为何不用设定UFW规则就能从外部网络访问,后来发现Docker跟UFW是冲突的,Docker会无视UFW的设定径行开放端口。 这篇文章记录如何整合二者一起使用。 Docker版本:24.0.2 UFW版本:0.36.2 UFW为Ubuntu和Debian系发行版默认使用的防

在搭建服务的时候,我很疑惑为何不用设定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,請將相關段落刪除。

  1. 编辑 /etc/default/ufw,将 DEFAULT_FORWARD_POLICY="ACCEPT"修改为 DEFAULT_FORWARD_POLICY="DROP"

  2. 安装此脚本修改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
  1. 在采用chaifeng的脚本后,来看实际例子学习新的UFW管理方式。

  2. 现在这里有个容器,它将容器内部的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
  1. 因为上面的脚本使用了 ufw-user-forward规则,UFW挡住了所有外部连线,我们就得分别开启「容器的8080 TCP端口」和「实体机的8081 TCP端口」:

  2. 这样子外部网络能访问此容器,该容器也能对外连接了,由UFW接管Docker的连接规则。

如果仍有容器的通訊埠能繞過UFW存取,那麼請重開機試試。

3. 如何移除ufw-docker指令稿

  1. 编辑 /etc/ufw/after.rules,将 # BEGIN UFW AND DOCKER# END UFW AND DOCKER之间的规则移除。

  2. 移除指令稿

sudo rm /usr/local/bin/ufw-docker

3.重开机。

Comment