当前位置: 首页 > 面试题库 >

Docker在使用“ -p时会忽略iptable规则 :”

尉迟正平
2023-03-14
问题内容

几天前才意识到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容器的iptables规则,则需要将它们放在FORWARD表链中filter。每个容器都有其 自己的
IP地址,这意味着您的主机仅接受数据包,然后将FORWARD其发送到容器地址。

INPUT链中的规则仅适用于主机全局网络名称空间中接口的最终目的地为地址的数据包。

但是,我不确定iptables实际上是您的问题。

如果您试图公开容器中的服务,以使其他系统可以使用它们,则需要使用-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地址:

-A FORWARD -o docker0 -p tcp --dport 80 \! -s 192.168.1.10 -j DROP

这将禁止访问 任何 容器上的端口80 。



 类似资料:
  • 有什么办法能做到这一点吗? 谢谢!

  • 我刚刚将Intellij Idea的SonarLint插件更新为2.3.2版。Changelog表示,由于2.3版,连接模式下的规则排除应该可用。 下面是我的配置,似乎被更正了,然而,忽略的规则仍然弹出。

  • 我正在尝试初始化一个运行Postgres的容器,使用 属于此数据库系统的文件将由用户“Postgres”所有。该用户还必须拥有服务器进程。 数据库集群将使用区域设置“en_us.utf8”初始化。默认的数据库编码相应地被设置为“UTF8”。默认的文本搜索配置将设置为“English”。 数据页校验和被禁用。 我已经检查了文件权限 如何确定init脚本忽略备份的原因?

  • 问题内容: 我正在尝试使用Jenkins来编译用Delphi创建的MSBuild项目。我将MSBuild插件安装到Jenkins中并进行了配置。我正在为我的构建工作选择特定的配置。 我已经在Jenkins中设置了Delphi编译器所需的所有环境变量(对于您的Delphi类型,来自rsvars.bat)。 该项目可以在命令行上正常编译。如果我在命令行上执行此操作,则MSBuild会在命令行中报告一个

  • 问题内容: 假设您具有以下pyspark DataFrame: 接下来的两个代码块应该做同样的事情-即,如果不是,则返回该列的大写。但是,第二种方法(使用)会产生错误。 方法1 :使用 方法2 :在内部使用 这给了我。为什么调用中的检查似乎被忽略了? 我知道我可以改变我要避免这种错误,但我想知道为什么它的发生。 完整回溯 : 问题答案: 您必须记住,Spark SQL(与RDD不同)不是您所看到的

  • 问题内容: 举例来说: 将产生sql: 哪个是正确的。但是,在加载模型时,该属性将被忽略,因为它不是的属性。 它与渴望加载和相似,但是我不希望所有列,仅指定的列是不好的。 必须有一种简单的方法来从其他模型获取列吗?与简单数组/哈希相比,我最好让这些项作为的实例返回 问题答案: 当您使用或进行时,将返回。它仅由您用来调用的类的对象组成。从联接模型中选择的列将添加到返回的对象中。由于这些属性不是的属性