Setting static DNS record for each DHCP lease
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.
# DNS record for DHCP lease
# Prepare variables in use
:local topdomain;
:local hostname;
:local hostip;
# Configure your domain
: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;
# Remove if DNS entry already exist
:foreach di in [find] do={
:if ([get $di name] = $hostname) do={
:put ("Removing: " . $hostname . " : " . $hostip);
remove $di;
}
}
# Add DNS entry
: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.
# Domain to be added to your DHCP-clients hostname
:local topdomain;
:set topdomain "lan";
# Use ttl to distinguish dynamic added DNS records
:local ttl;
:set ttl "00:59:59";
# Set variables to use
:local hostname;
:local hostip;
:local free;
# Remove all dynamic records
/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 ;
# Check if entry already exist
: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.
: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={
:log info ("Lease expired for ".$hostname.", deleting DNS entry.");
/ip dns static remove $i;
}
}
/ip dhcp-server lease;
:foreach i in=[find] do={
:set dhcpip [ get $i address ];
:if ( [ :len [ get $i host-name ] ] > 0) do={
:set hostname ( [ get $i host-name ] . "." . $zone );
/ip dns static;
:set dnsnode [ find where name=$hostname ];
:if ( [ :len $dnsnode ] > 0 ) do={
# it exists. Is its IP the same?
: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={
# it doesn't exist. Add it
:log info ("Adding new DNS entry for " . $hostname);
/ip dns static add name=$hostname address=$dhcpip ttl=$ttl;
}
}
}