ufw对docker映射出的端口无效问题
无意中发现,如果使用这种方式启动docker容器:
docker run -d ..... -p 8081:8080 image:id无论ufw如何deny,8081端口都可以被外部访问到,甚至让我一度怀疑ufw有没有生效。
一通搜索发现了一篇文章:无视系统防火墙的docker
通过文章可以了解到,是docker对iptables的修改造成了上面的问题,利用文章中的命令 sudo iptables -L DOCKER 做了几个简单的实验,得到的结论是,除非不加 -p 这个参数,否则docker都会绑定容器本身的ip和容器内的端口,同时还会根据-p参数进行端口映射。
比如说:
-p 127.0.0.1:8081:8080 会绑定 172.17.0.2:8080和127.0.0.1:8081
-p 8081:8080 会绑定172.17.0.2:8080和0.0.0.0:8081
且自动开放了iptables,也就是说可以被外部访问到,即使在ufw中设置了deny也没用。
文章中的解决方案是修改启动参数,增加一个 --iptables=false 就不会自动允许了。但是从文章中可以看到,这样改了会产生新的问题(虽然也解决了),另外评论中可以看到,docker至今也没修改这个问题,文章是2017年的,又过了7年了,估计是不会改了。
我个人的看法是,在有公网ip的服务器上启动任何容器时,都用 -p 127.0.0.1:8081:8080 这种方式进行端口映射(除非确实是要开放),虽然麻烦点,但麻烦一次即可。
另外,通过上面的实验,对于直接用docker run启动的容器间的网络通讯,可以使用其容器ip+端口即可。但要防止容器ip的变化,在小型系统或开发环境中问题是不大的。复杂点的系统就可以上docker compose或者kubernetes之类的工具了。
License:
CC BY 4.0