【问题标题】:Block external access to docker containers [closed]阻止对 docker 容器的外部访问 [关闭]
【发布时间】:2017-04-23 14:11:43
【问题描述】:

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

我需要创建哪些规则来阻止直接访问?

【问题讨论】:

  • 您是否正在测试来自外部机器的连接?否则,主机上的本地路由表将根据设计将您直接连接到容器网络。见netstat -nr
  • 是的。我正在互联网上的另一台机器上进行测试。

标签: docker iptables centos7


【解决方案1】:

除了@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

仅这个细节我就花了一段时间才弄清楚,我没有看到其他地方提到过。

【讨论】:

    【解决方案2】:

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

    对我来说的主要问题(当我尝试解决 @dpg 的答案的问题时)是 Docker 文档在解决此问题的两个页面中令人困惑(@987654321 @和link2)

    总结一下,也为别人节省时间,如果你知识不多,落入“Docker and iptables”,答案就在那里,只是他们有错过了:where ext_if is the name of the interface providing external connectivity to the host.

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

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

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

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

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

    【讨论】:

      【解决方案3】:

      我意识到我正在回复一个旧帖子,但我已经花了一个上午的大部分时间对这个问题感到沮丧。这篇文章显示在谷歌搜索的顶部,但我觉得接受的答案并没有回答 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 删除”

      "如果你需要添加在 Docker 规则之前加载的规则,请将它们添加到 DOCKER-USER 链中。"

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

      【讨论】:

        【解决方案4】:

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

        例如如果

        • 我有一个名为 my-service 的容器 A 和一个在端口 3000 上运行的服务,并且没有向主机发布端口
        • 容器 B,它是在端口 80 上运行的代理发布到主机。我的代理可以将请求传递给http://my-service:3000,它会将流量路由到容器。
        • 如果我尝试转到 http://mydomain:3000,这将不起作用,因为端口尚未公开,访问应用程序的唯一方法是通过端口 80 上的代理

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

        完全披露:我在我的个人 VPS 上运行这种设置,无法直接通过端口访问我的容器。使用内置的 docker 网络可能会比弄乱你的 IP 表更好

        希望这是有用的。

        迪伦

        编辑

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

        【讨论】:

        • 我猜你的解决方案只有在 haproxy 也在 docker 容器内运行时才有效?
        • 是的,我想这可能不适合您?我喜欢这种方法,因为它使应用程序/服务升级更容易,并为您提供额外的安全性,而无需弄乱操作系统防火墙
        • 我会试一试的。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-01-26
        • 1970-01-01
        • 1970-01-01
        • 2019-09-03
        • 2013-01-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多