Skip to content

Instantly share code, notes, and snippets.

@tgranqvist
Last active August 25, 2024 18:10
Show Gist options
  • Select an option

  • Save tgranqvist/d58c1d5bee1fac3a6b444b91b867edb9 to your computer and use it in GitHub Desktop.

Select an option

Save tgranqvist/d58c1d5bee1fac3a6b444b91b867edb9 to your computer and use it in GitHub Desktop.
RouterOS dynamic DNS with Cloudflare API v 4

Dynamic DNS

This is a script I use for dynamic DNS from RouterOS, using the Cloudflare DNS API. Inspired by bayukurnia.com.

Preparations

  1. Get an API token from Cloudflare
  2. Get the identifier for your DNS zone, right sidebar
  3. Call the API to find out the record id

Usage

  1. Set up a DHCP client on your interface of choice
  2. Paste the script below
  3. Replace the Cloudflare variables with your values (see preparations)
  4. Enjoy dynamic DNS!

The script

#--------------------------------------------
# MikroTik DDNS Script | Cloudflare API v4
# Inspired by https://bayukurnia.com/blog/mikrotik-ddns-cloudflare-api/
# See also https://api.cloudflare.com/#dns-records-for-a-zone-update-dns-record
#--------------------------------------------

# Cloudflare variables, adjust with yours
:local cfToken "xxxxxx"
:local cfZoneId "zone_id"
:local cfDnsId "record_id"
:local cfDnsType "A"
:local cfDnsName "dyn.example.org"
:local cfDnsTTL "1"
:local cfDnsProxied "false"

:local cfApiUrl "https://api.cloudflare.com/client/v4/zones/$cfZoneId/dns_records/$cfDnsId"
:local cfHeaders "Authorization: Bearer $cfToken"

if ($bound=1) do={
  :local newIp $"lease-address"

  :log info "Updating dynamic dns: $dnsName is now $newIp"

  # compose payload
  :local cfPayload "{\"type\":\"$cfDnsType\",\"name\":\"$cfDnsName\",\"content\":\"$newIp\",\"ttl\":$cfDnsTTL,\"proxied\":$cfDnsProxied}"

  :do {
    :log info "Delaying to stabilize connection"
    :delay 1500ms
    :local response [/tool fetch http-method="put" url=$cfApiUrl http-header-field=$cfHeaders http-data=$cfPayload as-value output=user]
  
    :if ($response->"status" = "finished") do={
      :log info "DDNS: pointed $dnsName to $newIp"
      :local message "Snickars has new ip: $newIp"
    }
  } on-error {
    :log error "DDNS: failed to change $dnsName to $newIp"
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment