IPv6 分支前缀:服务器上该用 iroute-ipv6 还是 route-ipv6?
route-ipv6 把前缀送进服务器内核;iroute-ipv6 指明承载该前缀的客户端。两者都属于终止该客户端的服务器。
两个名字几乎相同的指令会出现在每个能正常工作的示例里,只抄其中一个就会做出一个看似正确、却悄悄丢弃分支前缀的隧道。它们在同一个边界的两个方向上做不同的事:一个告诉服务器内核前缀在哪里,另一个告诉 OpenVPN 哪个已认证客户端承载它。两者都对了,前缀才能流通;只对了一个,数据包有路由却没有归属。
两条指令,两件不同的事
route-ipv6 是普通的装路由:服务器添加一条内核路由,把前缀指向它的隧道接口。iroute-ipv6 属于针对客户端的上下文,声明内部归属,于是守护进程知道该前缀的流量应当发给某个特定客户端,而不是内核路由碰巧点名的任意对端。
一个关乎内核的转发表,另一个关乎守护进程的内部路由模型。把两者分开,就能解释为什么一个看起来完整的配置仍会丢弃前缀。它也能解释为什么同一个网络在每个能工作的示例里出现两次。哪一行都不多余。
在传统的用户态方案里两者都需要,而且互相补充。只有内核路由,守护进程就选不出对端。只有 iroute,内核就没有通往隧道的路。针对每个客户端的文件的困惑也大多来自这里:文件不是路由表条目,路由条目也不是归属声明。
ip -6 route show | grep fd00:7a
ip -6 route get fd00:7a::1各自该放在哪里
路由放在服务器受管配置里,对那个服务器进程生效。iroute 放在以分支设备的已认证身份命名的客户端专属文件里。
与生效身份不匹配的文件名永远不会被读取,症状与缺少 iroute 完全相同。先核对服务器认证的身份,再逐字符核对文件名。
# /etc/openvpn/server/server.conf
route-ipv6 fd00:7a::/64
client-config-dir /etc/openvpn/server/ccd
# /etc/openvpn/server/ccd/branch-b
iroute-ipv6 fd00:7a::/64把地址池和分支前缀分开,因为二者重叠会造成任何指令都解不开的难题。
另一个客户端需要什么
应当访问该分支的第二个客户端需要的是通告,而不是归属。在适合你配置的客户端或组上下文里,把前缀推送给你要给的那些客户端。
不要把它发给分支本身,因为该设备已经把该前缀当作直连网络。
发给所有人是一个有后果的选择:这么一来每个客户端都相信可以经隧道访问该分支,包括你从未打算授予该访问权的客户端。通告在实践中就是访问决策,尽管该指令看起来像管道工程。服务器选项参考把 iroute-ipv6 记录为客户端专属归属,这才是值得保留的区别。
分支设备上的回程路径
只有在分支转发数据包、且其 LAN 知道如何应答时,归属才有用。在分支设备上启用 IPv6 转发,并确认其 LAN 上的主机把发往 VPN 地址池的流量送回分支,而不是送往不认识该地址池的默认路由。
那条回程路径就是 人们用 IPv4 时遇到的缺失路由问题的 IPv6 对应物。
要在 LAN 主机上查询 VPN 地址池地址来检查,而不是在分支本身检查。在路由器上做的查询回答的是另一个问题,与用户实际问的问题不同,而两者常常不一致,值得多敲一条命令。
当这一对仍然不够时
有些部署根本不用这条路径。内核数据路径和产品托管的服务器各有自己受支持的路由处理方式,用户态示例未必能直接照搬。
在照抄为另一条路径写的教程之前,先确认你的构建用的是哪条数据路径。
最后,记住地址范围:像 fd00:7a::/64 这样的唯一本地前缀按设计就是私有的,与公网 IPv6 可达性无关。把它当作内部访问,并把互联网出口当作另一个有独立策略的问题。