解决 IPv6 在路由器重新拨号后无法正常使用

2022-01-17 586点热度 0条评论

IPv6 想必大家并不陌生,就算你没有使用过,也肯定听说过。它有诸多新特性和优点,最大的优点莫过于地址池数量巨大,多到给地球上没一粒沙子分配一个地址都用不完。

但它同样也有缺点,现在国内运营商分配的 IPv6 地址都是随机的,每次拨号后都会改变,这一点本质上不算缺点,但是到了每个设备这里就不一样了。

因为运营商下发的是 IPv6 前缀,然后路由器在收到 DHCP 请求后根据这个前缀为每个设备下发唯一的 IPv6 地址,看起来似乎没什么问题,但是当路由器重新拨号后,事情就复杂了。由于 DHCP 并不支持通知客户端地址过期,所以当路由器重新拨号后,IPv6 前缀被改变,设备之前通过 DHCP 获取的 IPv6 地址也会随即失效,这样就有可能导致客户端的 IPv6 网络无法正常使用。

那为什么说是有可能呢,因为如果是实现完整的客户端,且 DHCP 服务器允许无状态+有状态地址获取,DHCP 获取 IPv6 地址时会获取到两个地址,分别是隐私地址和公共地址,公共地址是 DHCP 服务器根据 IPv6 地址前缀 + MAC 地址生成,而隐私地址则是随机生成的。问题就在于系统如何处理地址使用,Windows 默认使用隐私地址且在路由器重新拨号并下发新的地址后能正常使用;Linux 的 NetworkManager 默认使用公共地址,但是在路由器下发新的地址后并不会使用新的公共地址,但是如果将其设置为隐私地址优先,它就会使用新的地址。

虽然这是个不大不小的问题,毕竟路由器重新拨号间隔一般在24小时以上,期间大部分设备肯定会重启或者是重新联网一次,而且解决方案看似也很简单,只要让 NetworkManager 优先使用隐私地址就好了。

但如果是需要每时每刻都使用 IPv6 网络的设备呢,比如下载机,旁路由,这些设备可能需要实时维持 IPv6 网络的连接,所以最好的解决方案是让路由器拨号后,主动的向某些设备发送重新配置网络的请求,这样他们就可以在第一时间获取最新的 IPv6 地址了。

下面说一下我是如何解决这个问题的

我的路由器运行的是 OpenWrt,所以在重新拨号后运行事件脚本很简单,只需要在/etc/hotplug.d/iface/目录下创建一个脚本文件就行了,文件内容如下所示。

#!/bin/sh
# /etc/hotplug.d/iface/99-restart-device-network

[ "$INTERFACE" = wan_6 ] && [ "$ACTION" = ifup ] && {
  # 重置设备网络命令
}

因为 OpenWrt 重新拨号时,接口会先关闭,然后再启用,我们只需要检查 wan_6 接口是否被启用就行了。

至于如何通知设备重启网络,有多种方法,比如直接使用 SSH 执行命令,而我使用的是 shell2http 这个工具,这个工具通过 http 请求执行 shell 命令,这样只需要发送一个 http 请求就可以执行对应的 shell 命令。

这样配置好之后,就再也不需要担心设备的 IPv6 网络会挂掉了。

如果你的路由器使用的是非 OpenWrt 系统,也可以使用类似的方法解决问题。


如果有其他的问题,欢迎加入 QQ 群 与我交流。

微信公众号二维码

微信扫描二维码关注我们

如果觉得文章有帮助到你,可以点击下方的打赏按钮赞助下服务器费用。

小山

一个什么都不会但要装作很厉害的人

文章评论

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据