几天前才意识到Docker似乎绕过了我的iptable规则。我对Docker和iptables并不感到不可思议。最近几天尝试了很多不同的事情。还看到最近的docker版本有了很大的变化,带有特殊的DOCKER链,应该可以让我做到这一点。但是不确定我做错了什么,但是却从不做我期望做的事情。
所以我想要的很简单。我希望它的行为像预期的那样。如果我有一个ACCEPT-Rule要通过,如果没有,它将被阻止。
我的iptable最初看起来是这样的(因此,在我多次尝试失败之前):
*filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [779:162776] -A INPUT -i lo -j ACCEPT -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT -A INPUT -s 1.2.3.4 -p tcp -m tcp --dport 123 -j ACCEPT -A INPUT -j DROP COMMIT
希望它确实符合我的要求。只需允许访问端口22和80,还允许从ip 1.2.3.4访问端口123。但是,如果我用“ -p 123:123”创建一个容器,则每个人都可以访问它。有人可以帮助我,告诉我如何更改上述文件吗?
谢谢!
Docker版本:1.6.2
最初,我做了其他尝试,以确保问题不会过于复杂。但是,添加至少其中之一可能会有所帮助。
*nat :PREROUTING ACCEPT [319:17164] :INPUT ACCEPT [8:436] :OUTPUT ACCEPT [0:0] :POSTROUTING ACCEPT [16:960] :DOCKER - [0:0] COMMIT *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [779:162776] :DOCKER - [0:0] -A INPUT -i lo -j ACCEPT -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT -A DOCKER -s 1.2.3.4 -p tcp -m tcp --dport 123 -j ACCEPT -A DOCKER -j DROP -A INPUT -j DROP COMMIT
以上的作品。但是,那么会遇到很多其他问题。例如,我是否在容器链接方面遇到问题,DNS无法正常工作等等。因此,最后要添加许多其他规则来解决该问题,但是我永远都无法进入运行正常的状态。因此,我想这里会有更好更好的解决方案。
最终或多或少地准确地做出了幼虫所说的话。只是没有将其添加到FORWARD链中,而是将其添加到了DOCKER链中。FORWARD链的问题在于Docker在第一位置重新启动时会在其中添加其内容。这导致我的规则被下推并且没有任何效果。但是对于DOCKER链,似乎Docker仅附加了其他规则,因此我的规则仍然有效。因此,当我保存规则然后重新启动服务器时,一切仍然正常。
所以现在看起来或多或少是这样的:
*filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [779:162776] :DOCKER - [0:0] # That I can access from IP 1.2.3.4 -A DOCKER -s 1.2.3.4/32 -p tcp -m tcp --dport 123 -j ACCEPT # That I can access from other Docker containers -A DOCKER -o docker0 -p tcp -m tcp --dport 123 -j ACCEPT # Does not allow it for anything else -A DOCKER -p tcp --dport 123 -j DROP -A INPUT -i lo -j ACCEPT -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT -A INPUT -p tcp -m tcp --dport 80 -j ACCEPT -A INPUT -j DROP COMMIT
您的iptables配置现在看起来有些破损,就像您在不重新启动Docker的情况下将其清除了一样。例如,和表中都有一条DOCKER链,但是没有引用它的规则,因此放在该链中的规则将不起作用。filter``nat
DOCKER
filter``nat
通常,如果要实现影响Docker容器的iptables规则,则需要将它们放在FORWARD表链中filter。每个容器都有其 自己的 IP地址,这意味着您的主机仅接受数据包,然后将FORWARD其发送到容器地址。
FORWARD
filter
INPUT链中的规则仅适用于主机全局网络名称空间中接口的最终目的地为地址的数据包。
INPUT
但是,我不确定iptables实际上是您的问题。
如果您试图公开容器中的服务,以使其他系统可以使用它们,则需要使用-p标记来发布这些端口docker run。您可以在文档的此部分中阅读有关此内容的更多信息。
-p
docker run
如果您想使用要完成的任务的特定示例来更新您的问题,我可以提供更有针对性的答案。
更新资料
的确,当您使用发布容器端口时,-p它通常可用于任何源ip地址。为了限制对已发布端口的访问,您需要向FORWARD链中添加新规则。例如,如果我启动Web服务器:
docker run --name web -p 80:8080 larsks/mini-httpd
容器中的Web服务器现在可以在主机上的端口8080上使用。如果要阻止对该端口的访问,则需要在该FORWARD链中插入一条规则,以阻止对容器ip上的端口80的访问。所以首先我需要容器的IP地址:
$ web_ip=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' web) $ echo $web_ip 172.17.0.5
我在FORWARD链中创建的规则必须位于docker创建的规则 之前 ,因此我需要指定一个明确的位置:
iptables -I FORWARD 1 -d $web_ip -p tcp --dport 80 \! -s 192.168.1.10 -j DROP
这将阻止来自192.168.1.10以外的主机的所有流量。
如果您希望规则适用于所有容器而不是特定容器,则可以将其绑定到docker0接口而不是特定的IP地址:
docker0
-A FORWARD -o docker0 -p tcp --dport 80 \! -s 192.168.1.10 -j DROP
这将禁止访问 任何 容器上的端口80 。