I've been using this for a while. Hopefully someone else finds it useful too. It's not very elegant, but it gets the job done.
On my internal network I prefer to assign domain names to important devices, and because I don't always use mikrotik as the default DNS server (eg I'm on vpn), I sync everything to Cloudflare.
It's two scripts. One copies DHCP entries to static DNS based on comments, and the second script copies static DNS entries to Cloudflare DNS.
DHCP_to_DNS script. This expects you to have the desired domain name as the first thing in the comment section of the DHCP entry, afterwards you can type anything.
So something like "printer.example.com This is my printer". Just change the domain variable to your domain.
Code: Select all
:local domain "example.com"
:foreach k in=[/ip dhcp-server lease find] do={
:local leaseComment [/ip dhcp-server lease get $k comment]
:if ( $leaseComment ~$domain) do={
:local cleanDomain ([:pick $leaseComment 0 [:find $leaseComment "."]].".".$domain)
:put $cleanDomain
:local dhcpAddress [/ip dhcp-server lease get $k address]
:if ([/ip dns static find name=$cleanDomain] = "") do={
:put "not found $cleanDomain"
/ip dns static add name=$cleanDomain address=$dhcpAddress
} else={
:put "found $cleanDomain"
/ip dns static set [find name=$cleanDomain] address=$dhcpAddress
}
}
}
Simply enter your api key, zone id and domain. If the entry exists on CF, it will change it. If it doesn't exits, it will create a new entry for it.
Code: Select all
:local apiToken "<enter api key>"
:local zoneId "<enter zone id>"
:local cfIP 0
:local url 0
:local domain "example.com"
/system script run "JParseFunctions"; global JSONLoad; global JSONLoads; global JSONUnload
:foreach k in=[/ip dns static find] do={
:local dnsName [/ip dns static get $k name]
:if ( $dnsName ~$domain) do={
:local dnsIP [/ip dns static get $k address]
#lookup domain ip online
:do {
:set cfIP [:resolve $dnsName server=1.1.1.1];
} on-error={
:log info "$dnsName not found";
:set cfIP "0";}
#check if record doesn't match local dns
:if (($cfIP != "0") && ($cfIP != $dnsIP)) do={
#get record ID for domain
:set url "https://api.cloudflare.com/client/v4/zones/$zoneId/dns_records?type=A&name=$dnsName";
:global cfresult [/tool fetch url=$url http-method=get as-value output=user http-header-field=("authorization: Bearer " . $apiToken . ", content-type: application/json")];
:global dnsRecordId ([$JSONLoads ($cfresult->"data")]->"result"->0->"id")
#if entry not found, make one
:if ( [:len $dnsRecordId] < 5) do={
:log info "$dnsName not found";
:set url "https://api.cloudflare.com/client/v4/zones/$zoneId/dns_records"
:local newId [/certificate scep-server otp generate minutes-valid=0 as-value;]
/tool fetch url=$url http-method=post as-value output=user http-header-field=("authorization: Bearer " . $apiToken . ", content-type: application/json") http-data=("{\"content\":\"".$dnsIP."\",\"name\":\"".$dnsName."\",\"type\":\"A\",\"id\":\"".$newId->"password"."\",\"proxied\":false}")
#if entry is found update it
} else={
:log info "$dnsName updating";
:set url "https://api.cloudflare.com/client/v4/zones/$zoneId/dns_records/$dnsRecordId"
/tool fetch url=$url http-method=put as-value output=user http-header-field=("authorization: Bearer " . $apiToken . ", content-type: application/json") http-data=("{\"content\":\"".$dnsIP."\",\"name\":\"".$dnsName."\",\"type\":\"A\",\"id\":\"".$dnsRecordId."\",\"proxied\":false}")
}
:set cfresult
:set dnsRecordId
}
}
}
$JSONUnload