Docker:限制访问某些 IP 地址的正确方法

Docker:限制访问某些 IP 地址的正确方法

我有一个 Docker 容器,将端口 3306 暴露给互联网。我想限制对某些公共 IP 地址的访问。作为示例,我们使用 1.2.3.4。

作为附加条件,我希望规则在重新启动 Docker 守护程序和重新启动服务器后仍然有效。这样我就可以在服务器重新启动时使用iptables-persistent( iptables-save/ iptables-restore) 来恢复规则,而不会让dockerd启动干扰它。

我尝试了以下操作:

  1. 修改FORWARD链条:

    iptables -I FORWARD -p tcp --dport 3306 -j REJECT
    iptables -I FORWARD -p tcp --dport 3306 -s 1.2.3.4 -j ACCEPT
    

    在启动 Docker 守护进程后完成此操作即可。重新启动守护进程时,Docker 会在链顶部插入其他规则,而我的自定义规则最终会被忽略。

  2. 修改DOCKER链条:

    iptables -N DOCKER # if chain does not yet exist
    iptables -I DOCKER -p tcp --dport 3306 -j REJECT
    iptables -I DOCKER -p tcp --dport 3306 -s 1.2.3.4 -j ACCEPT
    

    直到重新启动后,此方法才有效dockerd。重新启动后,链似乎dockerd被清除DOCKER,所有自定义规则都消失了。

  3. 使用--iptables=false。虽然理论上可行,但该解决方案破坏了标准 Docker 转发功能,需要手动设置转发规则。

如果没有合适的方法来实现这一点,我会感到惊讶。有什么想法吗?

PS:我读了一些资料,但无济于事(例如使用 iptables 限制与 docker 容器的外部连接的步骤?Docker - 可从外部访问的暴露端口 - 忽略 iptables 规则,但这些问题似乎与重启问题无关。)

答案1

我已经发现https://serverfault.com/a/933803/592497最有价值的信息是能够在内部网络中公开某些端口,但阻止外部端口。例如数据库容器。

主要的是您必须使用 DOCKER-USER 链,因为它不会被 Docker 覆盖。

这也将解决您的问题,使这些规则在重新启动或服务重启后仍然有效。

答案2

dockersd可以使用以下选项运行:

--iptables=false

如果不是手动运行而是作为服务使用,则只需在配置文件中添加或修改以下行即可/etc/docker/daemon.json

“iptables”:false,

可以找到更详细的文档这里

答案3

我非常希望尽可能多的服务通过我的 nginx 进行路由,以便能够进行内部测试,轻松关闭外部访问和日志记录。由于 nginx 也是任何 TCP 连接的完美代理,因此对我来说唯一没有通过 nginx 隧道传输的服务是我的 sshd。

本文档描述了如何在多个 MySQL 接收器之间进行负载平衡,但您的情况下最基本的配置应该简单如下:

stream {
    server {
        listen 3306;
        allow  1.2.3.4;
        deny   all;
        proxy_pass 127.0.0.1:33061;
    }
}

可以提供更多细节和想法找到这里。您还可以添加日志记录和更多其他内容。

Docker 参数可能-p 127.0.0.1:33061:3306仅限于本地主机访问。

相关内容