文章

记一次尝试在 Docker 上启用 IPv6 访问的顶级折磨

Last-Modified: 2025-02-07

系统环境: Debian 12, 1Panel 1.10.22-lts, Docker 27.4.1

严格的讲,这一篇应该是组网系列的一篇番外。

因为我的网络配置比较神秘,文内遇到的绝大多数问题应该不会困扰到你,但是如果你的网络也像我一样神秘,那你可以看下去了。

1 客观条件与需求

为了给自己用上妙妙 AdGuard Home,于是月初的时候就给闲置的宁波 800M 带宽服务器上装好了 AdGuard Home。DoH 用起来非常的美妙,但是很快问题就来了,安卓手机系统只支持 DoT。

DoT (DNS over TLS),是一种非常安全的 DNS 访问方式,它使用 853 端口进行通信,并有完善的鉴权机制,可以有效防止 DNS 抢答与污染(如果你的上游没被污染,并且也用了 DoT/DoH)。

しかし,国内的服务器很多屏蔽了 53/853 端口(比如说前日入手的物语云宁波 800M 大带宽服务器),导致 DoT 和普通的 DNS UDP 53 都处于无法使用的状态。但是懒得再装一次 AdGuard Home 了,于是决定利用之前申请的 ASN,分配一个 IPv6 段给宁波服务器,然后再分出一块给 Docker(对,AdGuard 跑在 Docker 里),Docker 自动分配一个 IPv6 IP 给 container,就能美美用上 DoT 了。

总结一下,大概就是这样:

  • 分配一段 /64 到宁波服务器

  • 给 Docker 配好 IPv6 地址段

  • 给 container 配好网络和路由

  • 开用!

2 地址段分配

有一说一,这段其实是最简单的。

之前已经配好了开箱即用的 Zerotier Network ↓

并且可以自动为每个设备分配一个 /128 地址。

宁波服务器上装好 zerotier-one,加入 Network,就能使用神秘的 IPv6 地址了。

至于路由,Zerotier 提供了自由度很高的 开放世界 Flow Rules 功能,写一条规则就能把你定义好的地址段路由到指定的设备。

试了。如果你的需求和我差不多,那可能会产生大大小小的问题,不要用这个。

建议用妙妙 Managed Routes 功能,非常好用。

给服务器分配了两段 IPv6 /64 块,不过我们这次只需要用一个 /80 就完全够用了,鉴于 IPv6 地址太多了,所以浪费一点也没事……吧?

3 嘻嘻 我要抄教程

进入 1Panel 一眼就看见了这个非常吸引眼球的 IPv6 按钮。

9E9AFEA2-5A86-4DBB-9138-FBB82B9EC20A.png

点击后,跟随 1Panel 的妙妙教程 一步一步走,然后把你想添加 IPv6 连通性的容器改到默认的 bridge 网络下,就可以上网了……吗?

答案是确实能上网了,但是 IP 是联不通一点的。

使用 tcpdump 发现,docker 实际上对整个网段做了一个 NAT,至于为什么……只能说不太理解为什么在公网网段上 NAT。

而如果跟着教程创建新的网络,再把容器放到新的网络上,结果也是差不多的。

说实话有点绝望了,跟着 Docker 官方教程 又走了一遍,结果连网都上不去了,这下真成低能了。

4 原来就这么简单吗

com.docker.network.bridge.gateway_mode_ipv6=routed

说实话,这篇文章写到这里多少是要虎头蛇尾了,因为解决方法真的很简单。

经过了一段时间的搜索,终于找到了这篇文档。Packet filtering and firewalls

如果创建网络时加上了上面的配置,那么容器对外请求时,主机就不会进行 NAT,而是直接把数据包中转到容器内。

至于端口映射,在 0.0.0.0/127.0.0.1 上映射的端口会正常的映射到 主机的对应端口,而在 :: 上映射的端口 并不会起作用,而是会让 Docker 放通 容器端口,大约就相当于是一个神秘安全组的作用了。

5 总结

再也不想配 Docker IPv6 了,感觉文档写的也很神秘……

当然我也是 Docker 菜鸡,若有问题希望大家多多指出。

根据配置不同,可能还需要配置 NDP 与 ndppd。