May 23, 2019

Resolve local DHCP hosts using DNS in MikroTik router


I have an intel nuc that I need to carry around from home to office and back. It houses the testing environment of a business application I am working with - a moderately complex Clojure application along with Datomic, PostgreSQL and a bunch of LXD instances of a popular opensource SIP server. My workflow consists of making changes to application in my laptop, deploying the application and associated infrastructure to the nuc using some ansible scripts and finally running the integration tests. Ansible scripts require the remote hosts to be specified with hostnames.

Intel NUC I3
Figure 1. My test machines in it’s neon glory

Both my home network and the office network utilizes DHCP servers for no configuration network connectivity. Unfortunately, the convenience of the DHCP comes with a price that you get no guarantee of a fixed IP address. Even if it’s possible to have a fixed IP address, syncing the IP addresses for the nuc in both networks is a daunting task that I was not willing to take part in. So, the simplest and robust solution was to enable hostname based DNS resolution.

The Problem

My home network router runs on Linux. So enabling hostname based name resolution was as simple as installing dnsmasq and modifying a line or two. It’s nearly hassle free and works everytime. But my office network uses a MikroTik router with some version of their proprietary operating system. There is no way to run dnsmasq in it. Perhaps there is, with metarouter and what not; but I am too noob for that. As far as I remember, the official take on the issue is that it’s an unnecessary security risk; which I completely agree and also disagree for my case. The risk of someone unauthorized connecting to our physical network and spoofing hostnames to steal some data is a pipe-dream at best. I am not someone of that importance! Sigh! 😌

Fortunately, I found that MikroTik has a feature called Lease Script in their DHCP server configuration. You can put a small script in there to bind a new DNS name everytime a host connects to your network. With some inspirations from the internet and wasting a couple of hours with MikroTik’s scripting language, I made an script that serves my purpose.

DHCP Lease Script

:local lanDomain;
:local lanHostname;

:set lanDomain ".lan";

:local tHostname;
:local tAddress;

:if ($leaseBound = 1) do={
    :set lanHostname ($"lease-hostname" . $lanDomain);

    /ip dns static;
    :foreach k,v in=[find] do={
        :set tHostname [get $v "name"];
        :set tAddress [get $v "address"];
        :if ($tHostname = $lanHostname) do={
            remove $v ;
            :log info "Removed old static DNS entry: $tHostname => $tAddress" ;
    /ip dns static add name="$lanHostname" address="$leaseActIP" ;
    :log info "Added new static DNS entry: $lanHostname => $leaseActIP" ;

If you want a similar setup, just copy & paste the content of the script in IP > DHCP Server > Lease Script section and press Apply. If it works successfully, you should be able to reach machines in your network with names like hostname.lan. That’s it.

Tags: Sysadmin , Mikrotik