MikroTik RouterOS v7.17.2 Cloudflare DDNS 脚本
实测 MikroTik RouterOS v7.17.2 ARM 版支持 Cloudflare DDNS 功能。以下是配置脚本及说明:
################# CloudFlare 变量 #################
# 是否开启 debug 调试模式
:local CFDebug "ture"
# 是否开启 CFcloud 功能
:local CFcloud "false"
# 修改为有公网 IP 的接口名称
:global WANInterface "pppoe-out1"
# 修改为你要 ddns 的域名,若是二级域名,这里填写完整的二级域名
:local CFdomain "x.xxx.com"
# CloudFlare 全局密钥 token 或者有权限操作解析域名的 token
:local CFtkn "推荐全局 token"
:local CFemail "账号邮箱"
# 域名 zoneId
:local CFzoneid "6ec4ed51exxxxxxxxxxxxxxxxxxxxxxxxxxx"
# 要 ddns 的域名记录 id
:local CFid "de4ba35fbxxxxxxxxxxxxxxxxxxxxxx"
# 记录类型 一般无需修改
:local CFrecordType "":set CFrecordType"A"
# 记录 ttl 值,一般无需修改
:local CFrecordTTL "":set CFrecordTTL"120"
# 临时文件名
:global TMPfilename "":set TMPfilename ($CFdomain ."-"."ddns.tmp.txt");
:log info $TMPfilename;
#########################################################################
######################## 下面的内容请勿修改 ############################
#########################################################################
:log info "开始更新解析记录 $CFDomain ..."
################# 内部变量 variables #################
:local previousIP "":global WANip""
################# 构建 CF API Url (v4) #################
:local CFurl "https://api.cloudflare.com/client/v4/zones/"
:set CFurl ($CFurl . "$CFzoneid/dns_records/$CFid");
################# 获取或设置以前的 ip 变量 #################
:if ($CFcloud = "true") do={:set WANip [/ip cloud get public-address]
};
:if ($CFcloud = "false") do={:local currentIP [/ip address get [/ip address find interface=$WANInterface] address];
:set WANip [:pick $currentIP 0 [:find $currentIP "/"]];
};
:if ([/file find name="$TMPfilename"] = "") do={
:log error "找不到记录以前自动创建的公用 IP 地址的文件..."
:set previousIP $WANip;
:execute script=":put $WANip" file="$TMPfilename";
:log info "$TMPfilename";
:log info ("CF: 正在开始更新分析记录,正在设置 $CFDomain = $WANip")
/tool fetch http-method=put mode=https output=none url="$CFurl" http-header-field="X-Auth-Email:$CFemail,X-Auth-Key:$CFtkn,content-type:application/json" http-data="{\"type\":\"$CFrecordType\",\"name\":\"$CFdomain\",\"ttl\":$CFrecordTTL,\"content\":\"$WANip\"}"
:error message="找不到以前公用 IP 地址的文件"
} else={:if ( [/file get [/file find name="$TMPfilename"] size] > 0 ) do={:global content [/file get [/file find name="$TMPfilename"] contents] ;
:global contentLen [ :len $content ] ;
:global lineEnd 0;
:global line "";
:global lastEnd 0;
:set lineEnd [:find $content "\n" $lastEnd ] ;
:set line [:pick $content $lastEnd $lineEnd] ;
:set lastEnd ($lineEnd + 1) ;
:if ([:pick $line 0 1] != "#" ) do={#:local previousIP [:pick $line 0 $lineEnd]
:set previousIP [:pick $line 0 $lineEnd ];
:set previousIP [:pick $previousIP 0 [:find $previousIP "\r"]];
}
}
}
######## 将调试信息写入日志 #################
:if ($CFDebug = "true") do={:log info ("CF: 解析域名 = $CFdomain")
:log info ("CF: 域名解析 IPv4 = $previousIP")
:log info ("CF: 使用 IP = $currentIP")
:log info ("CF: 当前公网 IPv4 = $WANip")
:log info ("CF: 使用的 API 地址 v4 = $CFurl&content=$WANip")
:log info ("CF: Execute Command = \"/tool fetch http-method=put mode=https url=\"$CFurl\" http-header-field="X-Auth-Email:$CFemail,X-Auth-Key:$CFtkn,content-type:application/json" output=none http-data=\"{\"type\":\"$CFrecordType\",\"name\":\"$CFdomain\",\"ttl\":$CFrecordTTL,\"content\":\"$WANip\"}\"")
};
######## 比较并更新记录 #####
:if ($previousIP != $WANip) do={:log info ("CF: 正在更新 IPv4 解析地址, setting $CFDomain = $WANip")
/tool fetch http-method=put mode=https url="$CFurl" http-header-field="X-Auth-Email:$CFemail,X-Auth-Key:$CFtkn,content-type:application/json" output=none http-data="{\"type\":\"$CFrecordType\",\"name\":\"$CFdomain\",\"ttl\":$CFrecordTTL,\"content\":\"$WANip\"}"
/ip dns cache flush
:if ([/file get [/file find name="$TMPfilename"] size] > 0 ) do={
/file remove "$TMPfilename"
:execute script=":put $WANip" file="$TMPfilename"
}
} else={:log info "CF: IPv4 公网地址与解析的地址匹配无需更新!"}