Sunday, 30 March 2025

Upgrading to the Mikrotik RouterBoard RB2011, Part 2 - DHCP

This is Part 2 of my RB2011 series - [here's Part 1](https://blog.themillhousegroup.com/2025/01/upgrading-to-mikrotik-routerboard.html). You can find the [whole series here](https://blog.themillhousegroup.com/search/label/routerboard). ## DNSMasq Replacement First, let's replace the `dnsmasq` instance on the Raspberry Pi (which does DHCP, DNS and ad-blocking via Pi-Hole-style `0.0.0.0` resolution). As mentioned before, this will free up the Pi to just be a server again, rather than a critical bit of network infrastructure, but also: - allow the DHCP pool to be modified from a web UI (easier if using a phone in a pinch) - make the current DHCP client list visible in a browser - allow DHCP modifications without having to restart DNSmasq ### DHCP on RouterOS v7 Some other nice properties of the [Mikrotik DHCP server](https://help.mikrotik.com/docs/spaces/ROS/pages/24805500/DHCP#DHCP-DHCPServer) include: #### Multiple pools with different behaviour - I like the idea of having "trusted" devices (with a known MAC and fixed IP address) getting better bandwidth, and this is entirely possible with the `rate-limit` property of (leases](https://help.mikrotik.com/docs/spaces/ROS/pages/24805500/DHCP#DHCP-Leases) - It would be nice to also represent this status with some bit-flagging in the IP address itself, as per my [cunning scheme](https://blog.themillhousegroup.com/2011/04/ultimate-ubuntu-build-server-guide-part_25.html) #### Event scripting - you can run a [script upon lease assignment or de-assignment](https://help.mikrotik.com/docs/spaces/ROS/pages/24805500/DHCP#DHCP-DHCPServerProperties) - could be handy to trigger presence-like automated behaviour To minimise interruption to network users, we'll do this in a staged manner, gradually moving services over to the RB2011. ### Move to a static IP for the RouterBoard This is critically important, and if you don't do it right, you're highly-likely to end up with the dreaded unreachable router. Ask me how I know... To do this in one fell swoop, switch to the Quick Set tab in the top of the web interface. Make the configuration mode __Router__ but leave the Address Acquisition settings alone - we're not going to be using `ETH1`, for our intents and purposes, it's cursed. Then just fill out the Local Network IP settings you'd like the RB2011 to have, but turn off DHCP Server at this stage (we're not ready for that yet) and NAT - our existing gateway device does NAT for us.
Hit *Apply Configuration*, say a small prayer to `${DEITY}` and reload the page (at the new IP address if you changed it). Give it a minute or two before you punt it across the room... ### DHCP Server with single address pool Next up, we'll set up a DHCP server to do that aspect of what we're currently doing with DNSMasq - a single address pool for unspecified random (a.k.a "guest") devices for which we don't have a mapping, plus a bunch of fixed IPs for known devices. For a smooth switchover, first we'll bring the lease times of everyone getting leases from the Pi *down* to a short interval, to get them roughly "in sync". Backup the old `dnsmasq.conf` on the Pi: ``` % cd /etc % sudo cp dnsmasq.conf dnsmasq.conf.pre-rb2011 ``` Bring the lease time DOWN for everyone, by going into `dnsmasq.conf` and changing the `dhcp-range` (for random/guest devices) and each `dhcp-host` entry (for known devices) like this: ``` dhcp-range=10.240.0.64,10.240.0.96,1h ... dhcp-host=00:11:22:33:86:7e,somebox,10.240.0.100,2h ``` to ``` dhcp-range=10.240.0.64,10.240.0.96,5m ... dhcp-host=00:11:22:33:86:7e,somebox,10.240.0.100,5m ``` Restart dnsmasq for the changes to take effect: ``` pi % sudo service dnsmasq restart ``` Now over on the RB2011, we can run the built-in DHCP Server "wizard" from the SSH prompt: ``` [admin@MikroTik] > /ip/dhcp-server/setup Select interface to run DHCP server on dhcp server interface: bridge Select network for DHCP addresses dhcp address space: 10.0.0.0/8 Select gateway for given network gateway for dhcp network: 10.240.0.1 Select pool of ip addresses given out by DHCP server addresses to give out: 10.240.0.32-10.240.0.63 Select DNS servers dns servers: 10.240.0.200 Select lease time lease time: 1800 [admin@MikroTik] > ``` But then immediately disable it: ``` [admin@MikroTik] > /ip/dhcp-server/print Columns: NAME, INTERFACE, ADDRESS-POOL, LEASE-TIME # NAME INTERFACE ADDRESS-POOL LEASE-TIME 0 dhcp1 bridge dhcp_pool1 30m [admin@MikroTik] > /ip/dhcp-server/disable numbers: 0 ``` We can now fine-tune the config at our leisure, and enable it once we're entirely ready. __Set the `domain` so clients have a FQDN:__ ``` [admin@MikroTik] > /ip/dhcp-server/network/set numbers=0 domain=home.themillhousegroup.com ``` __Ensure each client gets an ARP table entry:__ ``` [admin@MikroTik] > /ip/dhcp-server/set numbers=0 add-arp=yes ``` ### Known MAC addresses I have a reasonably-long list of device MAC addresses (about 30) that I want to have "stable" IP addresses; this is a "static lease" in Mikrotik-speak. A typical dnsmasq host line looks like: ``` dhcp-host=00:11:22:33:86:7e,somebox,10.240.0.100,15m ``` Each line becomes (for example): ``` [admin@MikroTik] > /ip/dhcp-server/lease/add mac-address=00:11:22:33:86:7e comment=somebox address=10.240.0.100 lease-time=900 ``` But note the `hostname` from DNSMasq has just become a comment. To get the nice behaviour that DNSMasq gives us where a DNS entry is created, we need to also add a DNS entry: ``` [admin@MikroTik] > /ip/dns/static/add name=somebox address=10.240.0.100 ttl=900 ``` 30 entries was too much like manual labour for me, so here's a [little shell script in a Gist](https://gist.github.com/themillhousegroup/41fba50b448ba8f10166decbe2fcc890). Feed it your `dnsmasq.conf` and it'll spit out all the configuration lines you'll need to make your Mikrotik work like DNSMasq did; i.e. a static DHCP server lease and a static DNS entry. Paste the output into your RouterOS SSH session, and confirm that you've got a nice list in the UI at _IP_ -> _DNS_ -> _Static_. Once you're all set, we're going to take down dnsmasq's DHCP and bring up the RouterOS service as close-together as possible. To do this, first you'll need to tell dnsmasq to NOT listen on the usual interface. On my Pi running Raspbian Buster, this is unfortunately not something predictable like `eth1`, but rather something you'll need to copy-paste from the output of `ifconfig`; e.g.: ``` pi $ ifconfig enxb827ebfdad60: flags=4163 mtu 1500 inet 10.240.0.200 netmask 255.255.255.0 broadcast 10.240.0.255 ``` Edit `/etc/dnsmasq.conf`, adding that ethernet identifier to the `no-dhcp-interface` line (if there is one) ``` # If you want dnsmasq to provide only DNS service on an interface, # configure it as shown above, and then use the following line to # disable DHCP and TFTP on it. no-dhcp-interface=lo,enxb827ebfdad60 ``` And now it's swap-over time: ``` pi % sudo service dnsmasq restart ``` ``` [admin@MikroTik] > /ip/dhcp-server/enable numbers: 0 ``` Then watch the Pi's `/var/lib/misc/dnsmasq.leases` get shorter and the Mikrotik's _IP_ -> _DHCP Server_ -> _Leases_ start to fill up! Don't forget to backup your settings! The new DHCP responses still point to the Pi for DNS resolution; we'll configure that next time...