Skip to content

Instantly share code, notes, and snippets.

@SharpEdgeMarshall
Last active May 17, 2022 17:15
Show Gist options
  • Save SharpEdgeMarshall/c3d86d228b5e1607122069b60a6ad57a to your computer and use it in GitHub Desktop.
Save SharpEdgeMarshall/c3d86d228b5e1607122069b60a6ad57a to your computer and use it in GitHub Desktop.
Mikrotik DDNS on Cloudflare

Setup

  • create a script (System->scripts) with the content of Mikrotik_DDNS_CF.script

    • replace: <WAN-INTERFACE>, <TOKEN>, <DNS ZONE>, <DOMAIN>, <DOMAIN-ID>
    • permissions: read,write,policy,test
  • create a schedule (System->schedulers) pointing On Event to your script

    • set preferred schedule time (i.e every 5 min)
    • permissions: read,write,policy,test
################# Config variables #################
:global WANInterface;
################# CloudFlare variables #################
:local CFtkn "<TOKEN>"; # Your CloudFlare API token comes here
:local CFrecordType "A";
:local CFzoneid "<DNS ZONE>"; # Your DNS zone ID comes here (a hash of 32 chars)
# An associative array of domain names to domainIds (32 chars each, you'll need to query CF to get them)
:local CFdomains { "<DOMAIN>"="<DOMAIN-ID>" };
# An associative array of domain names to whether you want to enable CF proxying or not
:local CFproxied { "<DOMAIN>"="false" };
#########################################################################
######################## DO NOT EDIT BELOW ############################
#########################################################################
:global ddnslastipCF;
:local ddnsipWAN;
:if ([:typeof $WANInterface]~"(nothing|nil)") do={
:local result [/tool fetch url=https://ifconfig.co http-method=get mode=https as-value output=user];
:if ($result->"status" = "finished") do={
:local ip ($result->"data");
:set ddnsipWAN [:pick $ip 0 [:find $ip "\n"]];
}
} else={
:local result [/ip address find actual-interface=$WANInterface];
:if ([:len $result] > 0) do={
:local ip [/ip address get $result address];
:set ddnsipWAN [:pick $ip 0 [:find $ip "/"]];
}
}
:if ([:typeof $ddnslastipCF]~"(nothing|nil)" ) do={ :set ddnslastipCF 0.0.0.0; } else={ :set ddnslastipCF $ddnslastipCF; }
:if ([:typeof $ddnsipWAN]~"(nothing|nil)" ) do={
:log error ("DDNS-Update: Unable to get public ip, please check.");
} else={
:if ($ddnsipWAN != $ddnslastipCF) do={
:log warn ("DDNS-Update use IP: ".$ddnslastipCF." -> ".$ddnsipWAN);
:foreach domainName,domainId in=$CFdomains do={
:local proxied ($CFproxied->$domainName);
:local url "https://api.cloudflare.com/client/v4/zones/$CFzoneid/dns_records/$domainId";
:local header "Authorization: Bearer $CFtkn,content-type:application/json";
:local data "{\"type\":\"$CFrecordType\",\"name\":\"$domainName\",\"content\":\"$ddnsipWAN\",\"proxied\":$proxied,\"ttl\":120}";
:local result [/tool fetch http-method=put mode=https url=$url http-header-field=$header http-data=$data as-value output=user];
:if ($result->"status" = "finished") do={
:set ddnslastipCF $ddnsipWAN;
:log info ("DDNS-Update IP " . $ddnsipWAN . " Success");
} else={
:log error ("DDNS-Update Error ".$result->status);
}
};
} else={
:log debug "DDNS-Update: IP No Change";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment