«

RouterOS v7 DNSPod DDNS更新脚本

myluzh 发布于 阅读:1029 RouterOS


0x01 关于参数解释

loginToken:用于鉴权的 DNSPod Token,由 ID,Token 组合而成,中间用英文逗号分隔。获取地址:DNSPod Token。进入“我的账号 → API 密钥 → DNSPod Token”创建,注意这里用的是 DNSPod 传统 API Token。

domainId:域名 ID,在域名的解析设置里查看 Domain ID。

recordId:记录 ID。在解析记录的自定义列表字段中勾选“记录 ID”,就能看到。先在 DNSPod 创建一条 A 记录,再把对应的 ID 填到脚本里。

subDomain:主机记录。比如更新 home.example.com,这里填 home,不是完整域名。

recordLineId:线路 ID,默认线路填 0。

wanInterface:PPPoE 拨号接口名称,示例是 pppoe-out1,按自己的接口修改。

forceUpdate:填 false 时,首次运行或公网 IP 变化后更新;填 true 时,每次执行都提交更新。原来这里把 false 拼成了 flase,参数说明也写反了,这次一起修正。

0x02 RouterOS v7 DNSPod DDNS 更新脚本

这份按 RouterOS 上保留的定时任务整理,当前设备版本为 RouterOS 7.21.2。Token、域名 ID、记录 ID 和接口名称都换成了示例值。

脚本直接读取 PPPoE 接口的 IPv4 地址,不依赖外部查 IP 网站。它不会自动创建 DNSPod 记录,只更新 recordId 对应的已有记录。

:local loginToken "YOUR_DNSPOD_ID,YOUR_DNSPOD_TOKEN"
:local domainId "YOUR_DOMAIN_ID"
:local recordId "YOUR_RECORD_ID"
:local subDomain "home"
:local recordLineId "0"
:local wanInterface "pppoe-out1"
:local forceUpdate false
:global LastDDNSIP

:local currentIP ""
:do {
    /interface pppoe-client monitor $wanInterface once do={
        :set currentIP $"local-address"
    }
} on-error={
    :log error "DDNS: Failed to get IP"
    :error "Stop"
}

:if ([:len $currentIP] = 0) do={
    :log error "DDNS: IP is empty"
    :error "Stop"
}

:if ($LastDDNSIP != $currentIP || $forceUpdate = true) do={

    :log info "DDNS: Update Triggered ($LastDDNSIP -> $currentIP) [Force: $forceUpdate]"

    :local postData "login_token=$loginToken&format=json&domain_id=$domainId&record_id=$recordId&record_line_id=$recordLineId&sub_domain=$subDomain&value=$currentIP"

    :do {
        /tool fetch url="https://dnsapi.cn/Record.Ddns" mode=https http-method=post http-data=$postData keep-result=no
        :set LastDDNSIP $currentIP
        :log info "DDNS: Update Success"
    } on-error={
        :log error "DDNS: Update Failed"
    }

} else={
    #:log info "DDNS: No change."
}

LastDDNSIP 是内存里的全局变量,设备重启后会重新获取并提交一次。复制脚本更新多个域名时,每份脚本要使用不同的全局变量名,避免互相影响。

0x03 定时执行

WinBox 进入 System → Scheduler,新建任务:

项目 值
Name dnspod_ddns
Start Time startup
Interval 00:00:30
Policy read,write,test
On Event 粘贴上面的完整脚本

这里的 30 秒是检查公网 IP 的间隔,和 DNS 记录的 TTL 不是一回事。forceUpdate=false 时,IP 没变就不提交更新。

0x04 验证

执行后查看日志:

/log print where message~"DDNS:"

再检查 DNSPod 控制台里的记录值,或者在电脑上查询:

dig home.example.com A +noall +answer

也可以单独测试 API。下面全部是占位符,执行前替换成自己的值:

curl --request POST 'https://dnsapi.cn/Record.Ddns' \
  --data-urlencode 'login_token=YOUR_DNSPOD_ID,YOUR_DNSPOD_TOKEN' \
  --data-urlencode 'format=json' \
  --data-urlencode 'domain_id=YOUR_DOMAIN_ID' \
  --data-urlencode 'record_id=YOUR_RECORD_ID' \
  --data-urlencode 'record_line_id=0' \
  --data-urlencode 'sub_domain=home' \
  --data-urlencode 'value=YOUR_PUBLIC_IPV4'

API 返回的 status.code 为字符串 "1" 才表示业务处理成功。这份原脚本使用 keep-result=no,没有解析返回 JSON,因此不能只凭 DDNS: Update Success 这一条日志判断记录已经更新,仍要核对记录值。

接口参数见 DNSPod 更新动态 DNS 记录。

routeros ddns ros7 dnspod


正文到此结束
版权声明:若无特殊注明,本文皆为 Myluzh Blog 原创,转载请保留文章出处。
文章内容:https://itho.cn/ros/557.html
文章标题:《RouterOS v7 DNSPod DDNS更新脚本》