阻止对 docker 个容器的外部访问
Block external access to docker containers
我想阻止从外部直接访问 docker 容器。我使用 haproxy 并希望只允许访问端口 80、443。
我在 iptables 中添加了以下规则。但是我仍然可以通过不同的端口访问 docker 个容器。
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
COMMIT
这可能是由于 DOCKER 链
# iptables -L
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT icmp -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:http
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:https
Chain FORWARD (policy ACCEPT)
target prot opt source destination
DOCKER-ISOLATION all -- anywhere anywhere
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain DOCKER (4 references)
target prot opt source destination
ACCEPT tcp -- anywhere 172.18.0.2 tcp dpt:http
Chain DOCKER-ISOLATION (1 references)
target prot opt source destination
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
RETURN all -- anywhere anywhere
我需要创建什么规则来阻止直接访问?
您可以使用 docker network create NETWORK
命令创建一个网络来连接您的应用程序和代理,而不是使用 IP 表来执行此操作。也不要在任何端口上公开应用程序。您应该公开的唯一容器是您的代理。然后,您可以从代理内部使用容器名称作为主机名来路由流量。同一网络上的每个容器都可以被其他容器访问。
例如如果
- 我有容器 A,其名称为
my-service
,服务 运行ning 在端口 3000 上 没有发布到主机的端口
- 作为代理的容器 B 运行在端口 80 上 发布到主机 。我的代理可以将请求传递给 http://my-service:3000 并将流量路由到容器。
- 如果我尝试转到 http://mydomain:3000 这将无法工作,因为端口尚未公开并且访问该应用程序的唯一方法是通过端口 80 上的代理
我建议阅读 https://docs.docker.com/engine/userguide/networking/work-with-networks/,因为它解释了如何开始使用网络。
完全披露:我 运行 这种个人设置 VPS 无法直接通过端口访问我的容器。使用内置的 docker 网络可能比乱用 IP 表更好
希望这有用。
迪伦
编辑
我已经概括了这个过程,因为我不知道你的设置在代理、网络限制等方面的细节。我也没有进入具体的命令,因为上面的 link 比我更好地涵盖了它会。
我知道我正在回复一个旧线程,但我花了一个上午的大部分时间来解决这个问题。这个 post 显示在 google 搜索的顶部,但我觉得接受的答案没有回答 OP 的问题,而是提供了一种不同的设计来避免原始问题中所述的问题.该解决方案需要建立一个新的 docker 图像作为通往原始 docker.
的门户
有可能以下信息在原问题出现时不可用,但我从 Docker.com 中找到的是 link
https://docs.docker.com/network/iptables/
它在声明时似乎回答了原始问题:
”
默认情况下,允许所有外部源 IP 连接到 Docker 守护进程。要仅允许特定 IP 或网络访问容器,请在 DOCKER 过滤器链的顶部插入一条否定规则。例如,以下规则限制外部访问除 192.168.1.1 以外的所有 IP 地址:
$ iptables -I DOCKER-USER -i ext_if ! -s 192.168.1.1 -j DROP
和
"If you need to add rules which load before Docker’s rules, add them to the DOCKER-USER chain."
但遗憾的是,我已经尝试过该解决方案,但在 docker 版本 17.05.0-ce
上它似乎也不适合我
正如 @dpg 指出的那样,如果您需要从新手的角度来解决这个问题,那将是令人沮丧的。
我的主要问题(因为我也试图解决 @dpg 的回答的问题),是 Docker 文档混淆了两个解决此问题的页面数 (link1 and link2)
总结一下,也为大家节省时间,如果你没有太多的知识,陷入"Docker and iptables",答案就在那里,只是他们错过了这个:where ext_if is the name of the interface providing external connectivity to the host.
相反,在 "Understand container communication" link 中,确实有一点文字指出 ext_if 应该是网络接口.
所以,对我来说,限制对 docker 公开端口(例如:6782)的访问(这意味着需要修改 DOCKER-USER 而不是公共 INPUT 链)到某些 IP(例如:192.27.27.90)并限制所有其他 IP,我需要这样做,在我的情况下有效:
sudo iptables -I DOCKER-USER -p tcp -i eth0 ! -s 192.27.27.90 --dport 6782 -j REJECT
(这里我假设与外界通信的网络接口是eth0
,你想REJECT
而不是DROP
)。
如果需要更多说明,我很乐意提供帮助。
除了@Ezarate11 的评论(因为我没有足够的代表发表评论),确保--dport 是转发到 的端口,而不是端口即暴露。
例如,如果您的配置是 0.0.0.0:64743->80,那么您需要执行
sudo iptables -I DOCKER-USER -p tcp -i eth0 ! -s 192.27.27.90 --dport 80 -j REJECT
光是这个细节我就花了一段时间才弄清楚,我没有在其他地方看到这个。
我想阻止从外部直接访问 docker 容器。我使用 haproxy 并希望只允许访问端口 80、443。
我在 iptables 中添加了以下规则。但是我仍然可以通过不同的端口访问 docker 个容器。
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
COMMIT
这可能是由于 DOCKER 链
# iptables -L
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT icmp -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:http
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:https
Chain FORWARD (policy ACCEPT)
target prot opt source destination
DOCKER-ISOLATION all -- anywhere anywhere
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain DOCKER (4 references)
target prot opt source destination
ACCEPT tcp -- anywhere 172.18.0.2 tcp dpt:http
Chain DOCKER-ISOLATION (1 references)
target prot opt source destination
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
RETURN all -- anywhere anywhere
我需要创建什么规则来阻止直接访问?
您可以使用 docker network create NETWORK
命令创建一个网络来连接您的应用程序和代理,而不是使用 IP 表来执行此操作。也不要在任何端口上公开应用程序。您应该公开的唯一容器是您的代理。然后,您可以从代理内部使用容器名称作为主机名来路由流量。同一网络上的每个容器都可以被其他容器访问。
例如如果
- 我有容器 A,其名称为
my-service
,服务 运行ning 在端口 3000 上 没有发布到主机的端口 - 作为代理的容器 B 运行在端口 80 上 发布到主机 。我的代理可以将请求传递给 http://my-service:3000 并将流量路由到容器。
- 如果我尝试转到 http://mydomain:3000 这将无法工作,因为端口尚未公开并且访问该应用程序的唯一方法是通过端口 80 上的代理
我建议阅读 https://docs.docker.com/engine/userguide/networking/work-with-networks/,因为它解释了如何开始使用网络。
完全披露:我 运行 这种个人设置 VPS 无法直接通过端口访问我的容器。使用内置的 docker 网络可能比乱用 IP 表更好
希望这有用。
迪伦
编辑
我已经概括了这个过程,因为我不知道你的设置在代理、网络限制等方面的细节。我也没有进入具体的命令,因为上面的 link 比我更好地涵盖了它会。
我知道我正在回复一个旧线程,但我花了一个上午的大部分时间来解决这个问题。这个 post 显示在 google 搜索的顶部,但我觉得接受的答案没有回答 OP 的问题,而是提供了一种不同的设计来避免原始问题中所述的问题.该解决方案需要建立一个新的 docker 图像作为通往原始 docker.
的门户有可能以下信息在原问题出现时不可用,但我从 Docker.com 中找到的是 link https://docs.docker.com/network/iptables/ 它在声明时似乎回答了原始问题:
” 默认情况下,允许所有外部源 IP 连接到 Docker 守护进程。要仅允许特定 IP 或网络访问容器,请在 DOCKER 过滤器链的顶部插入一条否定规则。例如,以下规则限制外部访问除 192.168.1.1 以外的所有 IP 地址:
$ iptables -I DOCKER-USER -i ext_if ! -s 192.168.1.1 -j DROP
和
"If you need to add rules which load before Docker’s rules, add them to the DOCKER-USER chain."
但遗憾的是,我已经尝试过该解决方案,但在 docker 版本 17.05.0-ce
上它似乎也不适合我正如 @dpg 指出的那样,如果您需要从新手的角度来解决这个问题,那将是令人沮丧的。
我的主要问题(因为我也试图解决 @dpg 的回答的问题),是 Docker 文档混淆了两个解决此问题的页面数 (link1 and link2)
总结一下,也为大家节省时间,如果你没有太多的知识,陷入"Docker and iptables",答案就在那里,只是他们错过了这个:where ext_if is the name of the interface providing external connectivity to the host.
相反,在 "Understand container communication" link 中,确实有一点文字指出 ext_if 应该是网络接口.
所以,对我来说,限制对 docker 公开端口(例如:6782)的访问(这意味着需要修改 DOCKER-USER 而不是公共 INPUT 链)到某些 IP(例如:192.27.27.90)并限制所有其他 IP,我需要这样做,在我的情况下有效:
sudo iptables -I DOCKER-USER -p tcp -i eth0 ! -s 192.27.27.90 --dport 6782 -j REJECT
(这里我假设与外界通信的网络接口是eth0
,你想REJECT
而不是DROP
)。
如果需要更多说明,我很乐意提供帮助。
除了@Ezarate11 的评论(因为我没有足够的代表发表评论),确保--dport 是转发到 的端口,而不是端口即暴露。
例如,如果您的配置是 0.0.0.0:64743->80,那么您需要执行
sudo iptables -I DOCKER-USER -p tcp -i eth0 ! -s 192.27.27.90 --dport 80 -j REJECT
光是这个细节我就花了一段时间才弄清楚,我没有在其他地方看到这个。