RouterOS 使用CloudFlare动态更新 DDNS脚本
概述
Mikrotik RouterOS 是一个比较优秀的路由系统,最近了解了一下,确实很强大,特别是稳定性和系统占用,简直比ikuai、openwrt好太多,但是上手确实有一定门槛,很多东西都需要自己配置,所以功能也很强大,喜欢折腾的同学可以在虚拟机里面安装试试,只用下载chr版本,到Mikrotik官网注册帐号就可以注册无限制永久使用版本。
对于家里有公网IP的,肯定知道DDNS这个东西,就是动态解析域名,能够让自己出门在外随时远程到家取文件,或者是暴露内网服务到公网都需要用到它,今天就给大家分享一下ROS下使用CloudFlare的DDNS,脚本是在github找的通过自己的汉化并且在我安装的最新版测试通过,注释非常的详细,这里就不了解了,脚本放在文章下面。
你只需要替换 CloudFlare 变量中为你的参数即可,脚本的原理是查询你的ppppe的ip地址,然后通过CloudFlare api进行更新解析记录,为了防止频繁调用,所以有一定的策略就是先把上一次的IP地址已文件的形式保存在磁盘,然后每次获取到之后做对比,有变化再调用接口更新,降低网络请求,配合scheduler添加定时任务达到动态更新效果。
脚本
#########################################################################
# ================================================== #
# $ Mikrotik RouterOS 更新 CloudFlare动态DDNS脚本 $ #
# ================================================== #
# #
# - 首先你需要一个CloudFlare的帐号和api密钥, #
# - 一个域名的区域Id(CFzoneid)和 域名记录Id(CFid) #
# - 使用前请先修改第一节的CloudFlare变量再使用, #
# - 这2个值可以在CloudFlare面板中查看,或者是通过F12查看接口数据 #
# - 通过F12查看CFid接口后缀为xxxxxx/dns_records?per_page=50 #
# - 或者通过postman等工具调用官方的API接口进行获取 #
# - 如果需要,启用CFDebug - 它将打印一些信息到日志中 #
# - 如果你的公网没有公网IP,你可以打开CFcloud开关 #
# - 将脚本放在 /system scripts 并且允许 read,write,ftp 这三个权限即可 #
# - 本脚本lcry在RouterOS V7.6版本上测试通过,可以放心试用 #
# - 配合scheduler调度器可以达到IP地址变化自动更新解析记录 #
# - 必须要在RouterOS 6.44beta75 版本以上本脚本才可能支持 #
# #
# Credits for Samuel Tegenfeldt, CC BY-SA 3.0 #
# Modified by kiler129 #
# Modified by viritt #
# Modified by asuna #
# Modified by mike6715b #
# Sinicization by lcry #
# #
# 2022年12月24测试通过并正常工作 #
#########################################################################
################# CloudFlare 变量 #################
# 是否开启debug调试模式
:local CFDebug "false"
# 是否开启CFcloud功能
:local CFcloud "false"
# 修改为有公网IP的接口名称
:global WANInterface "pppoe-out1"
# 修改为你要ddns的域名,若是二级域名,这里填写完整的二级域名
:local CFdomain "ros.test.com"
# CloudFlare 全局密钥token或者有权限操作解析域名的token
:local CFtkn "xxxxxxxxxxx"
# 域名zoneId
:local CFzoneid "aaxxxxxxxxxxxxxxxxxxxxxxx"
# 要ddns的域名记录id
:local CFid "bbxxxxxxxxxxxxxxxxxxxxxxx"
# 记录类型 一般无需修改
:local CFrecordType ""
:set CFrecordType "A"
# 记录ttl值,一般无需修改
:local CFrecordTTL ""
:set CFrecordTTL "120"
#########################################################################
######################## 下面的内容请勿修改 ############################
#########################################################################
: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=ddns.tmp.txt] = "") do={
:log error "没有找到记录前一个公网IP地址的文件, 自动创建..."
:set previousIP $WANip;
:execute script=":put $WANip" file="ddns.tmp";
:log info ("CF: 开始更新解析记录, 设置 $CFDomain = $WANip")
/tool fetch http-method=put mode=https output=none url="$CFurl" http-header-field="Authorization:Bearer $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=ddns.tmp.txt] size] > 0 ) do={
:global content [/file get [/file find name="ddns.tmp.txt"] 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: 前一个解析IP地址 = $previousIP")
:log info ("CF: 当前IP地址 = $currentIP")
:log info ("CF: 公网IP = $WANip")
:log info ("CF: 请求CFurl = $CFurl&content=$WANip")
:log info ("CF: 执行命令 = \"/tool fetch http-method=put mode=https url=\"$CFurl\" http-header-field="Authorization:Bearer $CFtkn,content-type:application/json" output=none http-data=\"{\"type\":\"$CFrecordType\",\"name\":\"$CFdomain\",\"ttl\":$CFrecordTTL,\"content\":\"$WANip\"}\"")
};
######## 比较并更新记录 #####
:if ($previousIP != $WANip) do={
:log info ("CF: 开始更新解析记录, 设置 $CFDomain = $WANip")
/tool fetch http-method=put mode=https url="$CFurl" http-header-field="Authorization:Bearer $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=ddns.tmp.txt] size] > 0 ) do={
/file remove ddns.tmp.txt
:execute script=":put $WANip" file="ddns.tmp"
}
} else={
:log info "CF: 未发生改变,无需更新!"
}
参考文章
Routeros中使用CLoudflare—DDNS来解决自带的IP-CLOUD解析无效附带脚本解析动态域名
RouterOS(ros)软路由实现DDNS动态域名功能(DNSPOD)
商业转载请联系作者获得授权,非商业转载请注明本文出处及文章链接