我有一个 Docker 容器,将端口 3306 暴露给互联网。我想限制对某些公共 IP 地址的访问。作为示例,我们使用 1.2.3.4。
作为附加条件,我希望规则在重新启动 Docker 守护程序和重新启动服务器后仍然有效。这样我就可以在服务器重新启动时使用iptables-persistent
( iptables-save
/ iptables-restore
) 来恢复规则,而不会让dockerd
启动干扰它。
我尝试了以下操作:
修改
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 会在链顶部插入其他规则,而我的自定义规则最终会被忽略。
修改
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
,所有自定义规则都消失了。使用
--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
仅限于本地主机访问。