109Cafe

Automatically register DHCP clients as DNS static records in RouterOS

SysAdmOct 4, 2024

If you want to automatically register DHCP clients as static DNS records in RouterOS, here's the solution.

First, add the script below to your RouterOS.

dhcp-to-dns-static.rsc
{
  # UPDATE_ME
  :local dhcpserver "lan"
   # UPDATE_ME
  :local searchdomain "foo.internal"
  
  :local tolowercase do={
    :local atoz "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz_"
    :local atozUp "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz_"
    :local ptext $1
    :local textlen [:len $ptext]
    :local result ""
    :local valids ""

    :for i from=0 to=($textlen-1) step=1 do={
      :local subs [:pick $ptext $i]
      :local upindex [:find $atozUp $subs]

      :if ($upindex>-1) do={
        :local mapped [:pick $atoz $upindex]
        :set result ($result . $mapped)
      } else={
        :if ($result = "") do {
          return $result
        }
        :set result ($result . "-")
      }
    }
    return $result
  }

  # temporarily mute logging
  /system/logging/disable numbers=[/system/logging/find where topics="info"]

  # mark previous items
  /ip/dns/static/remove [/ip/dns/static/find where comment=dhcp-migration]
  /ip/dns/static/set numbers=[/ip/dns/static/find where comment=dhcp] comment=dhcp-migration
  
  :local dhcpserverno [/ip/dhcp-server/find where name=$dhcpserver disabled=no]

  :if ($dhcpserverno = "") do={
    return
  }
  
  :local defttl [/ip/dhcp-server/get number=$dhcpserver value-name=lease-time]
  :if ($defttl = "") do={
    :set defttl "00:05:00"
  }
  :local allitems [/ip/dhcp-server/lease/find where active-server=$dhcpserver disabled=no active-address]

  :foreach item in=$allitems do={
    :local itemaddr [/ip/dhcp-server/lease/get number=$item value-name=active-address]
    :local itemname [/ip/dhcp-server/lease/get number=$item value-name=host-name]
    :local ttl $defttl
    :local isdyn [/ip/dhcp-server/lease get number=$item value-name=dynamic]
    :if ($isdyn = false) do={
      :set ttl "1d00:00:00"
    }

    :local findomain [$tolowercase $itemname]

    :if ($itemaddr != "" && $findomain != "") do={
      :local dnsname ($findomain . "." . $searchdomain)
      :local olditem [/ip/dns/static/find name=$dnsname]
      :if ($olditem != "") do={
        /ip/dns/static/set numbers=$olditem type=A match-subdomain=no comment=dhcp address=$itemaddr ttl=$ttl
      } else={
        /ip/dns/static/add name=$dnsname type=A match-subdomain=no comment=dhcp address=$itemaddr ttl=$ttl
      }
    }
  }

  # remove no longer existing items
  /ip/dns/static/remove [/ip/dns/static/find where comment=dhcp-migration]
  /system/logging/enable numbers=[/system/logging/find where topics="info"]
}

Make sure to update the value of dhcpserver and searchdomain to fit your needs.

Now you can manually run the script to register all DHCP clients in the DNS list.

Automation

RouterOS lets you automatically run the script whenever there’s a DHCP lease. Just set the Lease Script for the DHCP Server to:

/system/script/run dhcp-to-dns-static

Make sure the script name maches the name you saved in previous section.