V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
raysonx
V2EX  ›  宽带症候群

打算做一个批量管理多台设备 IPv6 解析的开源 DDNS 工具,不知道需求有多大

  •  1
     
  •   raysonx · 2020-02-20 12:58:50 +08:00 · 4217 次点击
    这是一个创建于 1771 天前的主题,其中的信息可能已经有所发展或是发生改变。

    要解决的问题

    • 针对 IPv6 使用场景设计,兼容 IPv4/IPv6 双栈;
    • 在一台设备(比如 OpenWRT 路由器或 NAS )上运行该软件,批量更新本地多台设备的 DNS 解析记录。
    • 跨平台,支持 Linux/OpenWRT/EdgeOS/Windows/Mac 等系统,x86_64/MIPS/ARM/AARCH64 等 ISA。

    典型使用场景

    假设 ISP 通过 DHCPv6-PD 给用户分配的 IPv6 前缀是2001:db8:1111::/48,用户 LAN 口侧有三个设备,分别为网关、NAS 和监控摄像头。这三台设备拥有固定的 IPv6 后缀 ::1::dead::beef(通过 Modified EUI-64 基于 MAC 地址生成或者 DHCPv6 等方式下发),因此分别会分到2001:db8:1111::12001:db8:1111::dead2001:db8:1111::beef。 当用户与 ISP 的连接断开重新连接后,ISP 重新给用户下发新的前缀,比如是2001:db8:2222::/48。这时候用户侧设备的地址会发生变更,分别变为2001:db8:2222::12001:db8:2222::dead2001:db8:2222::beef

    针对这种后缀不变的情况,我们只要把新的前缀地址拼接上每台设备的固定后缀就可以得到每台设备的 IPv6 地址,因此只需要在一台设备上运行 DDNS 服务,就可以为所有设备批量更新 DDNS 解析。

    项目原型:DDNS6

    我现在已经完成了一个可运行的原型,名称暂定为 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 地址的方式还有很多,比如:

    1. 静态地址,如 "198.51.100.1", "2001:db8:1234:5678:90ab:cdef:1234"
    2. 通过访问 Web 获得(目前使用 http://ip.sb ),如:{web="_"}
    3. 网卡,如 {dev="eth0"}
    4. 获取一个地址的一部分(对地址和掩码做位与运算),如 {addr=ADDRESS,mask="255.255.255.0"}{addr=地址,mask="ffff:ffff:ffff:ffff::"}。其中ADDRESS可嵌套,比如为{dev="eth0"}
    5. 获取一个地址的网络地址(对地址取前N位),如 {addr=ADDRESS,len=24}{addr=地址,len=64}。其中ADDRESS可嵌套,前面已经演示过了。
    6. 对两个地址作或运算,常用来拼接前后缀,如 [ADDRESS1, ADDRESS2],前面已经演示过了。

    展望

    目前开源的 DDNS 软件很多,但对 IPv6 有良好支持的还不多,不能解决我个人使用的需求。但我的需求或许是小众的,不确定有没有完善、让更多人一起参与的必要,现在发出来让大伙参谋一下。

    14 条回复    2022-03-17 09:58:02 +08:00
    Archeb
        1
    Archeb  
       2020-02-20 13:32:16 +08:00
    正好我以前做过一模一样的
    https://github.com/Archeb/ADDNS
    Archeb
        2
    Archeb  
       2020-02-20 13:32:52 +08:00
    关于实际需求嘛
    我 IPv6 关掉了,因为目前还是太鸡肋
    所以我自己都没有再用
    raysonx
        3
    raysonx  
    OP
       2020-02-20 13:42:50 +08:00
    @Archeb 目前国内运营商的 IPv6 带宽还是太少,路由优化也不到位,不过长远来看还是能解决不少问题的。
    wazon
        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,这样似乎能实现更高程度的自动化。

    (例子中的数值经过脱敏处理)
    xmr68yahoo
        5
    xmr68yahoo  
       2020-02-21 08:25:23 +08:00 via iPhone
    有需求..

    目前下游设备 Linux Windows 用的脚本....

    其实放在 Openwrt 上做更新更方便
    raysonx
        6
    raysonx  
    OP
       2020-02-21 14:09:32 +08:00
    @wazon 我已经注意到这个问题了,新的操作系统(包括 mac )默认会启用隐私拓展,使得推断后缀变得不可行。
    查 ip neighbor 是一种方法,不过缺点是可能会拿到临时地址,而临时地址变化会有些频繁。
    wazon
        7
    wazon  
       2020-02-21 14:43:34 +08:00
    @raysonx 我已经讲了啊,可以根据 Link-Local 地址和临时地址推算出主机的稳定地址。再明确一下,这是因为有不少操作系统默认的 Link-Local 地址后 64bit 与稳定地址的后 64bit 是相同的。
    chwhsen
        8
    chwhsen  
       2020-02-21 17:42:49 +08:00
    持续关注,家里的 v4 公网被回收了,只剩下 ipv6 了,路由器下三台设备,正在想解决思路呢
    raysonx
        9
    raysonx  
    OP
       2020-02-21 20:48:55 +08:00 via iPhone
    @wazon 我自己用 mac,mac 下不同前缀的稳定后缀地址是不同的,但只要前缀不变,后缀也不会变,估计是前缀也作为后缀计算的变量加进去了。
    wazon
        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 主机,在路由器上按这种方法操作,是否也能获得这两个可供公网访问的地址。
    leoyzen
        11
    leoyzen  
       2020-02-23 02:04:53 +08:00 via Android
    自已用 go 改了改写了一个,运行了一年了,还算好用,在主路由上自动获取 prefix 地址并组装计算 ipv6 ( nas 上的各种服务)。主要现在 4g 都有 ipv6 了,ipv6 的端口还可用
    Maskeney
        12
    Maskeney  
       2020-03-09 16:38:15 +08:00
    异常的需求啊,两年前就有这个需求但是找了一圈没有合适的轮子。如果不用 DHCPv6,局域网设备的 IPV6 对于网关来说是透明的,之前 IPV4 时代的获取路由器公网 IP+端口转发的方式行不通了。希望出一个可以部署在 OpenwWrt 上的轮子,不过我感觉还是没法获取到局域网设备的 IPV6 啊?
    moyupoi
        13
    moyupoi  
       2020-03-14 02:46:35 +08:00 via iPhone
    @Maskeney 胡说八道,你是小学生吧?
    manfred4527
        14
    manfred4527  
       2022-03-17 09:58:02 +08:00
    @Archeb 怎么支持阿里云
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5381 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 05:48 · PVG 13:48 · LAX 21:48 · JFK 00:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.