最新的PaoPaoGateway版本支持了IPv6静态路由入站,但和IPv4不同,IPv6的静态路由有着更复杂的情况,因此这篇文章旨在帮需要使用IPv6静态路由的朋友们理清下条件和思路。

使用场景

PaoPaoGateway的IPv6静态路由适用于RealIP静态路由入站,但不包括FakeIP,因为IPv6的FakeIP没有意义,只会增加混乱,对于域名映射的作用都是一样的,FakeIP v4一样适用于AAAA记录的域名的访问,因此,以下讨论的是RealIP的IPv6静态路由,并且你的节点支持IPv6的落地,或者你的网关直连有IPv6的能力。不要求你的网络有IPv6公网地址,但有无公网地址的情况也有点不一样,后面的操作会讲到。 首先要解释IPv6的两种地址:GUA和ULA

GUA vs ULA 对比表

项目GUA (Global Unicast)ULA (Unique Local)
地址范围2000::/3fc00::/7
路由范围全球互联网仅限本地/私网
唯一性全球唯一本地唯一
类似 IPv4公网 IP私有 IP (10.0.0.0/8 等)
主要用途公网访问、对外服务内部通信、稳定标识
可共存是(设备通常同时拥有多个地址)

PaoPaoGateway提供了一个ula的定制选项,方便设置静态的ULA地址,后续静态路由均指向这个ULA地址。

使用条件

节点或者网关能访问对应IPv6网段是理所当然的前提,但内部网络有无IPv6公网地址是没有关系的,客户端和路由都有ULA地址即可。 但如果客户端有同时有公网的GUA地址,那么建议也给PaoPaoGateway也分配GUA地址,因为这会涉及回程路由 / 源地址不匹配的问题导致数据包有去无回。列一个表格来表示:

客户端 GUA客户端 ULAPP网关 GUAPP网关 ULA客户端发起源地址网关回源地址可达备注
GUAGUA常见内网有公网IPv6场景
ULAULA内网只有私网IPv6
ULAULA客户端有ULA即可
GUAULA客户端有GUA会自动使用GUA源,无法回程

回程路由 / 源地址不一致的问题需做NAT或客户端手动指定ULA源(不在本文讨论范围) 观察网关的流量记录可以看到,在客户端分别由GUA和ULA发起的请求的使用源IP也不一样。

配置实践

以最通用的OpenWrt路由器为例子,因为各种版本界面不一样,这里以命令行操作为准。 目标:以Cloudflare的IPv6 DNS测试地址为例,最终客户端可以直接执行curl "https://[2606:4700:4700::1111]/cdn-cgi/trace",并返回节点的IP信息。

首先,给内网分配全局的ULA地址段。 假设的接口名是LAN(有的常见是br-lan,我自己用的时候单独划分了一个vlan6接口,反正知道自己的局域网接口名就可以), 假设ULA地址段定为fd10:10:10::1/64,PP网关的地址定为fd10:10:10::3/64 执行:

1
2
3
4
5
6
7
# 给接口LAN添加一个ULA地址段
uci add_list network.LAN.ip6addr='fd10:10:10::1/64'
# 提交
uci commit network
# 查看配置,此时还未生效
uci show network.LAN6.ip6addr
network.LAN.ip6addr='fd10:10:10::1/64'

重启网络或者重启路由器,查看客户端设备被分配到了fd10:10:10::开头的地址即可。

定制PP网关的network.ini包含:

1
ula=fd10:10:10::3/64

注意,如果你的内网也包含公网IPv6的分配,也需要在network.ini里面给网关分配静态或者动态的IPv6地址,否则无法回源。 网关启动后,在客户端上ping fd10:10:10::3,看看是否可以ping通。

编辑/etc/config/network,在末尾增加IPv6的静态路由配置:

1
2
3
4
config route6
	option interface 'LAN'
	option target '2606:4700:4700::1111'
	option gateway 'fd10:10:10::3'

重启网络或者重启路由器,在客户端执行curl "https://[2606:4700:4700::1111]/cdn-cgi/trace",访问成功,并且在ip=一栏能看到节点的落地IPv6地址。 要注意,如果要使用udp协议,请确保你的节点支持并开启了udp相关配置。 测试udp,可直接查询DNS走udp 53(仅测试用途,实际不建议这么代理DNS):

1
dig www.google.com  @2606:4700:4700::1111