赛斯叔叔 - SAIS.IO

赛斯叔叔

Docker 映射端口穿透内置防火墙

12
2024-03-21

问题现象

举例

# 自制的springboot项目的dockerfile
# springboot 其实就是一个简单的hello-world程序,写了一个HelloController 做测试
# dockerfile内容:
FROM java:8 
MAINTAINER shan <test@test@test.com> 
ADD ./demo.jar /demo.jar
EXPOSE 8848
CMD java -jar /demo.jar


# 构建镜像
docker build -f ./dockerfile -t demo .

# 创建、映射端口、运行容器
docker run -d --name=demo -p 8838:8848 demo

在阿里云服务器上,一旦我们对外置防火墙或安全组进行了端口8838的放行操作,我们发现可以直接通过浏览器访问到数据。然而,问题在于我们启动了内置防火墙firewalld,却仍然出现了端口可以直接被访问的情况。使用 Docker 部署项目,发现直接使用 -p 映射端口,会出现 Docker 直接穿透系统本机的防火墙对外开放部署项目所需的端口。

问题原因

其实 Docker 并未忽视防火墙 firewalld,实际上,Docker 并未绕过防火墙,而是因为它在 iptables 中设定了规则,这使得你无法在 firewalld 中看到这些规则。(请注意,CentOS 7 系统同时具备 iptables 和 firewalld 功能。)安装完Docker后,它会接管 iptables 。只需在执行 docker run 时添加参数,Docker 就会自动向 iptables 添加规则。因此,使用 -p 参数指定容器端口:主机端口,最终会在 iptables 中添加相应的容器端口规则。

解决方式

方式一

利用阿里云、腾讯云等云服务器所提供的外置防火墙功能。

某些服务器被称为防火墙,而其他一些则被称为安全组,但它们实际上是同一种设备,都是系统的外部防火墙。

防火墙可以被视为一道门。设想一下,你将财物存放在你的房间里,此时有一个窃贼想要盗取你的财物。首先,窃贼需要通过你家的大门——这就是外置防火墙(也被称为安全组或防火墙)。然后,他们需要进入你的房间——这就是内置防火墙(例如iptables或firewalld)。

方式二

指定映射端口监听地址为本机

对于部署的项目只需要本地访问,不需要向外暴露端口的服务,在进行项目端口映射的时候指定监听地址为 127.0.0.1

# 创建、映射端口、运行容器
docker run -d --name=demo -p 127.0.0.1:8838:8848 demo

部署的项目启动后,外界无法访问到 8838 端口,即使外置防火墙放行了该端口