MikroTik DNSPOD动态域名解析脚本
#####################################################################################################################
##### RouterOS 利用 DNSPod 的API接口实现DDNS解析
##### 注意事项:首先到DNSPod官网添加需要动态解析域名的A记录,并选择“默认”路线,防止域名不存在,动态更新不成功!
##### 生成 Token 号;参考网址:https://support.dnspod.cn/Kb/showarticle/tsid/227/
##### 务必注意上图信息中的 ID 和 Token,需要用这两个字段来组合成一个完整的 Token,
##### 组合方式为:"ID,Token"(用英文半角逗号分割),比如说本示例中,完整的 Token 为:
##### 13490,6b5976c68aba5b14a0558b77c17c3932 。得到完整的 Token 之后,调用方式如下
##### curl https://dnsapi.cn/Domain.List -d"login_token=13490,6b5976c68aba5b14a0558b77c17c3932&format=json"
#####
##### DNSPod的API接口文档:https://support.dnspod.cn/Support/api
##### 更新动态DNS记录接口参数说明:https://www.dnspod.cn/docs/records.html#dns
#####################################################################################################################
##### 动态域名更新:dnspodsh - 动态解析脚本 for Mikrotik RouterOS Tools/Fetch
#####################################################################################################################
#####################################################################################################################
##### 参数设置开始:↓↓↓
##### DdnsToken → 完整的 Token 值("ID,Token"用英文半角逗号分割)
:local DdnsToken "16000,92cd5abcd6d7a5bea20fd7000000b";
##### DdnsDomain → 域名
:local DdnsDomain "x123.cn";
##### DdnsRecord → 子域名(主机记录)
:local DdnsRecord "www";
##### 设置解析网卡接口
:local ednsinterface "pppoe-out1";
##### 参数设置结束:↑↑↑
#####################################################################################################################
#####################################################################################################################
:local ednshost ($DdnsRecord.".".$DdnsDomain);
:log warning ("DDNS域名: ".$ednshost);
##### DdnsDomainID → domain_id
:local DdnsDomainID;
##### DdnsRecordsID → records_id
:local DdnsRecordsID;
##### PostData1、PostData2 → POST请求发送的数据内容。
:local PostData1 ("login_token=".$DdnsToken."&format=json&domain=".$DdnsDomain."&sub_domain=".$DdnsRecord."&record_type=A&offset=0&length=1");
##:log warning ($PostData1);
:local PostData2;
#####################################################################################################################
##### 获取 domain_id 获取 record_id 脚本
##### 接口参数说明:https://www.dnspod.cn/docs/records.html#record-info
#####
##### curl -X POST 'https://dnsapi.cn/Record.List' -d 'login_token=[自己的ID],[自己的Token]&format=json
##### &domain=[自己的域名.cn]&sub_domain=[自己的主机记录www]&record_type=A&offset=0&length=1'
#####################################################################################################################
#####################################################################################################################
#####获取pppoe-out1拨号接口是否处存在
:local InterfacePPPoe [:len [/interface find name=$ednsinterface]];
###:log warning ($InterfacePPPoe);
:if ($InterfacePPPoe!=0) do={
:local status [/interface get [/interface find name=$ednsinterface] running];
###:log info ($status);
#####检测接口是否处于运行状态
:if ($status!=false) do={
#####通过域名解析获取IP地址
:local ednslastip [:resolve $ednshost];
:log info ("域名解析IP: ".$ednslastip);
#####查看ednslastip变量是否为空,如果为空则分配0.0.0.0地址
:if ([:typeof $ednslastip] = nil) do={:local ednslastip "0.0.0.0" };
#####获取解析网卡IP地址
:local ednsiph [/ip address get [/ip address find interface=$ednsinterface] address];
:log info ($ednsiph);
:local ednsip [:pick $ednsiph 0 [:find $ednsiph "/"]];
:log info ("解析网卡IP: ".$ednsip);
#####域名IP与解析网卡IP对比,确定是否更新域名IP地址
:if ($ednslastip != $ednsip) do={
:delay 1;
:log info ("域名IP地址更新开始" );
####################################################################################
:log info ("获取 domain_id | record_id 脚本执行开始↓");
:local Dupdate1 [/tool fetch http-method=post http-data=$PostData1 url="https://dnsapi.cn/Record.List" as-value output=user];
:delay 1;
:local datastr1 ($Dupdate1->"data");
#####提取变量中的返回值,输出到日志中,便于检查测试时是否成功访问接口。
###:log info ($datastr1);
:local domainstr [:pick $datastr1 [:find $datastr1 "\"domain\""] [:find $datastr1 "," [:find $datastr1 "\"domain\""]]];
:local recordstr [:pick $datastr1 [:find $datastr1 "\"records\""] [:find $datastr1 "," [:find $datastr1 "\"records\""]]];
:local DdnsIPstr [:pick $datastr1 [:find $datastr1 "\"value\":\""] [:find $datastr1 "," [:find $datastr1 "\"value\":\""]]];
##############################
#####变量返回值,输出到日志中,检验是否成功定位匹配到domain_id内容
:log warning ($domainstr);
:set DdnsDomainID [:pick $domainstr 16 ([:len $domainstr]-1)];
:log warning ($DdnsDomainID);
#####变量返回值,输出到日志中,检验是否成功定位匹配到record_id内容
:log warning ($recordstr);
:set DdnsRecordsID [:pick $recordstr 18 ([:len $recordstr]-1)];
:log warning ($DdnsRecordsID);
#####获取域名远程IP地址
:log warning ($DdnsIPstr);
:local DdnsIP [:pick $DdnsIPstr 9 ([:len $DdnsIPstr]-1)];
:log warning ($DdnsIP);
##############################
:log info ("获取 domain_id | record_id 脚本执行结束↑");
####################################################################################
#####二次对比验证IP,防止没有任何变动的记录修改请求,造成该记录会被远程域名系统锁定
:if ($DdnsIP != $ednsip) do={
####################################################################################
:log warning ("参数全部获取成功,开始更新域名IP");
:set PostData2 ("login_token=".$DdnsToken."&format=json&record_line_id=0&domain_id=".$DdnsDomainID."&record_id=".$DdnsRecordsID."&sub_domain=".$DdnsRecord."&value=".$ednsip);
##:log warning ($PostData2);
##############################
:local Dupdate2 [/tool fetch http-method=post http-data=$PostData2 url="https://dnsapi.cn/Record.Ddns" as-value output=user];
:local datastr2 ($Dupdate2->"data");
####################################################################################
####################################################################################
#####校验域名IP地址是否更新成功
##:log info ($datastr2);
:local IPstr [:pick $datastr2 [:find $datastr2 "\"value\":\""] [:find $datastr2 "}" [:find $datastr2 "\"value\":\""]]];
:log warning ($IPstr);
:local NewIP [:pick $IPstr 9 ([:len $IPstr]-1)];
:log warning ($NewIP);
:if ($ednsip = $NewIP) do={ :log warning ("IP更新成功!")} else={ :log warning ("IP更新失败!")};
####################################################################################
:log info ("域名IP地址更新结束");
:delay 1;
} else={:log warning ("远程IP已更新,不执行域名更新脚本");
:delay 1;
};
} else={:log warning ("IP没有变动,不执行域名更新脚本");
:delay 1;
};
} else={:log warning ($ednsinterface."接口状态异常")};
} else={:log warning ($ednsinterface."接口不存在")};