Skip to content

Instantly share code, notes, and snippets.

@benyanke
Created June 16, 2019 02:42
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save benyanke/e715a19366823316564135222b94e042 to your computer and use it in GitHub Desktop.
Save benyanke/e715a19366823316564135222b94e042 to your computer and use it in GitHub Desktop.
Mikrotik DHCP-to-DNS Script
# NOT fully complete with all the desired features but it does work
# Suggested usage - place in the system scheduler and run every few minutes
# Set root domain here
:local zone "your.internal.domain.com";
:local ttl "00:00:10"
:local staticTtl "00:00:30"
# TODO : add "nodns" check in static lease comment
# Number of pings used to seperate between multiple address hostnames
# zero to disable ping check function
# currently only takes into account up/down.
# TODO: Make it ping both and check response time, returning the fastest
# TODO: Rewrite to make use of :execute to run pings in parallel
:local pingCount 1
# TODO: Fix bug where old records are not removed from dhcp properly
:local hostname
:local ip
:local dnsip
:local dhcpip
:local dnsnode
:local dhcpnode
# Loop through DNS records to check
/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.");
# :put ("Lease for ".$hostname." still exists. Not deleting.");
} else={
# there's no lease by that name. Maybe this mac has a static name.
: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");
:put ("Hostname ".$hostname." is static");
} else={
:log info ("Lease expired for ".$hostname.", deleting DNS entry.");
:put ("Lease expired for ".$hostname.", deleting DNS entry.");
/ip dns static remove $i;
}
}
}
/ip dhcp-server lease;
# :foreach i in=[find] do={
:foreach i in=[find where disabled=no] 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={
# DNS record 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={
:put ("STOP")
# However, only replace if the new host responds to pings, to ensure
# a dead address isn't replacing a live one
:if ($pingCount > 0) do={
:put ("Checking " . $hostname . " with ping before replacing DNS entry");
# Ping new ip we are attempting to add to DNS record
:local pNew [/ping $dhcpip count=$pingCount];
}
:if ($pingCount = 0 || $pNew = $pingCount) do={
:log info ("Replacing existing DNS entry for " . $hostname);
:put ("Replacing existing DNS entry for " . $hostname);
/ip dns static remove $dnsnode;
/ip dns static add name=$hostname address=$dhcpip ttl=$ttl comment="dhcp autogenerated";
}
}
} else={
# DNS Record doesn't exist. Add it
:log info ("Adding new DNS entry for " . $hostname);
:put ("Adding new DNS entry for " . $hostname);
/ip dns static add name=$hostname address=$dhcpip ttl=$ttl comment="dhcp autogenerated";
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment