Mikrotik RouterOS 路由器 CloudFlare DDNS 动态解析脚本(IPv4/IPv6)
Mikrotik RouterOS 路由器 CloudFlare DDNS 动态解析脚本(IPv4/IPv6)
Last edited 2022-6-25
type
Post
status
Published
date
Mar 13, 2020
slug
routeros-ddns-cloudflare
summary
在 RouterOS 添加一个脚本执行后将公网IPv4/IPv6解析到指定域名,该脚本改自 github 的 viritt/cloudflare_update.script 相比原版本增加IPv6解析以及双栈的支持
tags
RouterOS
category
网络运维
icon
password
Property
Jun 25, 2022 10:06 AM
在 RouterOS 添加一个脚本执行后将公网IPv4/IPv6解析到指定域名,该脚本改自 github 的 viritt/cloudflare_update.script 相比原版本增加IPv6解析以及双栈的支持。

前提条件

注意:脚本是基于RouterOS v6.46.4 编写的,大于小于此版本都可能导致一些命令问题

确认正确的公网地址

IPv4验证方法:
脚本提取 (WinBox --> IP --> Address List) 内指定接口的IP地址进行解析
ROS终端运行:/ip address get [/ip address find interface=接口名称] address
IPv6验证方法:
脚本提取 DHCPv6 Client 获取的 Prefix 并加上指定的IPv6后缀进行解析
ROS终端运行:/ipv6 dhcp-client get [find interface=接口名称] status
查看读出的数据是否为公网地址,

提前新建子域名

在 CloudFlare 新建需要解析的子域名,若需要解析IPv6 和双栈还需要建立IPv4同名子域名和单独子域名,单独子域名用于IPv6是否更新的判断
  1. ipv4.hscbook.com(A记录)
  1. ipv4.hscbook.com(AAAA记录)
  1. ipv6.hscbook.com(AAAA记录)

建立脚本

使用 WinBox 客户端连接至 RouterOS ;依次 System --> Scripts 进入脚本列表,新建一个名为DDNS_CloudFlare 脚本,将下面内容复制粘贴。
######################################################################### # ================================================== # # $ Mikrotik RouterOS update script for CloudFlare $ # # ================================================== # # Credits for Samuel Tegenfeldt, CC BY-SA 3.0 # # Modified by kiler129 # # Modified by viritt # # Modified by hscpro # ######################################################################### ################# 程序配置信息 ################# #调试信息 true/false :local CFDebug "false" #IPV4使用的接口 :global WANInterface4 "pppoe-out1" #IPV6使用的接口 :global WANInterface6 "pppoe-out1" #IPV6后缀("::"解析到RouterOS;可填写局域网内LAN固定后缀解析到内网某个设备,) :local LANipv6end ":xxxx:xxxx:xxxx:xxxx" #TTL :local CFttl "120" #主域名 :local CFzone "hscbook.com" #IPv4子域名 :local CFdomain "ipv4.hscbook.com" :local CFdomainid "087dxxxxxxxxxxxxxxxxxxxxxxxxxxxx" #双栈IPv6域名ID :local CFdomainid46 "8adcxxxxxxxxxxxxxxxxxxxxxxxxxxxx" #IPv6子域名 true/false :local switchv6 "true" :local CFdomain6 "ipv6.hscbook.com" :local CFdomainid6 "f100xxxxxxxxxxxxxxxxxxxxxxxxxxxx" #CloudFlare账号与APIKEY :local CFemail "xxxxx@xxxxxx.com" :local CFtkn "101fbxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" :local CFzoneid "c25abxxxxcxxxxxxxxxxxxxxxxxxxxxx" ################# 内部变量 ################# #ipv4 :local currentIP "" :local resolvedIP "" :global WANip "" #ipv6 :local currentIP6 "" :local resolvedIP6 "" :global WANip6 "" ################# 解析和设置IP变量 ################# #获取公网IPv4 :set currentIP [/ip address get [/ip address find interface=$WANInterface4 ] address]; :set WANip [:pick $currentIP 0 [:find $currentIP "/"]]; #获取域名IPv4 :set resolvedIP [:resolve $CFdomain]; #获取公网IPv6(DHCP方式)以及域名IPv6 :if ([/ipv6 dhcp-client get [find interface=$WANInterface6] status] = "bound") do={ :if ([/ipv6 dhcp-client get [find interface=$WANInterface6 status=bound] prefix] != "true") do={ :set currentIP6 [/ipv6 dhcp-client get [find interface=$WANInterface6 status=bound] prefix]; #IPv6地址=公网IPv6前缀+设定的后缀 :set WANip6 ([:pick $currentIP6 0 [:find $currentIP6 "::/"]] . $LANipv6end); :set resolvedIP6 [:resolve $CFdomain6]; }; } else={ :log info ("CF: 本机没有启用IPv6或配置不正确") :set switchv6 "false" } ################# 生成 CloudFlare API 链接 (v4) ################# #IPv4 :local CFurl4 "<https://api.cloudflare.com/client/v4/zones/>" :set CFurl4 ($CFurl4 . "$CFzoneid/dns_records/$CFdomainid"); #IPv6 :local CFurl46 "<https://api.cloudflare.com/client/v4/zones/>" :local CFurl6 "<https://api.cloudflare.com/client/v4/zones/>" :if ($switchv6 = "true") do={ :set CFurl46 ($CFurl46 . "$CFzoneid/dns_records/$CFdomainid46"); :set CFurl6 ($CFurl6 . "$CFzoneid/dns_records/$CFdomainid6"); }; ################# 将调试信息写入日志 ################# :if ($CFDebug = "true") do={ :log info ("CF: 调试模式打开") :log info ("CF: 解析域名 $CFdomain") :log info ("CF: 域名解析IPv4 $resolvedIP") :log info ("CF: 当前公网IPv4 $WANip") :log info ("CF: 使用的API地址v4 $CFurl4&content=$WANip") :if ($switchv6 = "true") do={ :log info ("CF: 域名解析IPv6 $resolvedIP6") :log info ("CF: 当前公网IPv6 $WANip6") :log info ("CF: 使用的API地址v6 $CFurl6&content=$WANip") }; :put "Get CFdomainid: curl -X GET \\"<https://api.cloudflare.com/client/v4/zones/$CFzoneid/dns_records\\>" -H \\"X-Auth-Email: $CFemail\\" -H \\"X-Auth-Key: $CFtkn\\" -H \\"Content-Type: application/json\\" | python -mjson.tool" }; ################# IPv4比较和更新域名记录 ################# :if ($resolvedIP != $WANip) do={ :log info ("CF: 正在更新 IPv4 解析地址 $CFdomain = $WANip") /tool fetch http-method=put mode=https url="$CFurl4" http-header-field="X-Auth-Email:$CFemail,X-Auth-Key:$CFtkn,content-type:application/json" as-value output=user http-data="{\\"type\\":\\"A\\",\\"name\\":\\"$CFdomain\\",\\"content\\":\\"$WANip\\",\\"ttl\\":$CFttl,\\"proxied\\":false}" #/ip dns cache flush 执行间隔时大于TTS一倍可免于清理dns(TTS120->5m TTS300->10m) } else={ :log info "CF: IPv4公网地址与解析的地址匹配无需更新!" } ################# IPv6比较和更新域名记录 ################# :if ($switchv6 = "true") do={ :if ($resolvedIP6 != $WANip6) do={ #双栈 :log info ("CF: 正在更新 IPv6 解析地址 $CFdomain = $WANip6") /tool fetch http-method=put mode=https url="$CFurl46" http-header-field="X-Auth-Email:$CFemail,X-Auth-Key:$CFtkn,content-type:application/json" as-value output=user http-data="{\\"type\\":\\"AAAA\\",\\"name\\":\\"$CFdomain\\",\\"content\\":\\"$WANip6\\",\\"ttl\\":$CFttl,\\"proxied\\":false}" #单IPv6域名 :log info ("CF: 正在更新 IPv6 解析地址 $CFdomain6 = $WANip6") /tool fetch http-method=put mode=https url="$CFurl6" http-header-field="X-Auth-Email:$CFemail,X-Auth-Key:$CFtkn,content-type:application/json" as-value output=user http-data="{\\"type\\":\\"AAAA\\",\\"name\\":\\"$CFdomain6\\",\\"content\\":\\"$WANip6\\",\\"ttl\\":$CFttl,\\"proxied\\":false}" #/ip dns cache flush } else={ :log info "CF: IPv6公网地址与解析的地址匹配无需更新!" } }

配置脚本

在 CloudFlare 域名主页的最下面 API 处
  1. 将 Zone ID 填入脚本的 CFzoneid 变量
  1. 点击 Get your API token 获取 API token 填入脚本的 CFtkn 变量
  1. 将 CloudFlare 的邮箱账号填入 CFemail 变量
根据三项信息套入 url -X GET \\"<https://api.cloudflare.com/client/v4/zones/$CFzoneid/dns_records\\>" -H \\"X-Auth-Email: $CFemail\\" -H \\"X-Auth-Key: $CFtkn\\" -H \\"Content-Type: application/json\\" | python -mjson.tool" 并在 linux 终端中运行可取得子域名的 CFid 并填入 CFdomainid 变量
其他变量根据注释以实际情况自行修改后点击 Run Script 运行脚本测试,查看系统日志无报错即可

创建任务计划

修改好脚本后使用 WinBox 客户端连接至 RouterOS ;依次 System --> Scheduler进入任务计划列表新建一个任务计划间隔时间建议为 TTL 变量的两倍,内容为 /system script run "DDNS_CloudFlare";

END

参考文档:MikroTik Wiki
获取 CFid 可使用 API 调试工具,例:Postwoman(ApiDebug)
  • RouterOS
  • Hexo自动部署博客脚本,具有微信确认、部署前预览确认的功能Nginx 结合又拍云反代理 Google Analytics 加速国内访问