Docker 主机的正确 iptables 规则是什么?

Docker 主机的正确 iptables 规则是什么?

我有一台装有 Docker 的 Ubuntu 服务器,用于提供 MySQL 和 SSH/SFTP 服务,我需要除以下端口之外的所有端口:330622设置防火墙,这是一个非常标准和简单的要求,对吧?

现在,我设法找到了一个某种解决方案但它对我来说并没有完全发挥作用,因为应用它之后,要么:

  1. 我无法访问任何提到的服务(默认情况下)
  2. 我无法从容器内访问互联网(如果我将iptables: falseDocker 的守护进程.json配置文件)

我尝试了许多其他搜索结果,但它们大多非常复杂,我不明白它们在做什么,或者它们的脚本太多,使得我这个 iptables 门外汉无法从中获得任何东西。

提出的解决方案看起来相当简单且易于理解,但整个 Docker 网络的复杂性使其调试变得更加困难。

有人可以分享他们针对 Docker 主机的工作 iptables 规则吗,或者至少为我指明正确的方向?

我使用 docker-compose 来启动服务,这是我的 yaml:

version: '3.7'

services:
  mysql:
    container_name: 'mysql'
    image: mysql:8.0.13
    command: --default-authentication-plugin=mysql_native_password
    user: 1000:1000
    ports:
      - "3306:3306"
    volumes:
      - ./data:/var/lib/mysql
      - ./config/custom.cnf:/etc/mysql/conf.d/custom.cnf
    networks:
      - database
    restart: always

networks:
  database:
    driver: bridge

编辑: 我发现,至少从长远来看,允许 Docker 管理 iptables 规则是推荐的,而且要求不高,让 Docker 打开所需的端口是可以的,尽管我没有按照自己喜欢的方式这样做,但它仍然有效。我现在想要知道是否可以使用 iptables 来阻止 Docker 打开的端口以及如何阻止(也许通过 mangle 预路由?)。有什么建议吗?非常感谢!

答案1

我无法从容器内访问互联网(如果我在 Docker 的 daemon.json 配置文件中输入 iptables: false)

Docker 依靠 iptables 来配置其网络。这包括用于处理外部网络访问的 NAT 规则,以及用于配置容器在 docker 网络上相互访问的许多其他规则。默认情况下,此访问是开放的,但在创建网络时可以选择限制外部访问和容器间通信。因此,我不建议iptables在 docker 中将选项设置为 false,因为正如您所见,这会破坏所有这些功能。

在主机上发布端口会隐式允许外部访问。因此,避免外部访问的最简单方法是不发布端口。您可以将端口发布到特定接口上,例如,127.0.0.1:8080:80在主机的环回接口 ( 127.0.0.1) 上发布端口 8080 以连接到容器的端口 80,并且该环回接口不可从外部访问。但是,如果无法将端口保持未发布状态,则可以使用 iptables 来实现。

我现在想要知道是否可以使用 iptables 来阻止 Docker 打开的端口以及如何

这可以通过修改过滤器链来实现DOCKER-USER。你可以找到这样的例子,例如:

$ iptables -I DOCKER-USER -i ext_if ! -s 192.168.1.0/24 -j DROP

来自以下文档:https://docs.docker.com/network/iptables/

请注意,端口是由在过滤规则之前运行的一些修改规则所改变的,因此如果您想按端口进行过滤,则需要使用 conntrack 来获取原始目标端口:

$ iptables -I DOCKER-USER -i eth0 -p tcp \
    -m conntrack --ctorigdstport 8080 -j DROP
$ iptables -I DOCKER-USER -i eth0 -s 10.0.0.0/24 -p tcp \
    -m conntrack --ctorigdstport 8080 -j ACCEPT

请注意,DOCKER-USER 中有一个默认规则是接受所有内容,因此您需要将规则插入到链的顶部(-I),而不是附加到末尾(-A)。

看:使用 iptables 限制与 docker 容器的外部连接的步骤?

答案2

此时我想要的是找出是否可以使用 iptables 来阻止 Docker 打开的端口以及如何阻止(也许通过 mangle 预路由?)。

经过大量的研究和测试,我发现只公开你想要的端口而不公开docker端口的最好(也是最简单)的方法是将IP设置为docker-compose.yml127.0.0.1(只公开给主机)

ports:
  - "127.0.0.1:3306:3306"

然后您可以使用 nginx 或任何其他反向代理来向外部公开。

这边走:

相关内容