刚刚意识到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
Run Code Online (Sandbox Code Playgroud)
希望它完全符合我的要求.只允许访问端口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
Run Code Online (Sandbox Code Playgroud)
以上的作品.然而,还有很多其他问题.例如,我遇到容器链接问题,DNS不再工作,等等.因此,最后添加了许多额外的规则来解决这些问题,但我从未进入正常运行的状态.所以我想那里有更好更简单的解决方案.
结束或多或少做了什么larsks说.只是没有将它添加到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
Run Code Online (Sandbox Code Playgroud)
小智 7
我不是iptables的专家,但我知道如果你运行容器,-p 127.0.0.1:123:123那么端口将不会暴露在所有接口上,只是在环回上.
您的 iptables 配置现在看起来有点损坏,就好像您在某个时候清除了它而没有重新启动 Docker。例如,您DOCKER在filter和nat表中都有一条链,但没有引用它的规则,因此放置在该链中的规则不会产生任何影响。
一般来说,如果你想实现影响 Docker 容器的 iptables 规则,它们需要进入FORWARD表链filter。每个容器都有自己的IP 地址,这意味着您的主机只是接受数据包,然后FORWARD将它们发送到容器地址。
链中的规则INPUT仅适用于最终目的地为主机全局网络命名空间中的接口上的地址的数据包。
但是,我不确定 iptables 实际上是你的问题。
如果您尝试公开容器中的服务以便它们可供其他系统使用,则需要使用标记将这些端口发布-p到docker run。您可以在文档的本节中阅读更多相关信息。
如果您想用您想要完成的具体示例来更新您的问题,我可以提供更有针对性的答案。
更新
确实,当您使用它发布容器端口时,-p它通常可用于任何源 IP 地址。为了限制对已发布端口的访问,您需要向FORWARD链中添加新规则。例如,如果我启动一个网络服务器:
docker run --name web -p 80:8080 larsks/mini-httpd
Run Code Online (Sandbox Code Playgroud)
容器中的 Web 服务器现在可在我的主机上的端口 8080 上使用。如果我想阻止对此端口的访问,我需要在FORWARD链中插入一条规则来阻止对容器 IP 上的端口 80 的访问。所以首先我需要容器的 IP 地址:
$ web_ip=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' web)
$ echo $web_ip
172.17.0.5
Run Code Online (Sandbox Code Playgroud)
我在链中创建的规则FORWARD需要位于docker 创建的规则之前,因此我需要指定一个明确的位置:
iptables -I FORWARD 1 -d $web_ip -p tcp --dport 80 \! -s 192.168.1.10 -j DROP
Run Code Online (Sandbox Code Playgroud)
这将阻止来自 192.168.1.10 之外的主机的所有流量。
如果您希望规则应用于所有容器,而不是特定的容器,您可以将其绑定到docker0接口而不是特定的 IP 地址:
-A FORWARD -o docker0 -p tcp --dport 80 \! -s 192.168.1.10 -j DROP
Run Code Online (Sandbox Code Playgroud)
这将禁止访问任何容器上的端口 80。
| 归档时间: |
|
| 查看次数: |
6836 次 |
| 最近记录: |