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

dzh*_*zhi 6 linux iptables linux-networking docker docker-compose

我有带 Docker 的 Ubuntu 服务器来为 MySQL 和 SSH/SFTP 提供服务,我需要对除330622之外的所有端口进行防火墙设置,这是非常标准和微不足道的要求,对吧?

现在,我设法找到了一种解决方案,但在应用它之后,它对我来说并不完全有效,要么:

  1. 我无法访问任何提到的服务(默认情况下)
  2. 我无法从容器内访问互联网(如果我放入iptables: falseDocker 的daemon.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
Run Code Online (Sandbox Code Playgroud)

编辑: 我发现允许 Docker 管理 iptables 规则是推荐的并且要求不高,至少从长远来看是可以的,即使我没有以我喜欢的方式打开所需的端口,它仍然可以有效的。此时我想要的是找出是否可以使用 iptables 来阻止 Docker 打开的端口以及如何(通过 mangle 预路由?)。有什么建议?万分感谢!

BMi*_*tch 5

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

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
Run Code Online (Sandbox Code Playgroud)

来自以下文档: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
Run Code Online (Sandbox Code Playgroud)

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

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