IPv6 在 OpenVPN 重启的那一刻就停止转发流量,而 IPv4 仍在工作。隧道接口被重建,另一个管理其 IPv6 状态的组件要么丢了地址,要么丢了让前缀可达的路由。这里涉及三份彼此独立的状态,各自有不同的负责人:运营商委派的前缀及其有效期、下发给 VPN 客户端的地址,以及把该客户端前缀送回服务器的上游路由。在动任何守护进程之前,先确认每一份状态归谁管,因为重启错的那一个只会把问题藏一天,并在下次连接时原样返回。

三份 IPv6 状态,三个负责人

StateTypical ownerWhat breaks when it is wrong
Delegated prefix and lifetimeUpstream router or provider via DHCPv6-PDClients keep addresses that the upstream no longer routes
Client addresses inside the tunnelOpenVPN server config or a delegation daemonNo global address, or an address outside the routed prefix
Return route for the client prefixUpstream router, or the server's own routing tableOutbound works, replies never arrive

隧道内拥有全局范围的地址本身并不够。上游路由器仍必须把该前缀送回 VPN 服务器,而它们不会因为服务器恰好持有其中一个地址就这么做。

这也是把公网 /64 复制进隧道地址池的风险所在。路由到服务器的前缀,与上游视为 on-link 的前缀并不是一回事,邻居发现也无法填补这个缺口。

改动之前先读取服务器状态

在 IPv6 正常时和重启之后各采集一次状态,然后对比。只读视图就够了,在维护窗口里也不产生任何开销:

ip -6 addr show
ip -6 route show table all
ip -6 rule show
sysctl net.ipv6.conf.all.forwarding

重点看三类差异:某条路由消失了、某个地址转入了已弃用或无效的生命周期,以及某个前缀在前缀重新委派后发生变化,而 VPN 配置仍在通告旧前缀。

如果地址消失但前缀没变,说明负责分配地址的守护进程已不再管理该接口。如果前缀变了而地址没变,说明客户端配置已过期。这两种故障从浏览器看完全一样,却毫无共同点。

决定是否让 dhcpcd 管理这条隧道

dhcpcd 能发现接口,并把 DHCPv6 前缀的一部分委派给下游接口,其配置还可以显式指定委派目标。若没有明确目标,其文档所述行为可能波及其它接口,隧道也就这样拿到了一个没人规划过的地址。

有两种情况应让你把隧道的静态地址交给 OpenVPN:服务器在配置中推送固定地址,且重连时隧道名称会变。两者都成立时,就特意把该隧道排除在委派守护进程之外,并写清原因。

如果反过来,向隧道委派是有意为之,那就实现前缀变更的处理。这意味着在前缀或其有效期变化时做出反应、更新服务器通告的客户端前缀,并重新加回路由。在这种设计里排除该接口,恰恰去掉了唯一知道新前缀的组件。

重启 dhcpcd 看似能修好,因为它会重建状态,但它同时会续订或撤销你没想到的接口配置。这种恢复方式并不构成每次重启 VPN 之后的必备步骤。它还会把你当作证据的计数器清零。更好的做法是对你真正改过的接口做定向重载。

把 IPv6 与 IPv4 NAT 分开验证

先确认转发已开启、上游路由确实指向客户端前缀,再做一次新的、被放行的 IPv6 连接。同时检查客户端自己的 IPv6 路由表,因为客户端显示出公网地址,并不能证明它的请求走了隧道。

IPv4 伪装解决的是另一个问题:私有来源的回程路径。它对已被撤销的 IPv6 前缀毫无作用,加上它也不会让 IPv6 恢复。

最后留下责任记录:谁委派前缀、谁分配客户端地址、谁持有回程路由,以及重连时各自会发生什么。运维手册里的四行字,能让下一个人不必重启三个守护进程才找到真正关键的那一个。

相关文章