Authoritative dnsmasq in a MikroTik container
Navigation
Homepage
Blog
Archive
github
🦣 chaos
📸 photo
Tags
android
boot
dn42
graphics
hardware
homebrew
mikrotik
misc
net
reverse-engineering
samsung-nx
xmpp
Blogroll
bunnie
debugmo.de
jssfr
pagetable.com
xnyhps
yosefk
Georg Lukas, 2026-07-26 19:24
This post is about setting up and configuring a<br>dnsmasq<br>container on a MikroTik RouterOS device to be used as an authoritative DNS<br>server and a forwarding cache at the same time.
Introduction
MikroTik Containers
Installing a dnsmasq container
Dual-use dnsmasq
Introduction
Recently I joined DN42, a world-wide overlay network<br>created for experimenting with IP routing and for connecting communities,<br>hack-spaces, and networking nerds who are not allowed 😜 to break the real<br>Internet.
I wanted to play on hard mode, so I configured the DN42 tunnels in a<br>VRF on my home<br>lab switch, a MikroTik RB4011. And of course I wanted to provide<br>authoritative DNS<br>for my .dn42 zone from the same switch.
MikroTik routers come with a built-in<br>DNS service, but it<br>can't act as an authoritative server, and there is a shared DNS cache for all<br>clients, which would leak my home lab to DN42.
I already run prosody and<br>iperf on my switch, so the "obvious" "solution" was to add another container.
MikroTik Containers
MikroTik routers with ARM and ARM64 CPUs support Docker<br>containers. The manufacturer<br>strongly recommends using external USB / SD card storage to not wear out<br>internal flash. Ignoring that recommendation might cause the flash in your<br>router to fail and turn the router into an expensive paperweight .
The RB4011 doesn't have USB or SD ports, and<br>adding NVMe looks complicated.<br>It is possible to use the<br>Storage package to mount remote<br>disks, but I hate circular dependencies between my devices. Then again,<br>people reports millions of flash writes,<br>so I'm going to YOLO my containers on the internal 512MB flash, using<br>/docker for the images and volumes.
Nevertheless, if you look for a MikroTik router to run containers, maybe<br>pick one with ARM64 and a physical storage port.
Enabling containers requires a walk to the switch<br>to ensure physical presence, and will increase your attack surface. Then we<br>can configure it to fetch from Docker Hub, which gives us access to some<br>117k ARM images:
/container config<br>set registry-url=https://registry-1.docker.io tmpdir=/docker
Installing a dnsmasq container
I've settled with the<br>dockurr/dnsmasq image based on<br>Alpine which needs around 12MB of flash space. It accepts DNS1 to DNS4<br>from the environment and allows to bind-mount /etc/dnsmasq.d for additional<br>config files:
/container envs<br>add key=DNS1 list=ENV_DNSMASQ value=fd42:d42:d42:54::1<br>add key=DNS2 list=ENV_DNSMASQ value=fd42:d42:d42:53::1<br>/container mounts<br>add dst=/etc/dnsmasq.d list=MOUNT_DNSMASQ_DNSMASQD src=/docker/dnsmasq-dnsmasq.d<br>/container<br>add remote-image=dockurr/dnsmasq name=dn42-dnsmasq \<br>envlists=ENV_DNSMASQ mountlists=MOUNT_DNSMASQ_DNSMASQD \<br>root-dir=/docker/images/dnsmasq interface=veth5 start-on-boot=yes
The two upstream servers are taken from the<br>DN42 anycast DNS.
The veth5 interface is a virtual interface bridged into my DN42 LAN on<br>a dedicated dn42 VRF. I've added two addresses to veth5, ::2 for<br>the authoritative DNS, and ::53 for the forwarder. Initially, I only had one<br>address, but dnsmasq refuses to operate a DNS forwarder on the same<br>IP/interface as an authoritative server.
/inteface bridge<br>add comment="dn42 bridge with containers" name=dn42-bridge<br>/ipv6 address<br>add address=fd16:9939:ecc0::1/64 advertise=no interface=dn42-bridge<br>/ip vrf<br>add interfaces=snip>,dn42-bridge name=dn42<br>/inteface veth<br>add address=fd16:9939:ecc0::2/64,fd16:9939:ecc0::53/64 comment="DN42 dnsmasq" \<br>gateway6=fd16:9939:ecc0::1 name=veth5<br>/interface bridge port<br>add bridge=dn42-bridge interface=veth5
Note: don't add the veth to your VRF, or you'll end up with<br>"port is already slave"!
When you add the container, RouterOS will download and extract the image in the<br>background. Later you can update it with /container/update - both will show<br>the download progress in the UI:
/container update dn42-dnsmasq<br>/container print<br>*snip*<br># NAME ROOT-DIR INTERFACE CONTAINER-SIZE TAG<br>;;; downloading layer 0/6 0%/7.7M<br>3 E dn42-dnsmasq /docker/images/dnsmasq veth5 7.7MiB registry-1.docker.io/dockurr/dnsmasq:latest<br>*snip*
Dual-use dnsmasq
dnsmasq strictly separates authoritative DNS (being the main DNS server for<br>a specific domain) and forwarding DNS (providing DNS responses for whatever<br>a client is asking for). Normally, when you run dnsmasq on a router, you can<br>configure it to be authoritative on the WAN interface and forwarding on the<br>LAN interface.
If you misconfigure it, it will return Host not found: 5(REFUSED) for remote<br>domains, and/or will fail to return a SOA for your domain.
When we run it in a container, we could either add two different virtual<br>interfaces, or we set up two different addresses for the two...