Calling ZeroTier's API is actually now possible with the new JSON support in RouterOS 7.13+ – older versions will NOT work with script. The code uses /tool/fetch with a user's API token to get a JSON array of ZeroTier members. That's converted to an scripting array using new ":deserialize from=json", and then looped to add static DNS entries to Mikrotik, checking if name already exists.
First, to use ZeroTier API, you need to create a "API Access Tokens" at bottom of https://my.zerotier.com/account . You'll want to keep this someplace safe, but you'll need to use that in the "token=" variable in the script below. You'll also need the ZeroTier "Network ID" for the network you want to "export" DNS entries from. Only one network can be extracted at a time. If network= is not provided, the first running ZeroTier interface is used.
To use it... next add the following function to /system/scripts or scheduler or cut-and-paste it to test:
Code: Select all
:global ZT2DNS do={
:if ($1="help") do={
:put "\$ZT2DNS - updates static DNS on Mikrotik from a ZeroTier network"
:put " usage: \$ZT2DNS token=<api_token> [network=<network_id>] [suffix=<dns_domain>]"
:put " <api_token> is 'API Access Tokens' from https://my.zerotier.com/account "
:put " <network_id> is ZeroTier network ID to use. Default: first running ZT interface"
:put " <suffix> added to name= in DNS entries, must include any leading dot. Default: \"\""
:return [:nothing]
}
:if ([:typeof $token]!="str") do={:error "token= must be specific with a ZeroTier API token"}
:local ztnet $token
:if ([:typeof $network]="str") do={
:set ztnet $network
} else={:set ztnet [/zerotier/interface/get ([/zerotier/interface/find running]->0) network]}
:local dnssuffix $suffix
:local ztmembers [:deserialize from=json ([/tool/fetch url="https://api.zerotier.com/api/v1/network/$ztnet/member" http-header-field="Authorization: token $token" as-value output=user]->"data")]
:foreach k,v in=$ztmembers do={
:foreach ip in=($v->"config"->"ipAssignments") do={
:if ([:len [/ip/dns/static/find name="$($v->"name")$dnssuffix"]]=0) do={
/ip/dns/static/add address=$ip name="$($v->"name")$dnssuffix"
:put "/ip/dns/static add address=$ip name=$($v->"name")$dnssuffix"
} else={:put "# skip: $ip with name $($v->"name")$dnssuffix"}
}
}
}
# v1.2
And full example to call function is:
Code: Select all
$ZT2DNS token="OcKJlkasdkjaasdfSDFASD" suffix=".example.com" network="123abc456cba"
There is a help screen using "$ZT2DNS help" that described the parameters – only token= is required strictly required:
[admin@Mikrotik] > $ZT2DNS help
$ZT2DNS - updates static DNS on Mikrotik from a ZeroTier network
usage: $ZT2DNS token=<api_token> [network=<network_id>] [suffix=<dns_domain>]
<api_token> is 'API Access Tokens' from https://my.zerotier.com/account
<network_id> is ZeroTier network ID to use. Default: first running ZT interface
<suffix> is appended to name= in DNS entries, must include any leading dot (optional)
LMK if you have problem/issues. My old script below has worked, but with new JSON support in 7.13...it's now possible to easily do on Mikrotik itself.
---
FWIW, my less sophisticated version using Linux tools almost makes Mikrotik scripting look friendly (and requires jq [& awk] packages), but this has worked for me to get DNS records for Mikrotik from a ZeroTier network. I manually run it as needed but above Mikrotik script could be /system/scheduler on the Mikrotik itself to update periodically.
Code: Select all
ZT_TOKEN=zerotier-API-token-FROM-my.zerotier.com-AccountPage
ZT_NET=zt-network-id
curl -X GET -H "Authorization: token $ZT_TOKEN" https://api.zerotier.com/api/v1/network/$ZT_NET/member |
jq -r '(.[] | [.config.ipAssignments[], .name]) | @tsv' |
awk 'length($1)>0 && length($2)>0 { print "/ip/dns/static add address="$1" name="$2".zt" } '