Skip to content

Instantly share code, notes, and snippets.

@Nullcaller
Created March 2, 2025 18:47
Show Gist options
  • Save Nullcaller/6ab75a258123e9ff9e9f169d4c0c7781 to your computer and use it in GitHub Desktop.
Save Nullcaller/6ab75a258123e9ff9e9f169d4c0c7781 to your computer and use it in GitHub Desktop.
A MikroTik RouterOS DHCP server lease script that adds MAC-based (XX-XX-XX-XX-XX-XX.lan) and hostname-based (hostname.lan) domains to static DNS records.
:local lanDomain;
:local lanMacDomain;
:local lanHostnameDomain;
:local dhcpRecordComment;
:local sanitizedMAC;
:set lanDomain ".lan";
:local recordHostname;
:local recordAddress;
:local doRemove;
# Only update LAN hostnames on lease bind
:if ($leaseBound = 1) do={
# Fetch DHCP record comment for the assigned address
:foreach a,b in [/ip dhcp lease find address=$leaseActIP status=bound] do={
:set dhcpRecordComment [/ip dhcp lease get $b comment];
}
# Replace ':' with '-' in the MAC address, write to $sanitizedMAC
:for i from=0 to=([:len $leaseActMAC] - 1) do={
:local char [:pick $leaseActMAC $i];
:if ($char = ":") do={
:set $char "-";
}
:set $sanitizedMAC ($sanitizedMAC . $char);
}
# Use sanitized MAC to make a LAN MAC-based domain ("XX-XX-XX-XX-XX-XX.lan")
:set lanMacDomain ($sanitizedMAC . $lanDomain);
# Remove any previous DNS records made for the LAN MAC-based domain
/ip dns static;
:foreach k,v in=[find] do={
:set recordHostname [get $v "name"];
:set recordAddress [get $v "address"];
:if ($recordHostname = $lanMacDomain) do={
remove $v;
:log info "Removed old static DNS entry: $recordHostname => $recordAddress";
}
}
# Add a new DNS record for LAN MAC-based domain
/ip dns static add name="$lanMacDomain" address="$leaseActIP" ttl=300 comment="$dhcpRecordComment";
:log info "Added new static DNS entry: $lanMacDomain => $leaseActIP";
# If hostname isn't empty, proceed to adding LAN hostname-based domain
:if ($"lease-hostname" != "") do={
# Make a LAN hostname-based domain
:set lanHostnameDomain ($"lease-hostname" . $lanDomain);
# Remove previous DNS records made for the LAN hostname-based domain
# except for the ones that have correct IP addresses leased to the hostname
# (for hosts with multiple ethernet interfaces)
/ip dns static;
:foreach k,v in=[find] do={
:set recordHostname [get $v "name"];
:set recordAddress [get $v "address"];
:if ($recordHostname = $lanHostnameDomain) do={
:set doRemove 1;
:foreach a,b in [/ip dhcp lease find host-name=$"lease-hostname" status=bound] do={
:if ($recordAddress = [/ip dhcp lease get $b address]) do={
:set doRemove 0;
}
}
:if ($doRemove=1) do={
remove $v;
:log info "Removed old static DNS entry: $recordHostname => $recordAddress";
}
}
}
# Remove all DNS records matching exact IP and LAN hostname-based domain
/ip dns static;
:foreach k,v in=[find address="$leaseActIP" name="$lanHostnameDomain"] do={
remove $v;
:log info "Removed old static exact DNS entry: $lanHostnameDomain => $leaseActIP";
}
# Add a new DNS record for LAN hostname-based domain
/ip dns static add name="$lanHostnameDomain" address="$leaseActIP" ttl=300 comment="$dhcpRecordComment";
:log info "Added new static DNS entry: $lanHostnameDomain => $leaseActIP";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment