自从意识到在互联网上有成千上万的扫描器 24 小时不停的扫扫扫,以及在 Censys.io 网络空间搜索引擎里几乎能搜索到关于本人服务器上运行的业务的近乎一切详情后,我开始怕了。服务器上暴露端口可能导致各种被入侵,被当肉鸡,或者暴露源站 ip,不同机子之间的关联信息。所以一年前开始我就特别注重服务器防火墙的配置。
妈的,直到上个月我才发现一个怪事,就是 Docker 容器暴露出来的端口不会受 UFW 的规则影响,手动 deny 掉也照样可以访问,无大语了。
当你在使用 Docker 时,它会创建一个虚拟网络接口(通常是名为 docker0 的网桥),并使用 Linux 的网络命名空间来隔离容器的网络环境,这些操作是通过 iptables 修改系统网络功能实现的
UFW(Uncomplicated Firewall)是一个简化了防火墙配置的前端工具,它使用 iptables 来管理 Linux 系统的防火墙规则。当你在使用 UFW 时,其实是它根据你的配置再设置 iptables 规则来限制网络流量。
然而,Docker 会修改系统的 iptables 规则,以便容器之间可以相互通信,并且容器可以与主机和外部网络进行通信。而且这些修改的优先级高于 UFW 这样的 iptables 规则管理程序,导致 UFW 的规则失效。 Docker 直接操作了 iptables 规则,而不是通过 UFW。
具体现象是:
在一个对外提供服务的服务器上启用了 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
也无法阻止外部访问这个端口。
这个问题其实挺严重的,这意味着本来只是为了在内部提供服务的一个端口被暴露在公共网络上。
别用ufw
了,用firewall
就没这个问题
docker create
:创建容器,处于停止状态。
centos:latest
:centos容器:最新版本(也可以指定具体的版本号)。docker run
:创建并启动容器。