ros ddns脚本(clouflare)和动态ip回流脚本
1952 字
10 分钟
ros ddns脚本(clouflare)和动态ip回流脚本
1. Cloudflare ddns脚本 本脚本是基于视频https://youtu.be/cSTHn2gxScY?si=r0p1PdiWqeddCJ01更改而来. 将原本需要用global api token 改为普通api token 首先需要获取获取records_ID,参考原视频。 Linux/unix终端下,
curl -X GET "https://api.cloudflare.com/client/v4/zones/Zone_ID/dns_records" \-H "x-auth-email:email" \-H "x-auth-key:auth-key" \-H "content-type: application/json"新建script,那么填 cf_ddns 如果运行完总是会报红字错误,试试最后加一行空行
# Update Cloudflare DNS IPv4 address script# RouterOS version >= 7.x is required
# ** CONFIGURE SECTION **
# WAN IPv4 interface:local wanif "pppoe-out1"
# Cloudflare section:local email "email":local key "auth-key":local zoneID "Zone_ID":local recordsID "record_ID"
# Domain hostname:local hostName "ddns域名"
# DNS server for resolution:local dnsServer "1.1.1.1"
# ** END OF CONFIGURE SECTION **
# Get WAN interface IPv4 address:local ip4new [/ip address get [/ip address find interface=$wanif] address]:set ip4new [:pick [:tostr $ip4new] 0 [:find [:tostr $ip4new] "/"]]
:if ([:len $ip4new] = 0) do={:log error "[Cloudflare DDNS] Could not get IPv4 for interface $wanif":error "[Cloudflare DDNS] Could not get IPv4 for interface $wanif"}
# Use DNS resolve with specified server to get current IP address of the domain:local resolvedIp [:resolve $hostName server=$dnsServer]
:if ($resolvedIp = "") do={:log error "[Cloudflare DDNS] Could not resolve $hostName using server $dnsServer":error "[Cloudflare DDNS] Could not resolve $hostName using server $dnsServer"}
:log info "[Cloudflare DDNS] DNS resolved IP for $hostName: $resolvedIp":log info "[Cloudflare DDNS] Current WAN IPv4 address: $ip4new"
:if ($ip4new = $resolvedIp) do={:log info "[Cloudflare DDNS] WAN IPv4 address for interface $wanif and DNS resolved IP are the same, no update needed."} else {:log info "[Cloudflare DDNS] WAN IPv4 address for interface $wanif has been changed to $ip4new."
:local url "https://api.cloudflare.com/client/v4/zones/$zoneID/dns_records/$recordsID":local header "X-Auth-Email: $email,Authorization: Bearer $key,Content-Type:application/json":local data "{\"type\":\"A\",\"name\":\"$hostName\",\"content\":\"$ip4new\",\"ttl\":60,\"proxied\":false}"
:log info "[Cloudflare DDNS] URL: $url":log info "[Cloudflare DDNS] HEADER: $header":log info "[Cloudflare DDNS] DATA: $data":log info "[Cloudflare DDNS] Updating host $hostName address."
:local jsonAnswer [/tool fetch http-method=put mode=https http-header-field=$header http-data=$data url=$url as-value output=user]
:if ([:len $jsonAnswer] > 0) do={
/system script run "JParseFunctions"; local JSONLoads; local JSONUnload:local result ([$JSONLoads ($jsonAnswer->"data")]->"success")$JSONUnload
:if ($result = true) do={:log info "[Cloudflare DDNS] Successfully updated IPv4 address to $ip4new."} else {:log error "[Cloudflare DDNS] Error while updating IPv4 address."}} else {:log error "[Cloudflare DDNS] No answer from Cloudflare API."}}pppoe-out1 使用的profile内的On Up部分加上:(末尾留一行空行
:delay 3s/system/script/run cf_ddns2. 动态ip回流脚本 新建script ,名为“dynamic_nat”
:global addold
:global addnew
:set addnew [/interface get [/interface find name="pppoe-out1"] running]
:if ($addnew=true) do={
:set addold [/ip address get [/ip address find dynamic=yes interface="pppoe-out1"] address]
:set addold [:pick $addold 0 ([:len $addold ] -3)]
/ip firewall nat set [/ip firewall nat find comment="dynamic_nat"] dst-address=$addold
}同样的,在pppoe-out1 使用的profile内的On Up部分加上就变成了如下:
#dynamic_nat
:delay 3sexecute "dynamic_nat"
#cf_ddns/system/script/run cf_ddns另外,ros版本大于7.14的话,新建脚本JParseFunctions,作为依赖库。来源参考: https://github.com/Winand/mikrotik-json-parser
# -------------------------------- JParseFunctions ---------------------------------------------------# ------------------------------- fJParsePrint ----------------------------------------------------------------:global fJParsePrint:if (!any $fJParsePrint) do={ :global fJParsePrint do={ :global JParseOut :local TempPath :global fJParsePrint
:if ([:len $1] = 0) do={ :set $1 "\$JParseOut" :set $2 $JParseOut }
:foreach k,v in=$2 do={ :if ([:typeof $k] = "str") do={ :set k "\"$k\"" } :set TempPath ($1. "->" . $k) :if ([:typeof $v] = "array") do={ :if ([:len $v] > 0) do={ $fJParsePrint $TempPath $v } else={ :put "$TempPath = [] ($[:typeof $v])" } } else={ :put "$TempPath = $v ($[:typeof $v])" } }}}# ------------------------------- fJParsePrintVar ----------------------------------------------------------------:global fJParsePrintVar:if (!any $fJParsePrintVar) do={ :global fJParsePrintVar do={ :global JParseOut :local TempPath :global fJParsePrintVar :local fJParsePrintRet ""
:if ([:len $1] = 0) do={ :set $1 "\$JParseOut" :set $2 $JParseOut }
:foreach k,v in=$2 do={ :if ([:typeof $k] = "str") do={ :set k "\"$k\"" } :set TempPath ($1. "->" . $k) :if ($fJParsePrintRet != "") do={ :set fJParsePrintRet ($fJParsePrintRet . "\r\n") } :if ([:typeof $v] = "array") do={ :if ([:len $v] > 0) do={ :set fJParsePrintRet ($fJParsePrintRet . [$fJParsePrintVar $TempPath $v]) } else={ :set fJParsePrintRet ($fJParsePrintRet . "$TempPath = [] ($[:typeof $v])") } } else={ :set fJParsePrintRet ($fJParsePrintRet . "$TempPath = $v ($[:typeof $v])") } } :return $fJParsePrintRet}}# ------------------------------- fJSkipWhitespace ----------------------------------------------------------------:global fJSkipWhitespace:if (!any $fJSkipWhitespace) do={ :global fJSkipWhitespace do={ :global Jpos :global JSONIn :global Jdebug :while ($Jpos < [:len $JSONIn] and ([:pick $JSONIn $Jpos] ~ "[ \r\n\t]")) do={ :set Jpos ($Jpos + 1) } :if ($Jdebug) do={:put "fJSkipWhitespace: Jpos=$Jpos Char=$[:pick $JSONIn $Jpos]"}}}# -------------------------------- fJParse ---------------------------------------------------------------:global fJParse:if (!any $fJParse) do={ :global fJParse do={ :global Jpos :global JSONIn :global Jdebug :global fJSkipWhitespace :local Char
:if (!$1) do={ :set Jpos 0 }
$fJSkipWhitespace :set Char [:pick $JSONIn $Jpos] :if ($Jdebug) do={:put "fJParse: Jpos=$Jpos Char=$Char"} :if ($Char="{") do={ :set Jpos ($Jpos + 1) :global fJParseObject :return [$fJParseObject] } else={ :if ($Char="[") do={ :set Jpos ($Jpos + 1) :global fJParseArray :return [$fJParseArray] } else={ :if ($Char="\"") do={ :set Jpos ($Jpos + 1) :global fJParseString :return [$fJParseString] } else={# :if ([:pick $JSONIn $Jpos ($Jpos+2)]~"^-\?[0-9]") do={ :if ($Char~"[eE0-9.+-]") do={ :global fJParseNumber :return [$fJParseNumber] } else={
:if ($Char="n" and [:pick $JSONIn $Jpos ($Jpos+4)]="null") do={ :set Jpos ($Jpos + 4) :return [] } else={ :if ($Char="t" and [:pick $JSONIn $Jpos ($Jpos+4)]="true") do={ :set Jpos ($Jpos + 4) :return true } else={ :if ($Char="f" and [:pick $JSONIn $Jpos ($Jpos+5)]="false") do={ :set Jpos ($Jpos + 5) :return false } else={ :put "Err.Raise 8732. No JSON object could be fJParseed" :set Jpos ($Jpos + 1) :return [] } } } } } } }}}
#-------------------------------- fJParseString ---------------------------------------------------------------:global fJParseString:if (!any $fJParseString) do={ :global fJParseString do={ :global Jpos :global JSONIn :global Jdebug :global fUnicodeToUTF8 :local Char :local StartIdx :local Char2 :local TempString "" :local UTFCode :local Unicode
:set StartIdx $Jpos :set Char [:pick $JSONIn $Jpos] :if ($Jdebug) do={:put "fJParseString: Jpos=$Jpos Char=$Char"} :while ($Jpos < [:len $JSONIn] and $Char != "\"") do={ :if ($Char="\\") do={ :set Char2 [:pick $JSONIn ($Jpos + 1)] :if ($Char2 = "u") do={ :set UTFCode [:tonum "0x$[:pick $JSONIn ($Jpos+2) ($Jpos+6)]"] :if ($UTFCode>=0xD800 and $UTFCode<=0xDFFF) do={# Surrogate pair :set Unicode (($UTFCode & 0x3FF) << 10) :set UTFCode [:tonum "0x$[:pick $JSONIn ($Jpos+8) ($Jpos+12)]"] :set Unicode ($Unicode | ($UTFCode & 0x3FF) | 0x10000) :set TempString ($TempString . [:pick $JSONIn $StartIdx $Jpos] . [$fUnicodeToUTF8 $Unicode]) :set Jpos ($Jpos + 12) } else= {# Basic Multilingual Plane (BMP) :set Unicode $UTFCode :set TempString ($TempString . [:pick $JSONIn $StartIdx $Jpos] . [$fUnicodeToUTF8 $Unicode]) :set Jpos ($Jpos + 6) } :set StartIdx $Jpos :if ($Jdebug) do={:put "fJParseString Unicode: $Unicode"} } else={ :if ($Char2 ~ "[\\bfnrt\"]") do={ :if ($Jdebug) do={:put "fJParseString escape: Char+Char2 $Char$Char2"} :set TempString ($TempString . [:pick $JSONIn $StartIdx $Jpos] . [[:parse "(\"\\$Char2\")"]]) :set Jpos ($Jpos + 2) :set StartIdx $Jpos } else={ :if ($Char2 = "/") do={ :if ($Jdebug) do={:put "fJParseString /: Char+Char2 $Char$Char2"} :set TempString ($TempString . [:pick $JSONIn $StartIdx $Jpos] . "/") :set Jpos ($Jpos + 2) :set StartIdx $Jpos } else={ :put "Err.Raise 8732. Invalid escape" :set Jpos ($Jpos + 2) } } } } else={ :set Jpos ($Jpos + 1) } :set Char [:pick $JSONIn $Jpos] } :set TempString ($TempString . [:pick $JSONIn $StartIdx $Jpos]) :set Jpos ($Jpos + 1) :if ($Jdebug) do={:put "fJParseString: $TempString"} :return $TempString}}
#-------------------------------- fJParseNumber ---------------------------------------------------------------:global fJParseNumber:if (!any $fJParseNumber) do={ :global fJParseNumber do={ :global Jpos :local StartIdx :global JSONIn :global Jdebug :local NumberString :local Number
:set StartIdx $Jpos :set Jpos ($Jpos + 1) :while ($Jpos < [:len $JSONIn] and [:pick $JSONIn $Jpos]~"[eE0-9.+-]") do={ :set Jpos ($Jpos + 1) } :set NumberString [:pick $JSONIn $StartIdx $Jpos] :set Number [:tonum $NumberString] :if ([:typeof $Number] = "num") do={ :if ($Jdebug) do={:put "fJParseNumber: StartIdx=$StartIdx Jpos=$Jpos $Number ($[:typeof $Number])"} :return $Number } else={ :if ($Jdebug) do={:put "fJParseNumber: StartIdx=$StartIdx Jpos=$Jpos $NumberString ($[:typeof $NumberString])"} :return $NumberString }}}
#-------------------------------- fJParseArray ---------------------------------------------------------------:global fJParseArray:if (!any $fJParseArray) do={ :global fJParseArray do={ :global Jpos :global JSONIn :global Jdebug :global fJParse :global fJSkipWhitespace :local Value :local ParseArrayRet [:toarray ""]
$fJSkipWhitespace :while ($Jpos < [:len $JSONIn] and [:pick $JSONIn $Jpos]!= "]") do={ :set Value [$fJParse true] :set ($ParseArrayRet->([:len $ParseArrayRet])) $Value :if ($Jdebug) do={:put "fJParseArray: Value="; :put $Value} $fJSkipWhitespace :if ([:pick $JSONIn $Jpos] = ",") do={ :set Jpos ($Jpos + 1) $fJSkipWhitespace } } :set Jpos ($Jpos + 1)# :if ($Jdebug) do={:put "ParseArrayRet: "; :put $ParseArrayRet} :return $ParseArrayRet}}
# -------------------------------- fJParseObject ---------------------------------------------------------------:global fJParseObject:if (!any $fJParseObject) do={ :global fJParseObject do={ :global Jpos :global JSONIn :global Jdebug :global fJSkipWhitespace :global fJParseString :global fJParse# Syntax :local ParseObjectRet ({}) don't work in recursive call, use [:toarray ""] for empty array!!! :local ParseObjectRet [:toarray ""] :local Key :local Value :local ExitDo false
$fJSkipWhitespace :while ($Jpos < [:len $JSONIn] and [:pick $JSONIn $Jpos]!="}" and !$ExitDo) do={ :if ([:pick $JSONIn $Jpos]!="\"") do={ :put "Err.Raise 8732. Expecting property name" :set ExitDo true } else={ :set Jpos ($Jpos + 1) :set Key [$fJParseString] $fJSkipWhitespace :if ([:pick $JSONIn $Jpos] != ":") do={ :put "Err.Raise 8732. Expecting : delimiter" :set ExitDo true } else={ :set Jpos ($Jpos + 1) :set Value [$fJParse true] :set ($ParseObjectRet->$Key) $Value :if ($Jdebug) do={:put "fJParseObject: Key=$Key Value="; :put $Value} $fJSkipWhitespace :if ([:pick $JSONIn $Jpos]=",") do={ :set Jpos ($Jpos + 1) $fJSkipWhitespace } } } } :set Jpos ($Jpos + 1)# :if ($Jdebug) do={:put "ParseObjectRet: "; :put $ParseObjectRet} :return $ParseObjectRet}}
# ------------------- fByteToEscapeChar ----------------------:global fByteToEscapeChar:if (!any $fByteToEscapeChar) do={ :global fByteToEscapeChar do={# :set $1 [:tonum $1] :return [[:parse "(\"\\$[:pick "0123456789ABCDEF" (($1 >> 4) & 0xF)]$[:pick "0123456789ABCDEF" ($1 & 0xF)]\")"]]}}
# ------------------- fUnicodeToUTF8----------------------:global fUnicodeToUTF8:if (!any $fUnicodeToUTF8) do={ :global fUnicodeToUTF8 do={ :global fByteToEscapeChar# :local Ubytes [:tonum $1] :local Nbyte :local EscapeStr ""
:if ($1 < 0x80) do={ :set EscapeStr [$fByteToEscapeChar $1] } else={ :if ($1 < 0x800) do={ :set Nbyte 2 } else={ :if ($1 < 0x10000) do={ :set Nbyte 3 } else={ :if ($1 < 0x20000) do={ :set Nbyte 4 } else={ :if ($1 < 0x4000000) do={ :set Nbyte 5 } else={ :if ($1 < 0x80000000) do={ :set Nbyte 6 } } } } } :for i from=2 to=$Nbyte do={ :set EscapeStr ([$fByteToEscapeChar ($1 & 0x3F | 0x80)] . $EscapeStr) :set $1 ($1 >> 6) } :set EscapeStr ([$fByteToEscapeChar (((0xFF00 >> $Nbyte) & 0xFF) | $1)] . $EscapeStr) } :return $EscapeStr}}
# ------------------- Load JSON from arg --------------------------------global JSONLoadsif (!any $JSONLoads) do={ global JSONLoads do={ global JSONIn $1 global fJParse local ret [$fJParse] set JSONIn global Jpos; set Jpos global Jdebug; if (!$Jdebug) do={set Jdebug} return $ret}}
# ------------------- Load JSON from file --------------------------------global JSONLoadif (!any $JSONLoad) do={ global JSONLoad do={ if ([len [/file find name=$1]] > 0) do={ global JSONLoads return [$JSONLoads [/file get $1 contents]] }}}
# ------------------- Unload JSON parser library ----------------------global JSONUnloadif (!any $JSONUnload) do={ global JSONUnload do={ global JSONIn; set JSONIn global Jpos; set Jpos global Jdebug; set Jdebug global fByteToEscapeChar; set fByteToEscapeChar global fJParse; set fJParse global fJParseArray; set fJParseArray global fJParseNumber; set fJParseNumber global fJParseObject; set fJParseObject global fJParsePrint; set fJParsePrint global fJParsePrintVar; set fJParsePrintVar global fJParseString; set fJParseString global fJSkipWhitespace; set fJSkipWhitespace global fUnicodeToUTF8; set fUnicodeToUTF8 global JSONLoads; set JSONLoads global JSONLoad; set JSONLoad global JSONUnload; set JSONUnload}}# ------------------- End JParseFunctions----------------------这样ddns和动态ip脚本就会随着每一次重新pppoe拨号重新运行
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
ros ddns脚本(clouflare)和动态ip回流脚本
https://blog.qiui.net/posts/2025-03-04-ros-ddns-clouflare-ip-21/相关文章智能推荐
1
Cloudflare删除账户级ip规则脚本
网站相关起因, 之前因为用了一些防御规则,生成了近600个ip质询规则,手动删除是要累死人了,就一直没管。正好看到有个批量删除zone级别规则的项目,花了几分钟修改了下好把我以前的这些规则清空。
2
Docker部署Minio--自建s3服务端
软路由NAS部署前准备, mkdir /path-to-data/minio/.minio.sys -p nano /path-to-data/minio/.minio.sys/format.json
3
Fedora kde桌面发行版安装中文输入法
硬件鼓捣fedora的kde桌面版本默认是不带中文输入法的,这里记录下安装的步骤。
4
Fedora43安装howdy
硬件鼓捣在自己的笔记本上安装了很多桌面Linux发行版,最终使用的还是Fedora KDE版本的。一方面是KDE套件美观实用,另一方面是Fedora和Ubuntu这类的包管理用的更习惯些,不像Arch,更新安装命令都是些什么玩意缩写?又大写又小写的乱得不行,纯八股文记忆。
5
禁用insert键
智障公司做的智障功能七年过后,我依旧强烈推荐禁用insert键。在繁重的论文写作相关的过程中,如果误触了这个键位,你的修改成果可能毁于一旦,实际上极易误触(就在delete键上方,退格键右侧)。 这个键唯一的使用意义想必是使用终端时,用特定的ctrl+insert和shift+insert组合...
随机文章随机推荐




