在 Docker 中配置 IPV6 NAT
第 1 节 概述
由于公网 IP 的获取比较困难,本人的 NAS 上的各种 Docker 应用都是通过路由器的公网 IPV6 地址进行代理的,使用的是在 OpenWrt 上部署到一款名为 Lucky 的应用,Github项目地址, 这款应用聚合了端口转发、动态域名、自动证书等功能,一个应用就能解决将服务部署到公网的全部流程。
因为 Lucky 集成了 socat 的功能,可以进行 IPV6 到 IPV4 的端口转发,所以通常 NAS 上的应用只要能通过 IPV4 地址访问到就可以部署到公网。
但是这样会存在一个问题:
Docker 默认情况下不会配置 IPV6 功能,因而在 Docker 容器内无法通过域名(IPV6)去访问别的容器,只能使用本地的 IPV4 地址来访问。这样不方便,并且有的应用需要SSL或者设置了BaseURL,直接用 IPV4 地址访问可能会有问题。
不过,一直以来,本人并不知道 Docker 默认没有 IPV6 ,主要原因如下:
- 我在 OpenWrt 上安装了Clash,而 Clash 为了保证访问的私密性,配置了 FakeIP 功能。
- 我没有设置 FakeIP Filter,所以即便是本地网络之间的访问,地址也会被转成 FakeIP。
- 访问的 IPV6 地址也会被转成 FakeIP,并且 FakeIP 是保留 IP 段的 IPV4 地址。
- 路由器负责解析 FakeIP,并且 Lucky 将解析后的结果代理到了对应的 IPV4 地址。
所以,阴差阳错之下,本人一直在容器内正常使用着 IPV6 功能。

不过,也许是因为 Clash 时常可能访问不了,或者别的原因,容器内访问 IPV6 时常也会访问不了。并且用这种方式会增加通信之间的消耗,增加网络的复杂性,容易出现各种未知的问题,所以只好想办法来解决这一问题。
查看 OpenWrt 上的路由器网络,WAN6 IP 地址的掩码是 64 位的,这说明运营商只给我分配了这一个 IPV6 公网地址,我不可以通过前缀委派(Prefix Delegation,PD)给其他内网设备分配公网 IPV6 地址,所以从路由器开始,我的后续所有的设备的 IPV6 地址都只能通过网络地址转换(Network Address Translation,NAT)来分配。

本人的 Docker 容器基本全都是桥接的,于是解决这个问题有 3 个步骤:
- Nas 本身要配置 IPV6
- Docker 的虚拟网口和 NAS 之间要配置 NAT
- Docker 容器内要配置 IPV6 并且和 Docker 网口之间配置 NAT
在下文中,本人将依次讲述这些如何配置。
第 2 节 路由器网络
本人使用的是威联通的 NAS,登录 NAS 系统,来到控制台->网络与虚拟交换机->网络适配器,配置 IPV6 如下:

第 3 节 NAS 网络
通过 ssh 连接到 NAS,通过测试,威联通的 NAS 安装了iptables和ip6talbes,但是没有安装ip6tables_nat,所以不可以进行 IPV6 的 NAT。
Github 上有人编译了威联通的 ip6tables_nat 包,项目地址。去 release 里头下载modules.zip并解压得到ip6table_nat.ko即可。
通过 ssh 连接到 NAS,执行以下命令,将对应目录挂载到/tmp/config,具体参照网址:
|
|
在目录下新建文件autorun.sh,填入以下内容
|
|
将文件修改为可执行,并解除挂载:
|
|
登录 NAS 系统,来到控制台->硬件->常规,对应选项上打勾:

重启 NAS 或者手动执行autorun.sh中的内容。
在 Docker 中创建支持 IPV6 的网络:
|
|
NAT分为 SNAT 和 DNAT 两种:
- DNAT 修改目标 IP 地址,主要用来进行端口转发,将公网IP端口映射到内网IP端口
- SNAT 修改源 IP 地址,用来解决 IP 地址不足的问题,将内网IP端口修改为公网IP端口
这里要实现的目标不是通过内网的 IPV6 地址访问内网的服务,因为 Docker 原本就有 IPV4 的端口转发,更加简单好记。
所以,只考虑配置 SNAT,使得容器内访问 IPV6 地址,修改 IP 端口,变为 NAS 访问 IPV6 地址,进而交由路由器来处理,方法如下:
|
|
第 4 节 容器内部
Docker 在创建容器时,一般就自动创建好了容器内的防火墙和NAT规则,规则也比较简单,通常不需要进行任何设置就可以访问 NAS。
一个比较特殊的容器是 WireGuard,其内部可能存在多个网口,比如wg0、wg1、wg2等,需要配置相关的 NAT 规则,这种方式的目的是隔离多个网口,并且每个网口分别做防火墙,提供给不同的人使用。
Docker 部署方式如下:
|
|
需要在容器内使用 IPV6 时,需要添加的有:
|
|
其他项不是必备的配置,可以创建以后手动进行修改。
服务器端的配置如下:
|
|