Setting Static DNS Record For Each DHCP Lease - MikroTik Script RouterOS
Run this in scheduler and it will add static dns entry for each DHCP lease.
NB: As this script may delete already added static DNS entries, bases on received hostname over DHCP, the script involves a security risk. Use a uniq domain, for example dhcp.yourdomain.com, dynamic.yourdomain.com or similar. If you have to mix static and dynamic DNS entries on exact same domain, see below.
:local topdomain;
:local hostname;
:local hostip;
:set topdomain "dhcp.yourdomain.com";
/ip dhcp-server lease;
:foreach i in=[find] do={
/ip dhcp-server lease;
:if ([:len [get $i host-name]] > 0) do={
:set hostname ([get $i host-name] . "." . $topdomain);
:set hostip [get $i address];
/ip dns static;
:foreach di in [find] do={
:if ([get $di name] = $hostname) do={
:put ("Removing: " . $hostname . " : " . $hostip);
remove $di;
}
}
:put ("Adding: " . $hostname . " : " . $hostip);
/ip dns static add name=$hostname address=$hostip;
}
}
This second script takes another approach. Using TTL as a way to distinguish dynamical added DNS entries and delete those before adding new. Adding hostnames that already exist is denied.
Also old DNS-entries will be removed, when not longer in DHCP-lease. This will prevent messed up DNS-static with a lot of entries.
:local topdomain;
:set topdomain "lan";
:local ttl;
:set ttl "00:59:59";
:local hostname;
:local hostip;
:local free;
/ip dns static;
:foreach a in=[find] do={
:if ([get $a ttl] = $ttl) do={
:put ("Removing: " . [get $a name] . " : " . [get $a address]);
remove $a;
}
}
/ip dhcp-server lease ;
:foreach i in=[find] do={
/ip dhcp-server lease ;
:if ([:len [get $i host-name]] > 0) do={
:set free "true";
:set hostname ([get $i host-name] . "." . $topdomain);
:set hostip [get $i address];
/ip dns static ;
:foreach di in [find] do={
:if ([get $di name] = $hostname) do={
:set free "false";
:put ("Not adding already existing entry: " . $hostname);
}
}
:if ($free = true) do={
:put ("Adding: " . $hostname . " : " . $hostip ) ;
/ip dns static add name=$hostname address=$hostip ttl=$ttl;
}
}
}
Here's another example. This one will only change the DNS information when changes are necessary, and deletes old DNS entries when leases expire. You can also supply "static" hostnames for ethernet addresses. For example
:global shost001122334455 "hostname"
will assign the hostname "hostname" to the IP address of whatever the lease for mac 00:11:22:33:44:55 winds up being.
:local zone "dhcp";
:local ttl "00:05:00"
:local hostname
:local ip
:local dnsip
:local dhcpip
:local dnsnode
:local dhcpnode
/ip dns static;
:foreach i in=[find where name ~ (".*\\.".$zone) ] do={
:set hostname [ get $i name ];
:set hostname [ :pick $hostname 0 ( [ :len $hostname ] - ( [ :len $zone ] + 1 ) ) ];
/ip dhcp-server lease;
:set dhcpnode [ find where host-name=$hostname ];
:if ( [ :len $dhcpnode ] > 0) do={
:log debug ("Lease for ".$hostname." still exists. Not deleting.");
} else={
:local found false
/system script environment
:foreach n in=[ find where name ~ "shost[0-9A-F]+" ] do={
:if ( [ get $n value ] = $hostname ) do={
:set found true;
}
}
:if ( found ) do={
:log debug ("Hostname ".$hostname." is static");
} else={
:log info ("Lease expired for ".$hostname.", deleting DNS entry.");
/ip dns static remove $i;
}
}
}
/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 [ get $i host-name ];
}
:if ( [ :len $hostname ] > 0) do={
:set hostname ( $hostname . "." . $zone );
/ip dns static;
:set dnsnode [ find where name=$hostname ];
:if ( [ :len $dnsnode ] > 0 ) do={
: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;
}
} else={
:log info ("Adding new DNS entry for " . $hostname);
/ip dns static add name=$hostname address=$dhcpip ttl=$ttl;
}
}
}
Credit: wiki.mikrotik.com