阻止对docker容器的外部访问

时间:2016-12-08 10:54:27

标签: docker iptables centos7

我想阻止从外部直接访问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

我需要制定哪些规则才能阻止直接访问?

4 个答案:

答案 0 :(得分:1)

您可以使用docker network create NETWORK命令创建网络,将您的应用与代理连接起来,而不是使用IP表执行此操作。也不要在任何端口上公开应用程序。您应该公开的唯一容器是您的代理。然后,您可以在代理中使用容器名称作为主机名来路由流量。其他容器可以访问同一网络上的每个容器。

例如,如果

  • 我的容器A名称为my-service,服务在端口3000上运行,没有端口发布到主机
  • 容器B是在端口80上运行的代理发布到主机。我的代理可以将请求传递给http://my-service:3000,它会将流量路由到容器。
  • 如果我尝试转到http://mydomain:3000,这将无法正常工作,因为端口尚未公开,而且只有通过端口80上的代理才能到达应用程序

我建议您阅读https://docs.docker.com/engine/userguide/networking/work-with-networks/,因为这解释了如何开始使用网络。

完全披露:我在个人VPS上运行此类设置,无法直接通过端口访问我的容器。使用内置的docker网络可能比使用IP表更好地发挥作用

希望这很有用。

迪伦

修改

我已经概括了这个过程,因为我不知道你的设置在代理,网络限制等方面的具体细节。我也没有进入具体的命令,因为上面的链接比我更好地覆盖它。

答案 1 :(得分:1)

我意识到我正在响应旧的主题,但是整个上午的大部分时间我都对这个问题感到沮丧。这篇文章显示在google搜索的顶部,但是我认为被接受的答案不能回答OP的问题,而是提供一种不同的设计来避免原始问题中所述的问题。该解决方案需要站起来一个新的Docker映像,以充当原始Docker的网关。

在最初提出问题时,以下信息可能不可用,但是我从Docker.com找到的是此链接 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”

“如果您需要添加在Docker规则之前加载的规则,请将其添加到DOCKER-USER链中。”

但遗憾的是,我尝试了该解决方案,但它似乎也不适用于Docker 17.05.0-ce版

答案 2 :(得分:1)

通过@ Ezarate11添加评论(由于我没有足够的评论代表),请确保--dport是正被转发至的端口,而不是已公开的端口。< / p>

例如,如果您的配置为0.0.0.0:64743-> 80 ,则您需要这样做

sudo iptables -I DOCKER-USER -p tcp -i eth0 ! -s 192.27.27.90 --dport 80 -j REJECT

仅此一个细节就花了我一段时间,但我在其他任何地方都没有看到这一点。

答案 3 :(得分:0)

@dpg 指出,如果您需要从新手的角度来解决这个问题,那么这个问题将令人沮丧。

对我来说,主要的问题(我也尝试解决 @dpg 的问题)是Docker文档在解决此问题的两个页面中令人困惑({{ 3}}和link1

总结一下,并为其他人节省时间,如果您没有很多知识,而陷入“ Docker and iptables” 中,答案就在那里,只是他们有错过了这个:where ext_if is the name of the interface providing external connectivity to the host.

相反,在“了解容器通信” 链接中,确实确实有一个小文本,确切地指出ext_if应该是网络接口。

因此,对我来说,将对docker暴露端口(例如:6782)​​的访问限制为某个IP(例如:192.27.27.90)(这意味着DOCKER-USER需要修改,而不是公共INPUT链)。 )并限制所有其他内容,我需要这样做,可以在我的情况下起作用

sudo iptables -I DOCKER-USER -p tcp -i eth0 ! -s 192.27.27.90 --dport 6782 -j REJECT

(这里我假设与外界通信的网络接口是eth0,而您想使用REJECT而不是DROP)。

如果需要更多说明,我将很乐意为您提供帮助。