UFW 是 Ubuntu 上很流行的一个 iptables 前端,可以非常方便的管理防火墙的规则。但是当安装了 Docker,UFW 无法管理 Docker 发布出来的端口了。
具体现象是:
在一个对外提供服务的服务器上启用了 UFW,并且默认阻止所有未被允许的传入连接。
运行了一个 Docker 容器,并且使用 -p 选项来把该容器的某个端口发布到服务器的所有 IP 地址上。比如:docker run -d --name httpd -p 0.0.0.0:8080:80 httpd:alpine 将会运行一个 httpd 服务,并且将容器的 80 端口发布到服务器的 8080 端口上。
UFW 将不会阻止所有对 8080 端口访问的请求,用命令 ufw deny 8080 也无法阻止外部访问这个端口。
这个问题其实挺严重的,这意味着本来只是为了在内部提供服务的一个端口被暴露在公共网络上。
旧方案
存在问题:
http获取到的IP是docker网关的IP:172.18.0.1,不能得到用户真实的IP。通过network_mode: host
解决。但是如果2个容器占用相同的端口,就必须修改1个容器中的端口,使环境变复杂。
新方案ufw-docker
安装
下载 ufw-docker 脚本
sudo wget -O /usr/local/bin/ufw-docker \
https://github.com/chaifeng/ufw-docker/raw/master/ufw-docker
chmod +x /usr/local/bin/ufw-docker
使用下列命令来修改 ufw 的 after.rules 文件
ufw-docker install
这个命令做了以下事情:
备份文件 /etc/ufw/after.rules
把 UFW 和 Docker 的相关规则添加到文件 after.rules 的末尾
使用方法
显示帮助
ufw-docker help
检查 UFW 配置文件中防火墙规则的安装
ufw-docker check
更新 UFW 的配置文件,添加必要的防火墙规则
ufw-docker install
显示当前防火墙允许的转发规则
ufw-docker status
列出所有和容器 httpd 相关的防火墙规则
ufw-docker list httpd
暴露容器 httpd 的 80 端口
ufw-docker allow httpd 80
暴露容器 httpd 的 443 端口,且协议为 tcp
ufw-docker allow httpd 443/tcp
如果容器 httpd 绑定到多个网络上,暴露其 443 端口,协议为 tcp,网络为 foobar-external-network
ufw-docker allow httpd 443/tcp foobar-external-network
把容器 httpd 的所有映射端口都暴露出来
ufw-docker allow httpd
删除所有和容器 httpd 相关的防火墙规则
ufw-docker delete allow httpd
删除容器 httpd 的 tcp 端口 443 的规则
ufw-docker delete allow httpd 443/tcp
暴露服务 web 的 80 端口
docker service create --name web --publish 8080:80 httpd:alpine
ufw-docker service allow web 80
# 或者
ufw-docker service allow web 80/tcp
删除与服务 web 相关的规则
ufw-docker service delete allow web
问题
虚拟网络无法访问,新增规则解决
vim /etc/iptables/rules.v4
-A ufw-user-forward -s 来源IP/32 -j ACCEPT
操作方法见文章
评论