Community discussions

 
User avatar
sebastia
Forum Guru
Forum Guru
Topic Author
Posts: 1373
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 Veteran
Forum Veteran
Posts: 940
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?
 
How to use Splunk to monitor your MikroTik Router

MikroTik->Splunk
 
 
User avatar
sebastia
Forum Guru
Forum Guru
Topic Author
Posts: 1373
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: 1373
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

Who is online

Users browsing this forum: No registered users and 4 guests