Community discussions

MikroTik App
 
User avatar
sebastia
Forum Guru
Forum Guru
Topic Author
Posts: 1782
Joined: Tue Oct 12, 2010 3:23 am
Location: Antwerp, BE

DHCP server DNS update

Sun Feb 10, 2019 4:31 pm

Hi

I've written a script to update dns when dhcp server issues a lease.

It consists of 3 parts:
* script executed by dhcp server
* two additional script used for mapping of the host name: conversion to lower case and replacement of forbidden characters

The two auxiliary scripts should be loaded on system level, preferably by scheduler on start-up.
:global 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;
}

:global 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;
}

The dhcp server script needs to associated with the server definition. Do replace your home domain name with your value:
{
:global lowerCase;
:global mapHostName;

:local parent ".your.domain.com";
:do {
	:if ([/ip dhcp-server lease get value-name=dynamic [find mac-address=$leaseActMAC]]) do={
		:if ($leaseBound = 1) do={
			:local host [/ip dhcp-server lease get value-name=host-name [find mac-address=$leaseActMAC ]];
			:if ([:len $host] = 0) do={:error "Error: no hostname for $leaseActMAC"};
			:set host [$lowerCase entry=$host];
			:set host [$mapHostName name=$host];
			:local fqdn ($host . $parent);
			:do {
				/ip dns static remove [find address=$leaseActIP];
				/ip dns static add address=$leaseActIP name=$fqdn;
			} on-error={:log error message="Failure during dns registration of $fqdn with $leaseActIP"}
		} else={
			/ip dns static remove [find address=$leaseActIP];
		}
	}
} on-error={:log error message="Look-up by MAC failed: $leaseActMAC"}
}

Additional note: the script only manages dynamic leases. For lease which are made static/fixed, dns should be managed manually.

If you wish to keep it simple and in one location place the auxiliary scripts in the dhcp server script and replace ":global xxxxx" by ":local xxxxx". This will make these scripts private for dhcp script only.

Cheers

Updated:
* take care of corner case "no/emtpy hostname for mac"
* clean-up preexisting assignment
Last edited by sebastia on Mon Feb 11, 2019 10:42 am, edited 1 time in total.
 
User avatar
Jotne
Forum Guru
Forum Guru
Posts: 3297
Joined: Sat Dec 24, 2016 11:17 am
Location: Magrathean

Re: DHCP server DNS update

Mon Feb 11, 2019 8:13 am

Thanks for the script.

How does this script handle host that already has an DNS name? Does it over write the old name or keep the old name?
Also I would like to set every host static at the same time as the DNS is given, would that be possible?
 
User avatar
sebastia
Forum Guru
Forum Guru
Topic Author
Posts: 1782
Joined: Tue Oct 12, 2010 3:23 am
Location: Antwerp, BE

Re: DHCP server DNS update

Mon Feb 11, 2019 10:41 am

Since it's dhcp initiated, it's working on that basis: for existing dns entry with a different ip, it won't touch it. But you could adjust it if you wish?
For same ip, it will clean-up first.


Regarding conversion to static, it's probably possible, but I haven't looked into it.
 
User avatar
sebastia
Forum Guru
Forum Guru
Topic Author
Posts: 1782
Joined: Tue Oct 12, 2010 3:23 am
Location: Antwerp, BE

Re: DHCP server DNS update

Thu Mar 14, 2019 9:06 pm

Update on the dhcp server script
{

# :log info message="leaseBound=$leaseBound, leaseServerName=$leaseServerName, leaseActMAC=$leaseActMAC, leaseActIP=$leaseActIP, lease-hostname=$"lease-hostname"";
:global lowerCase;
:global mapHostName;

# on de-assignment the lease data is already gone (currently) so fqdn is the only way to determine if it's a dynamic assignment
# if parent is reserved for dynamic entries, removal can happen "blindly", see below
:local parent ".dyn.home";

:local host $"lease-hostname";
:if ([:len $host] = 0) do={:error "Error: no hostname for $leaseActMAC"};
:set host [$lowerCase entry=$host];
:set host [$mapHostName name=$host];
:local fqdn ($host . $parent);

:if ($leaseBound = 1) do={
	:do {
		:if ([/ip dhcp-server lease get value-name=dynamic [find mac-address=$leaseActMAC]]) do={
			:log info message="dhcp server: $leaseActMAC -> $host"
			:do {
				/ip dns static add address=$leaseActIP name=$fqdn ttl=10m;
			} on-error={:log error message="Failure during dns registration of $fqdn with $leaseActIP"}
		}
	} on-error={:error "Look-up by MAC failed: $leaseActMAC"}
} else={
	/ip dns static remove [find address=$leaseActIP name=$fqdn];
}
}

With that some changes:
* script is using $"lease-hostname" which is undocumented at this time, but wiki will be updated at some point
* on de-assignment the lease data is already gone (on v6.44) so fqdn is the only way to determine if it's a dynamic assignment
** with domain reserved for dynamic entries only, dns entry removal on dhcp lease removal can be done blindly and safely
* "overwrite" will generate an error in logs and will stop the script, but if static and dynamic configuration is isolated, as explained above, this should not happen
 
RackKing
Member
Member
Posts: 380
Joined: Wed Oct 09, 2013 1:59 pm

Re: DHCP server DNS update

Tue Jul 07, 2020 12:09 am

Thanks for this script.

Quick question - is there any advantage to running this from the script call aka
/system script run DhcpToDns
vs having the whole code in the server script area?

Things all good in 6.47?

Who is online

Users browsing this forum: telecomcraft and 27 guests