-
-
Save benosman/1acb61b61b9b2742e3e727003cd7ef4a to your computer and use it in GitHub Desktop.
MikroTik (RouterOS) script for automatically setting DNS records for clients when they obtain a DHCP lease
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# MikroTik (RouterOS) script for automatically setting DNS records | |
# for clients when they obtain a DHCP lease. | |
# | |
# authors: | |
# SmartFinn <https://gist.github.com/SmartFinn> | |
# elevendroids <https://gist.github.com/elevendroids> | |
:local dnsTTL "00:15:00"; | |
:local token "$leaseServerName-$leaseActMAC"; | |
:local LogPrefix "[dhcp2dns]($leaseServerName | $leaseActMAC)" | |
# Normalize hostname (e.g. "-= My Phone =-" -> "my-phone") | |
# - convert to lowercase | |
# - truncate length to 63 chars | |
# - substitute disallowed chars with a hyphen | |
# param: name | |
:local normalizeHostname do={ | |
:local result; | |
:local isInvalidChar true; | |
:local lower "abcdefghijklmnopqrstuvwxyz"; | |
:local upper "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |
:for i from=0 to=([:len $name]-1) do={ | |
:local char [:pick $name $i]; | |
:if ($i < 63) do={ | |
:if ($char~"[a-zA-Z0-9]") do={ | |
:local pos [ :find $upper $char ]; | |
:if ($pos > -1) do={ :set char [ :pick $lower $pos ] }; | |
:set result ($result . $char); | |
:set isInvalidChar false; | |
} else={ | |
:if (!$isInvalidChar) do={ | |
:set result ($result . "-"); | |
:set isInvalidChar true; | |
}; | |
}; | |
}; | |
}; | |
# delete trailing hyphen | |
:if ($isInvalidChar) do={ | |
:set result [:pick $result 0 ([:len $result]-1)]; | |
} | |
:return $result; | |
}; | |
:if ($leaseBound = 1) do={ | |
# Getting the hostname and delete all disallowed chars from it | |
:local hostName $"lease-hostname"; | |
:local macName; | |
:set hostName [$normalizeHostname name=$hostName]; | |
:set macName [$normalizeHostname name=$leaseActMAC]; | |
# Use MAC address as a hostname if the hostname is missing or contains only | |
# disallowed chars | |
:if ([:len $hostName] = 0) do={ | |
:set hostName $macName; | |
}; | |
# Getting the domain name from DHCP server. If a domain name is not | |
# specified will use hostname only | |
/ip dhcp-server network { | |
:local domainName [get [:pick [find $leaseActIP in address] 0] domain]; | |
:if ([:len $domainName] > 0) do={ | |
# Append domain name to the hostname and macname | |
:set hostName ($hostName . "." . $domainName); | |
:set macName ($macName . "." . $domainName); | |
}; | |
}; | |
:do { | |
/ip dns static { | |
:local entry [ find name=$hostName ] | |
:if ( $entry ) do={ | |
:if ([ get $entry comment ] = $token) do={ | |
:log warning "$LogPrefix: Updating existing entry for $hostName" | |
set $entry address=$leaseActIP ttl=$dnsTTL comment=$token | |
} else={ | |
:log warning "$LogPrefix: Conflicting entry for $hostName already exists, using mac address fallback" | |
:local macEntry [ find name=$macName ] | |
:if ( $macEntry ) do={ | |
:if ([ get $macEntry comment ] = $token) do={ | |
:log warning "$LogPrefix: Updating existing entry for $macName" | |
set $macEntry address=$leaseActIP ttl=$dnsTTL comment=$token | |
} else={ | |
:log warning "$LogPrefix: Conflicting entry for $macName already exists, skipping" | |
} | |
} else={ | |
:log info "$LogPrefix: Adding entry for $macName" | |
add name=$macName address=$leaseActIP ttl=$dnsTTL comment=$token; | |
} | |
} | |
} else={ | |
:log info "$LogPrefix: Adding entry for $hostName" | |
add name=$hostName address=$leaseActIP ttl=$dnsTTL comment=$token; | |
} | |
} | |
} on-error={ | |
:log error "Fail to add DNS entry: $hostName -> $leaseActIP ($leaseActMAC)"; | |
}; | |
} else={ | |
/ip dns static remove [find comment=$token]; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment