Press "Enter" to skip to content

Mikrotik DHCP Hostname to DNS

In this tutorial, we will explore how to configure your local area network (LAN) to allow you to easily find DHCP-hosted devices by their hostnames, eliminating the need to remember IP addresses.

Add this script on IP > DHCP Server > DHCP > defconf > Scripts:

Script

# DNS TTL to set for DNS entries
:local dnsttl "00:15:00";

###
# Script entry point
#
# Expected environment variables:
# leaseBound        1 = lease bound, 0 = lease removed
# leaseServerName   Name of DHCP server
# leaseActIP        IP address of DHCP client
# leaseActMAC       MAC address of DHCP client
###

# "a.b.c.d" -> "a-b-c-d" for IP addresses used as replacement for missing host names
:local ip2Host do=\
{
	:local outStr
	:for i from=0 to=([:len $inStr] - 1) do=\
	{
		:local tmp [:pick $inStr $i];
		:if ($tmp =".") do=\
		{
			:set tmp "-"
		}
		:set outStr ($outStr . $tmp)
	}
	:return $outStr
}

:local mapHostName do={
# param: name
# max length = 63
# allowed chars a-z,0-9,-
	:local allowedChars "abcdefghijklmnopqrstuvwxyz0123456789-";
	:local numChars [:len $name];
	:if ($numChars > 63) do={:set numChars 63};
	:local result "";

	:for i from=0 to=($numChars - 1) do={
		:local char [:pick $name $i];
		:if ([:find $allowedChars $char] < 0) do={:set char "-"};
		:set result ($result . $char);
	}
	:return $result;
}

:local lowerCase do={
# param: entry
	:local lower "abcdefghijklmnopqrstuvwxyz";
	:local upper "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
	:local result "";
	:for i from=0 to=([:len $entry] - 1) do={
		:local char [:pick $entry $i];
		:local pos [:find $upper $char];
		:if ($pos > -1) do={:set char [:pick $lower $pos]};
		:set result ($result . $char);
	}
	:return $result;
}

:local token "$leaseServerName-$leaseActMAC";
:local LogPrefix "DHCP2DNS ($leaseServerName)"

:if ( [ :len $leaseActIP ] <= 0 ) do=\
{
	:log error "$LogPrefix: empty lease address"
	:error "empty lease address"
}

:if ( $leaseBound = 1 ) do=\
{
	# new DHCP lease added
	/ip dhcp-server
	#:local dnsttl [ get [ find name=$leaseServerName ] lease-time ]
	network
	:local domain [ get [ find $leaseActIP in address ] domain ]
	#:log info "$LogPrefix: DNS domain is $domain"

	:local hostname [/ip dhcp-server lease get [:pick [find mac-address=$leaseActMAC and server=$leaseServerName] 0] value-name=host-name]
	#:log info "$LogPrefix: DHCP hostname is $hostname"

 #Hostname cleanup
	:if ( [ :len $hostname ] <= 0 ) do=\
	{
		:set hostname [ $ip2Host inStr=$leaseActIP ]
		:log info "$LogPrefix: Empty hostname for '$leaseActIP', using generated host name '$hostname'"
	}
	:set hostname [$lowerCase entry=$hostname]
	:set hostname [$mapHostName name=$hostname]
	#:log info "$LogPrefix: Clean hostname for FQDN is $hostname";

	:if ( [ :len $domain ] <= 0 ) do=\
	{
		:log warning "$LogPrefix: Empty domainname for '$leaseActIP', cannot create static DNS name"
		:error "Empty domainname for '$leaseActIP'"
	}

	:local fqdn ($hostname . "." .  $domain)
	#:log info "$LogPrefix: FQDN for DNS is $fqdn"

		:if ([/ip dhcp-server lease get [:pick [find mac-address=$leaseActMAC and server=$leaseServerName] 0] ]) do={
			# :log info message="$LogPrefix: $leaseActMAC -> $hostname"
			:do {
				/ip dns static add address=$leaseActIP name=$fqdn ttl=$dnsttl comment=$token;
			} on-error={:log error message="$LogPrefix: Failure during dns registration of $fqdn with $leaseActIP"}
		}

} else={
# DHCP lease removed
	/ip dns static remove [find comment=$token];
}

Effect

Every-time new device received an IP Address, the hostname automatically added into Static DNS, including lease expired

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.