默认情况下,创建容器如果绑定了端口,则 docker 会自动修改 iptables 打开这个端口。然而 UFW 并不会显示这个规则,这就导致了不管使用 UFW 做什么限制,docker 绑定的这个端口都是开放的。
问题所在
默认情况下,创建容器如果绑定了端口,则 docker 会自动修改 iptables 打开这个端口。然而 UFW(uncomplicated firewall) 并不会显示这个规则,这就导致了不管使用 UFW 做什么限制,docker 绑定的这个端口都是开放的。
可以使用 iptables -L DOCKER 查看 docker 在防火墙上开的洞,而且官方并不打算修复这个问题。
那么现在要做的就是禁止 docker 自作聪明的修改 iptables,并使用 UFW 来限制 docker 的端口开放。
1 启用 UFW
在启动 UFW 之前务必添加规则允许 ssh 通过,否则...
|
|
2 禁止 docker 更新 iptables
Ubuntu 16.04 之后使用 systemd 替代 upstart,所以在 /etc/default/docker
修改 DOCKER_OPTS 加上 --iptables=false
的方式不起作用了。
|
|
检查 docker 的启动命令
|
|
3 配置 docker 的 NAT
完成上面两步之后 docker 就应该处于 UFW 的限制之下了。如果重启之后发现 docker 容器无法连接外网的话,还需要这里配置
|
|
检查 docker 容器是否能连接外网
|
|
列出 docker 的网络
|
|
其他
nginx 无法获取真实 ip 可以使用 host 模式启动容器
|
|
docker for macOS
There is no docker0 bridge on macOS
在 macOS 上是看不到 docker0 这个网桥的,所以容器是无法通过 172.0.0.1 来向宿主机通信,这时候就可以使用 docker.for.mac.localhost
来连接(v17.06+ only)。
然而容器内还是无法获取客户端的真实 IP 的,也是一个(几年前的坑)(https://github.com/moby/moby/issues/15086)。
有人提出3个方案:
一是使用 --net=host 启动容器,二是 disable the userland proxy ,然而在 macOS 上并没什么卵用。
最后一个令人窒息的操作,即在宿主机开一个 nginx 反向代理,在请求头加上 IP。