禁止〖 IP + 端口 〗访问〖 Docker 〗〖 汇总版 〗

概况

分为以下几种情形。第一种,使用 host 网络模式,则直接通过 iptables INPUT 规则即可限制,缺点很明显,容器越来越多,则必然端口冲突。第二种,服务器厂家自带外置防火墙,例如 linode 防火墙,可以直接定义端口的规则,可以无视容器规则带来的控制问题,缺点的话,不是每一个厂家都提供这种服务。第三种,直接不暴露端口,改用 Nginx 容器所在网络,必须反代使用,缺点几乎没有,非常特殊的需求下会有冲突,例如这几天鼓捣的最终目的就是把反代迁移出去,因为 44380 端口需要让位给 X-UI 使用。第四种,使用 bridge 网络模式,包括自定义 bridge 网络,需要定义 iptables DOCKER-USER 规则,特别重要的是屏蔽端口不能是映射到宿主的端口,必须是容器内部端口,这是核心关键点所在,还需要固定容器 IP 地址,不然的话多个容器同时存在时会开机打乱地址,而且开机自启动需要晚于系统创建 DOCKER-USER 规则链的时间,否则不生效,这一种可以说是最完美的方案,没有任何缺点,硬要说,也只有一点,就是必须手动创建规则,不过可以借助脚本,同时可以开机自动运行,因为每次重启,Docker 都会自动重新创建规则。大致无外乎就是这四种情形。第三种之前文章已经记录过,前两种不需要刻意记录,搜索即可看到大把教程。说是〖最终汇总版〗,其实重点就是记录最后一种情况的步骤,也算是这几天没有白忙活,翻遍各种网络教程,结合 ChatGPT 之助攻,感觉自己有所收获。下面开始记录,同时把 IPv6 一起涵盖记录。

第 1 步

由于把 IPv6 情形涵盖在内,首先部署 robbertkl/ipv6nat 容器,实现 IPv6NAT 转发功能,分配内部 IPv6 地址,创建自定义 Docker 网络,把容器加入到这个自定义网络中。同时需要定义固定的 IP 地址,包括 IPv4IPv6 两者。

第 2 步

创建规则脚本,并创建开机自启动服务,其中规则脚本开机自启动需要晚于系统创建 DOCKER-USER 规则链的时间,否则不生效。故需要定义脚本中循环等待检查的参数。另外 IPv4IPv6 需要分别定义。屏蔽端口不能是映射到宿主的端口,必须是容器内部端口,这是核心关键点所在。同样是不定义本地 IP 地址,但是,通过 iptables INPUT 规则限制的端口,就算是本地节点,亦不能访问,而,通过 iptables DOCKER-USER 规则限制的端口,外界无法访问,本地节点可以访问,这类似于 linode 商家的外置防火墙给我的感觉。

命令备忘

THE END