MikroTik Router OS lacks a built-in dynamic DNS service that automatically generates and update DNS records for DHCP clients. This guide provides a workaround to create and update DNS (FQDNS) records for DHCP clients using a simple script that runs on the MikroTik router. The script will be triggered by DHCP lease events, allowing it to create or update DNS records based on the client's hostname, IP address and DHCP network domain.
Step 1: Configure DHCP Networks
Go to IP -> DHCP-Server -> Networks and add a domain name for your DHCP network. This will be used to create FQDNs for the DHCP clients.
Step 2: Configure DHCP Script
Go to IP -> DHCP-Server -> DHCP and set the "Lease Script" to the "dhcp-lease-script". This script will be executed every time a DHCP lease is created, renewed, or removed.
Step 3: Create the DHCP Lease Script
Go to System -> Scripts and create a new script named "dhcp-lease-script" with the following content:
:local DHCPtag
:set DHCPtag "#DHCP"
:if ( [ :len $leaseActIP ] <= 0 ) do={ :error "empty lease address" }
:if ( $leaseBound = 1 ) do={
:local ttl
:local domain
:local hostname
:local dnsname
:local fqdn
:local leaseId
:local comment
:local devicename
:local convert ({})
:local validChars "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890-"
/ip dhcp-server
# Get ttl from DHCP server configuration.
:set ttl [ get [ find name=$leaseServerName ] lease-time ]
network
# Get domain from DHCP network configuration.
:local foundNetworks [find $leaseActIP in address]
:set domain [get [:pick $foundNetworks ([:len $foundNetworks] - 1)] domain];
.. lease
:set leaseId [ find address=$leaseActIP ]
# Check for multiple active leases for the same IP address. It's weird and it shouldn't be, but just in case.
:if ( [ :len $leaseId ] != 1) do={
:log info "DHCP2DNS: not registering domain name for address $leaseActIP because of multiple active leases for $leaseActIP"
:error "multiple active leases for $leaseActIP"
}
:set hostname [ get $leaseId host-name ]
:set comment [ get $leaseId comment ]
/
# Get device name from DHCP lease comment
:set devicename $comment
:if ( [ :len $devicename ] <= 0 ) do={
:set devicename $hostname
}
# Check device name for invalid characters
:for validCharsIndex from=0 to=([:len $validChars] - 1) do={
:local validChar [:pick $validChars $validCharsIndex]
:set ($convert->($validChar)) ($validChar)
}
:set ($convert->("_")) ("-")
:set ($convert->(" ")) ("-")
:for i from=0 to=([:len $devicename] - 1) do={
:local char [:pick $devicename $i]
:local converted ($convert->"$char")
:local convertedType [:typeof $converted]
:if ($convertedType = "str") do={
:set $char $converted
} else={
:set $char ""
}
:set dnsname ($dnsname.$char)
}
# Set FQDN
:if ( [ :len $dnsname ] <= 0 ) do={
:log error "DHCP2DNS: not registering domain name for address $leaseActIP because of empty lease host-name or comment"
:error "empty lease host-name or comment"
}
:if ( [ :len $domain ] <= 0 ) do={
:log error "DHCP2DNS: not registering domain name for address $leaseActIP because of empty network domain name"
:error "empty network domain name"
}
:set fqdn "$dnsname.$domain"
/ip dns static
:if ( [ :len [ find name=$fqdn and address=$leaseActIP and disabled=no ] ] = 0 ) do={
:log info "DHCP2DNS: registering static domain name $fqdn for address $leaseActIP with ttl $ttl"
add address=$leaseActIP name=$fqdn ttl=$ttl comment=$DHCPtag disabled=no
} else={
:log error "DHCP2DNS: not registering domain name $fqdn for address $leaseActIP because of existing active static DNS entry with this name or address"
}
/
} else={
/ip dns static
:local dnsDhcpId
:set dnsDhcpId [ find address=$leaseActIP and comment=$DHCPtag ]
:if ( [ :len $dnsDhcpId ] > 0 ) do={
:log info "DHCP2DNS: removing static domain name(s) for address $leaseActIP"
remove $dnsDhcpId
}
/
}
Credits
https://indibit.de/mikrotik-dns-namensaufloesung-fqdn/
https://gist.github.com/SmartFinn/acc7953eaeb43cece034