解决 Docker 干预 iptables 导致异常暴露端口的问题
系统版本:CentOS Linux release 7.9.2009
Docker版本:version 24.0.7
问题
Docker 容器映射端口会自动打开宿主机的相应端口,无法用 firewalld
或 ufw
管理
解决办法
host 模式
创建 Docker 容器时使用 host
模式
1 | version: '3' |
- 优点:可以用
firewalld
或ufw
管理端口了 - 缺点:可能会造成端口冲突
在映射端口时添加 127.0.0.1
- 操作:
- 首次创建:例如
docker run -p 127.0.0.1:8090:8090 -d your-image
- 正在运行:修改
/etc/docker/daemon.json
加上"ip":"127.0.0.1"
,然后执行systemctl daemon-reload && systemctl restart docker
docker-compose
直接改就好了
- 首次创建:例如
- 优点:不再暴露宿主机的端口
- 缺点:只能本机访问,且有跨容器通信的问题
- 如果要使用
Nginx Proxy Manager
等反代的话,须确保反代工具处于host
模式,反代用127.0.0.1:映射的端口
将容器放在同一个网桥内,不再映射端口
以
Nginx Proxy Manager
反代为例
- 新建一个
reverse-network
网桥1
docker network create reverse-network
- 只暴露
Nginx Proxy Manager
的80
和443
端口1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19version: '3'
services:
app:
image: jc21/nginx-proxy-manager:latest
container_name: npm
ports:
- '80:80'
- '443:443'
networks:
- reverse-network
restart: unless-stopped
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
networks:
reverse-network:
external: true - 将其他容器也放在
reverse-network
这个网桥- 直接修改
docker-compose
文件 - 使用
CLI
创建的正在运行的容器的话麻烦一点:- 断开和原网桥的连接连上新网桥
1
2
3docker network disconnect default <container_id> # 断开旧网桥
docker network connect reverse-network <container_id> # 连上新网桥 - 修改配置文件删除端口映射
1
2
3
4
5
6
7
8
9
10
11
12
13
14# 查看容器完整的 hash_of_the_container 数值
docker inspect {容器的名称或者 id } | grep Id
# 停止 docker 服务
systemctl stop docker
# 修改配置文件
vim /var/lib/docker/containers/{hash_of_the_container}/hostconfig.json
# 找到 PortBindings, 删除 {} 里的内容
"PortBindings":{}
# 启动 docker 服务
systemctl start docker
- 断开和原网桥的连接连上新网桥
- 直接修改
用 ufw-docker
管理
懒得写了,看这个吧:https://ivonblog.com/posts/fix-ufw-docker/
注意
- 网上禁用 Docker 的 iptables 规则的办法基本都失效了,例如:
- 修改
/lib/systemd/system/docker.service
加上--iptables=false
- 修改
/etc/docker/daemon.json
加上{ "iptables" : false }
- 以上皆会造成重启 Docker 时报错:在初始化网络控制器时遇到问题,其中涉及到不能创建新的 iptables 链,
EnableIPTable
被禁用
- 修改
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 七夜 の Blog!
评论