本文介绍如何在RouterOS中使用脚本完成动态域名解析DDNS
1. Cloudflare DDNS 脚本
先祭出ddns脚本,仅提供解析至cf的脚本。自行准备好“你的DDNS token”“你的ZONEID””你的RECORD6ID“或”RECORD4ID“以及域名(支持ddns泛解析)。文末提供”ZONEID“、”RECORD4ID”等所需参数获取教程。
1.1 完整脚本模板
- 此模板为先更新IPV6记录,等待300s后更新IPV4记录
# token $ zoneid
:local TOKEN "你的DDNS token"
:local ZONEID "你的ZONEID"
# IPv6
:local RECORD6ID "你的RECORD6ID"
:local RECORD6NAME "*.你的v6域名.com"
:local WANIF6 "pppoe-out1或bridge1" #自行更改,NAT6选PPPOE接口,SLAAC选bridge
:local url6 "https://api.cloudflare.com/client/v4/zones/$ZONEID/dns_records/$RECORD6ID/"
# IPv4
:local RECORD4ID "你的RECORD4ID"
:local RECORD4NAME "*.你的v4域名.com"
:local WANIF4 "pppoe-out1" #自行更改
:local url4 "https://api.cloudflare.com/client/v4/zones/$ZONEID/dns_records/$RECORD4ID/"
# 更新 IPv6 记录
:if ([/interface get $WANIF6 value-name=running]) do={
# 获取本地 IPv6 地址
:local currentIP6 [/ipv6/address/get [:pick [find global interface=$WANIF6] 0 ] address]
:local IP6NEW [:pick $currentIP6 0 [:find $currentIP6 "/"]]
:log info "当前IPv6地址: $IP6NEW"
# 获取 Cloudflare 当前的 DNS 记录
:local cfRecord [/tool fetch mode=https url=$url6 check-certificate=no output=user as-value \
http-header-field="Authorization: Bearer $TOKEN,Content-Type: application/json"]
# 解析 Cloudflare 返回的 JSON 数据
:local cfContent ($cfRecord->"data")
:local startIndex [:find $cfContent "\"content\":\""]
:local cfIP6 [:pick $cfContent ($startIndex + 11) [:find $cfContent "\"" ($startIndex + 11)]]
:log info "CF IPv6地址: $cfIP6"
# 对比本机 IP 和 Cloudflare 记录
:if ($IP6NEW != $cfIP6) do={
:log info "检测到 IP 变化:Cloudflare=$cfIP6, 本地=$IP6NEW"
# 更新 Cloudflare 记录
:local cfUpdate6 [/tool fetch http-method=put mode=https url=$url6 check-certificate=no output=user as-value \
http-header-field="Authorization: Bearer $TOKEN,Content-Type: application/json" \
http-data="{\"type\":\"AAAA\",\"name\":\"$RECORD6NAME\",\"content\":\"$IP6NEW\",\"ttl\":120,\"proxied\":false}"]
:log info "已更新 Cloudflare IPv6 为 $IP6NEW"
} else={
:log info "当前 Cloudflare 记录 ($cfIP6) 与本机 IP 相同,无需更新。"
}
} else={
:log error "$WANIF6 接口未运行,无法获取本地 IPv6 地址"
}
#等待300s,若仅更新V4或V6需删除
:delay 300s
# 更新 IPv4 记录
:if ([/interface get $WANIF4 value-name=running]) do={
# 获取本地 IPv4 地址
:local currentIP4 [/ip/address get [/ip/address find interface=$WANIF4] address]
:local IP4NEW [:pick $currentIP4 0 [:find $currentIP4 "/"]]
:log info "当前IPv4地址: $IP4NEW"
# 获取 Cloudflare 当前的 DNS 记录
:local cfRecord [/tool fetch mode=https url=$url4 check-certificate=no output=user as-value \
http-header-field="Authorization: Bearer $TOKEN,Content-Type: application/json"]
# 解析 Cloudflare 返回的 JSON 数据
:local cfContent ($cfRecord->"data")
:local startIndex [:find $cfContent "\"content\":\""]
:local cfIP4 [:pick $cfContent ($startIndex + 11) [:find $cfContent "\"" ($startIndex + 11)]]
:log info "CF IPv4地址: $cfIP4"
# 对比本机 IP 和 Cloudflare 记录
:if ($IP4NEW != $cfIP4) do={
:log info "检测到 IP 变化:Cloudflare=$cfIP4, 本地=$IP4NEW"
# 更新 Cloudflare 记录
:local cfUpdate4 [/tool fetch http-method=put mode=https url=$url4 check-certificate=no output=user as-value \
http-header-field="Authorization: Bearer $TOKEN,Content-Type: application/json" \
http-data="{\"type\":\"A\",\"name\":\"$RECORD4NAME\",\"content\":\"$IP4NEW\",\"ttl\":120,\"proxied\":false}"]
:log info "已更新 Cloudflare IPv4 为 $IP4NEW"
} else={
:log info "当前 Cloudflare 记录 ($cfIP4) 与本机 IP 相同,无需更新。"
}
} else={
:log error "$WANIF4 接口未运行,无法获取本地 IPv4 地址"
}
1.2 单独 IPv4/IPv6 版本
- 若仅需更新IPV4或IPV6,删除多余板块和”:delay 300s”即可
- 以仅更新IPV6为例
# token $ zoneid
:local TOKEN "你的DDNS token"
:local ZONEID "你的ZONEID"
# IPv6
:local RECORD6ID "你的RECORD6ID"
:local RECORD6NAME "*.你的v6域名.com"
:local WANIF6 "pppoe-out1或是bridge1" #自行更改,NAT6选PPPOE接口,SLAAC选bridge
:local url6 "https://api.cloudflare.com/client/v4/zones/$ZONEID/dns_records/$RECORD6ID/"
# 更新 IPv6 记录
:if ([/interface get $WANIF6 value-name=running]) do={
# 获取本地 IPv6 地址
:local currentIP6 [/ipv6/address/get [:pick [find global interface=$WANIF6] 0 ] address]
:local IP6NEW [:pick $currentIP6 0 [:find $currentIP6 "/"]]
:log info "当前IPv6地址: $IP6NEW"
# 获取 Cloudflare 当前的 DNS 记录
:local cfRecord [/tool fetch mode=https url=$url6 check-certificate=no output=user as-value \
http-header-field="Authorization: Bearer $TOKEN,Content-Type: application/json"]
# 解析 Cloudflare 返回的 JSON 数据
:local cfContent ($cfRecord->"data")
:local startIndex [:find $cfContent "\"content\":\""]
:local cfIP6 [:pick $cfContent ($startIndex + 11) [:find $cfContent "\"" ($startIndex + 11)]]
:log info "CF IPv6地址: $cfIP6"
# 对比本机 IP 和 Cloudflare 记录
:if ($IP6NEW != $cfIP6) do={
:log info "检测到 IP 变化:Cloudflare=$cfIP6, 本地=$IP6NEW"
# 更新 Cloudflare 记录
:local cfUpdate6 [/tool fetch http-method=put mode=https url=$url6 check-certificate=no output=user as-value \
http-header-field="Authorization: Bearer $TOKEN,Content-Type: application/json" \
http-data="{\"type\":\"AAAA\",\"name\":\"$RECORD6NAME\",\"content\":\"$IP6NEW\",\"ttl\":120,\"proxied\":false}"]
:log info "已更新 Cloudflare IPv6 为 $IP6NEW"
} else={
:log info "当前 Cloudflare 记录 ($cfIP6) 与本机 IP 相同,无需更新。"
}
} else={
:log error "$WANIF6 接口未运行,无法获取本地 IPv6 地址"
}
2. 在 RouterOS 中配置 DDNS
- 配置DNS static (可选项,博主所在地区无法直连cf的api,所以设置后通过代理访问cf的api)
/ip dns static add address=104.19.192.175 name=api.cloudflare.com type=A
- 添加脚本,名字随意

- 点击运行脚本,查看log是否报错

- 若报错,将104.19.192.175路由至sing-box走代理

- 添加计划任务,3分钟执行一次

3. 获取 DDNS 脚本所需参数
3.1 获取 Global API Key
- 登录CF主页,点击我的个人资料

- 输入密码查看Global API KEY

- 创建DDNS token
注:API令牌仅出现1次,务必保存好

3.2 获取 ZONEID
- 账户主页-进入需DDNS的域名界面

- 往下滑找到区域ID即为ZONEID

3.3 获取 RECORDID
若域名无DNS记录,需先创建1条DNS记录 在任意linux系统中通过下述命令获取你的RECORDID,A代表V4,AAAA代表V6,如果同域名需要解析V4和V6,在CF上使用同一个二个域名,分别选择A和AAAA
- 获取RECORD4ID(IPV4)
curl -X GET "https://api.cloudflare.com/client/v4/zones/这里输入你的ZONEID/dns_records?type=A&name=你的域名" \
-H "X-Auth-Email: 这里输入你的CF帐号邮箱" \
-H "X-Auth-Key: 这里输入你的global_TOKEN" \
-H "Content-Type: application/json"
- 获取RECORD6ID(IPV6)
curl -X GET "https://api.cloudflare.com/client/v4/zones/这里输入你的ZONEID/dns_records?type=AAAA&name=你的域名" \
-H "X-Auth-Email: 这里输入你的CF帐号邮箱" \
-H "X-Auth-Key: 这里输入你的global_TOKEN" \
-H "Content-Type: application/json"