如果一侧网络具有IPV6公网,想要把ROS路由器的IPV6公网的地址(动态,DDNS)同步到cloudflare的域名,而不同步IPV4地址(因为是无效的),应该怎么做呢?
首先分析一下需求。在IPV6-IPV4 Dual Stack 网络中,那个IPV4通常是CGNAT网络,不能使用。而IPV6是Public IP,但是会动态变化。由于在IPV6环境下“内网”里机器的IPV6和网关(这里指RouterOS)不一样,如果在内网里某个设备上使用市面上的ddns工具,比如ddns-go,实际上IPV6的地址不是网关的。所以这里要求最好能在网关上直接运行。
RouterOS本身具有一个DDNS工具,正版用户可以免费使用。但是这个工具如果检测到双栈,会同时更新A和AAAA记录。某些客户端不是IPV6-ONLY 设计的(比如iOS和OSX的Wireguard等),会首选连接到无效的A记录,并连接失败。这个问题我在reddit上看到很多人反馈了,目前也无改善。
如果把另外一个域名的CNAME到这个Mikrotik提供的DDNS域名上,也会是一样的结果。目前的DNS不支持在CNAME时单独复制一种记录。
所以需要写一个脚本来手工仅更新AAAA记录。
在网上找了一些直接在ROS上运行的DDNS脚本,不是双栈的,就是过于复杂,最后找到一个稍微简单一点的样例。运行报错 CODE 10000
并停滞了。
经过研究Cloudflare的文档,现在CF的鉴权改了,不再要求电子邮件,而是直接用一个key。
:local token "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
:local mail "[email protected]";
:local zoneId "yyyyyyyyyyyyyyyyyyyyyyyyy";
:local dnsId "zzzzzzzzzzzzzzzzzzzzzzzzzz";
:local domain "ipv6.example.com";
:local ip [/ipv6 dhcp-client get pppoe-out1 prefix];
:set $ip [:pick $ip 0 [:find $ip "/"]];
:local lastIp [/system script get ddns comment];
:local address "https://api.cloudflare.com/client/v4/zones/$zoneId/dns_records/$dnsId";
:local header "Authorization: Bearer $token,Content-Type:application/json";
:local body "{\"type\":\"AAAA\",\"name\":\"$domain\",\"content\":\"$ip\",\"ttl\":120,\"proxied\":false}";
:if ($lastIp != $ip) do={
:put $address;
/tool fetch url=$address http-method=put output=none http-header-field=$header http-data=$body;
/system script set ddns comment=$ip;
}
其中删除email(不再需要)。token 是 API KEY,权限为DNS编辑,ZONE为你的域名。ZONEID 在CF控制台获取,DNS ID 需要用curl获取,获取方式自己Google。
这个脚本必须命名为”ddns” 因为它会把之前的IP存在COMMENT里… 简单而优雅吧?
下面 "Authorization: Bearer $token,Content-Type:application/json";
去掉了email和AUTH-KEY,直接用 Bearer 代替。
先运行一次,可以看到更新成功了,再运行一次没反应,说明从Comment里读到IP并认为相同,不需要更新。
[admin@MikroTik] > /system script run "ddns"
https://api.cloudflare.com/client/v4/zones/yyyyyyyyyyyyyyyyyy/dns_re
cords/zzzzzzzzzzzzzzzzzz
status: finished
downloaded: 0KiB
total: 0KiB
duration: 2s
[admin@MikroTik] > /system script run "ddns"
[admin@MikroTik] >
再去Cloudflare控制台上看,已经更新成功。接下来设为计划任务,每5分钟运行一次即可。
这样客户端输入这个域名 ipv6.example.com ,就仅有AAAA记录而不会连接到A记录去了。
参考:
github https://github.com/vhvy/reminder/issues/4