DNS Names For Static DHCP Leases

This post is the last part about my automatically generated configurations and it is about DNS names for static DHCP leases. In my networking setup, my guest WLAN is the only place where I use dynamically assigned DHCP leases. All other networks must be configured.

I was looking for a more or less automated way to keep the static DNS entries up to date and found the examples on the MikroTik website at Setting static DNS record for each DHCP lease

I used it for a while but noticed a few things, which I did not like:

  1. It was noisy in the routers log.
  2. It used NetBIOS names for hosts with dynamic leases so I ended up with some ugly names in my „beautiful“ namespace.
  3. Deleting names for expired DHCP leases did not work properly.

Step by Step

This is the whole guide for this setup to work:

  1. Generate Configuration for Syslog, User-Manager and DNS Servers
  2. Replace MAC Addresses With Labels Using Syslog-NG
  3. User-Manager Setup For Static DHCP
  4. DNS Names For Static DHCP Leases (this part)


I used the script from the MikroTik website (the one at the bottom of the page) and modified it. To get all the global variables containing the MAC addresses, I wrote a shell script which generates all formats of MAC address information I need.

The first step was to change the log messages and levels so it did only show necessary information.

Moreover I removed the part where NetBIOS names were used for otherwise unknown hosts. This way only the configured hosts (existing global variable shost<MAC address> get static DNS entiries.

I modified the host deletion part so it is now working correctly.

The script now runs in the scheduler every 5 minutes and updates the static DNS entries.

RouterOS Script

:local zone "mcnair";
:local ttl "00:05:00"
:local hostname
:local ip
:local dnsip
:local dhcpip
:local dnsnode
:local dhcpnode

:global shost001122AABBCC „client-1"
:global shost334455DDEEFF „client-2"

# Check all existing static DNS entries if they still exist
/ip dns static;
:foreach i in=[ find ] do={
  :local found false
  :local maccomment
  :local hostname
  :set hostname [ get $i name ];
  :set maccomment [ get $i comment ];

# check all current leases if the current DNS entries one is still there
  /ip dhcp-server lease;
  :foreach j in=[ find ] do={
    :local mac
    :set mac [ get $j mac-address ];
    :while ($mac ~ ":") do={
      :local pos [ :find $mac ":" ];
      :set mac ( [ :pick $mac 0 $pos ] . [ :pick $mac ($pos + 1) 999 ] );

    :if ( $maccomment = $mac ) do={
      :set found true;

  :if ( found ) do={
    :log debug ("Lease for " . $maccomment . " (" . $hostname . ") still exists.");
  } else={
    :log info ("Lease expired for " . $hostname . ", deleting DNS entry.");
    /ip dns static remove $i;

# Look for new IP addresses
/ip dhcp-server lease;
:foreach i in=[find] do={
  :set hostname ""
  :local mac
  :set dhcpip [ get $i address ];
  :set mac [ get $i mac-address ];
  :while ($mac ~ ":") do={
    :local pos [ :find $mac ":" ];
    :set mac ( [ :pick $mac 0 $pos ] . [ :pick $mac ($pos + 1) 999 ] );
  :foreach n in=[ /system script environment find where name=("shost" . $mac) ] do={
    :set hostname [ /system script environment get $n value ];
  :if ( [ :len $hostname ] > 0) do={
    :set hostname ( $hostname . "." . $zone );
    /ip dns static;
    :set dnsnode [ find where name=$hostname ];
    :if ( [ :len $dnsnode ] > 0 ) do={
# it exists. Is its IP the same?
      :set dnsip [ get $dnsnode address ];
      :if ( $dnsip = $dhcpip ) do={
        :log debug ("DNS entry for " . $hostname . " does not need updating.");
      } else={
        :log info ("Replacing DNS entry for " . $hostname);
        /ip dns static remove $dnsnode;
        /ip dns static add name=$hostname address=$dhcpip ttl=$ttl comment="mac";
    } else={
# it doesn't exist. Add it
      :log info ("Adding new DNS entry for " . $hostname);
      /ip dns static add name=$hostname address=$dhcpip ttl=$ttl comment="$mac";

Leave a comment

Your email address will not be published. Required fields are marked *