假设 ISP 通过 DHCPv6-PD 给用户分配的 IPv6 前缀是2001:db8:1111::/48
,用户 LAN 口侧有三个设备,分别为网关、NAS 和监控摄像头。这三台设备拥有固定的 IPv6 后缀 ::1
、 ::dead
和::beef
(通过 Modified EUI-64 基于 MAC 地址生成或者 DHCPv6 等方式下发),因此分别会分到2001:db8:1111::1
、 2001:db8:1111::dead
和2001:db8:1111::beef
。
当用户与 ISP 的连接断开重新连接后,ISP 重新给用户下发新的前缀,比如是2001:db8:2222::/48
。这时候用户侧设备的地址会发生变更,分别变为2001:db8:2222::1
、 2001:db8:2222::dead
和2001:db8:2222::beef
。
针对这种后缀不变的情况,我们只要把新的前缀地址拼接上每台设备的固定后缀就可以得到每台设备的 IPv6 地址,因此只需要在一台设备上运行 DDNS 服务,就可以为所有设备批量更新 DDNS 解析。
我现在已经完成了一个可运行的原型,名称暂定为 DDNS6,代码放在 GitHub 上: https://github.com/vfreex/ddns6。 目前这个原型功能还很原始,只支持托管在 dns.he.net 上的域名以及有限的几种 IP 地址检测方式,更新策略为每 5 分钟固定向 DDNS 服务商发送更新请求,但已经可以比较稳定地运作。
程序使用 Rust 开发,async-await 异步编程,为了简便目前只在 GitHub 上放了一个Linux x86_64 编译版本,全静态链接,因此体积比较大(约 3.35MB )。我简单做过实验,如果针对 MIPS OpenWRT 编译,动态链接 musl libc 和 openssl,再加上一些标准库魔改,最终可执行文件可以缩到 1M 以下。
配置文件使用 TOML 格式,目前使用固定路径config/ddns6.toml
。
[[entries]]
hostname="router.example.com"
username="router.example.com"
password="your-password"
provider="he.net"
ipv4={web="_"}
ipv6=[{addr={dev="br0"}, len=64}, "::1"]
[[entries]]
hostname="nas.example.com"
username="nas.example.com"
password="your-password"
provider="he.net"
ipv4={web="_"}
ipv6=[{addr={dev="br0"}, len=64}, "::2"]
上面这个示例配置了两个域名,其中域名router.example.com
的 A 记录设置为外网 IPv4 地址(通过访问 Web 地址 http://ip.sb 获得),IPv6 地址为网桥br0
的前 64 位,拼接后缀::1
。域名nas.example.com
的 IPv4 地址相同,IPv6 地址为网桥br0
的前 64 位,拼接后缀::2
。
指定 IP 地址的方式还有很多,比如:
"198.51.100.1"
, "2001:db8:1234:5678:90ab:cdef:1234"
。{web="_"}
。{dev="eth0"}
。{addr=ADDRESS,mask="255.255.255.0"}
,{addr=地址,mask="ffff:ffff:ffff:ffff::"}
。其中ADDRESS
可嵌套,比如为{dev="eth0"}
。N
位),如 {addr=ADDRESS,len=24}
,{addr=地址,len=64}
。其中ADDRESS
可嵌套,前面已经演示过了。[ADDRESS1, ADDRESS2]
,前面已经演示过了。目前开源的 DDNS 软件很多,但对 IPv6 有良好支持的还不多,不能解决我个人使用的需求。但我的需求或许是小众的,不确定有没有完善、让更多人一起参与的必要,现在发出来让大伙参谋一下。
1
Archeb 2020-02-20 13:32:16 +08:00
正好我以前做过一模一样的
https://github.com/Archeb/ADDNS |
2
Archeb 2020-02-20 13:32:52 +08:00
关于实际需求嘛
我 IPv6 关掉了,因为目前还是太鸡肋 所以我自己都没有再用 |
4
wazon 2020-02-20 22:38:16 +08:00 1
比较新的操作系统默认使用带隐私保护扩展的 SLAAC,IPv6 后缀是会变化的:
对于 stable address,Windows 一般随机自动生成,之后保持稳定,但重装驱动等操作也会导致重新生成。Linux 类的情况比较复杂,如果根据 EUI-64 生成是稳定的,但也有“stable privacy address”等根据前缀自动改变的机制 对于 temporary address,一般是根据几小时到几天不等的有效期自动变化(有的系统没有这个地址) 个人觉得也可以通过 NDP,结合预设的 MAC 找到对应设备的最新 IP 地址。这样使用者无需配置主机,只需要在路由器记录 MAC 和域名的对应关系即可。 例如我一台 Windows 电脑运行 ipconfig -all 有: 物理地址. . . . . . . . . . . . . : DC-AA-77-42-58-A2 IPv6 地址 . . . . . . . . . . . . : 2400:12:34:5600:e506:9710:e3b2:b9e9 临时 IPv6 地址. . . . . . . . . . : 2400:12:34:5600:d8fb:10a9:636:2912 本地链接 IPv6 地址. . . . . . . . : fe80::e506:9710:e3b2:b9e9%24 IPv4 地址 . . . . . . . . . . . . : 192.168.1.233 而在路由器上运行 ip neighbour 有: 192.168.1.233 dev br-lan lladdr dc:aa:77:42:58:a2 REACHABLE fe80::e506:9710:e3b2:b9e9 dev br-lan lladdr dc:aa:77:42:58:a2 REACHABLE 2400:12:34:5600:d8fb:10a9:636:2912 dev br-lan lladdr dc:aa:77:42:58:a2 REACHABLE 让路由、客户端的防火墙放行 ICMP,则会发现这两个 IPv6 地址: 2400:12:34:5600:e506:9710:e3b2:b9e9 2400:12:34:5600:d8fb:10a9:636:2912 都可以响应外部的 ping。 这样的话,路由器上的程序可以直接根据 MAC 得到 Temporary addresses,也可以结合 Local Link 地址推出公网的 Stable addresses,这样似乎能实现更高程度的自动化。 (例子中的数值经过脱敏处理) |
5
xmr68yahoo 2020-02-21 08:25:23 +08:00 via iPhone
有需求..
目前下游设备 Linux Windows 用的脚本.... 其实放在 Openwrt 上做更新更方便 |
6
raysonx OP @wazon 我已经注意到这个问题了,新的操作系统(包括 mac )默认会启用隐私拓展,使得推断后缀变得不可行。
查 ip neighbor 是一种方法,不过缺点是可能会拿到临时地址,而临时地址变化会有些频繁。 |
7
wazon 2020-02-21 14:43:34 +08:00
@raysonx 我已经讲了啊,可以根据 Link-Local 地址和临时地址推算出主机的稳定地址。再明确一下,这是因为有不少操作系统默认的 Link-Local 地址后 64bit 与稳定地址的后 64bit 是相同的。
|
8
chwhsen 2020-02-21 17:42:49 +08:00
持续关注,家里的 v4 公网被回收了,只剩下 ipv6 了,路由器下三台设备,正在想解决思路呢
|
9
raysonx OP @wazon 我自己用 mac,mac 下不同前缀的稳定后缀地址是不同的,但只要前缀不变,后缀也不会变,估计是前缀也作为后缀计算的变量加进去了。
|
10
wazon 2020-02-22 02:56:35 +08:00
@raysonx 这应该就是 stable privacy address 机制,可以防止设备在跨网络环境时因为后 64bit 不变而被追踪( Windows 的后 64bit 则相对稳定)。对 DDNS 而言,可以选择发布 stable address,也可以选择发布 temporary address,毕竟两者都是会变的。只是前者是按运营商设定的时间变,后者是在前者的基础上又会因主机的因素而变。对 Windows 主机,发布后者比较简单,路由器的 neighbour 里可以直接找到。发布前者稍微复杂一点,需要把 Link-Local 的后 64bit 取出来,拼上 temporary 的前 64bit。不知道对你的 mac 主机,在路由器上按这种方法操作,是否也能获得这两个可供公网访问的地址。
|
11
leoyzen 2020-02-23 02:04:53 +08:00 via Android
自已用 go 改了改写了一个,运行了一年了,还算好用,在主路由上自动获取 prefix 地址并组装计算 ipv6 ( nas 上的各种服务)。主要现在 4g 都有 ipv6 了,ipv6 的端口还可用
|
12
Maskeney 2020-03-09 16:38:15 +08:00
异常的需求啊,两年前就有这个需求但是找了一圈没有合适的轮子。如果不用 DHCPv6,局域网设备的 IPV6 对于网关来说是透明的,之前 IPV4 时代的获取路由器公网 IP+端口转发的方式行不通了。希望出一个可以部署在 OpenwWrt 上的轮子,不过我感觉还是没法获取到局域网设备的 IPV6 啊?
|
14
manfred4527 2022-03-17 09:58:02 +08:00
@Archeb 怎么支持阿里云
|