MITM-DNS Explained: How It Works and How to Deploy It
In our first post we used a hosts-file edit to kill a popup on one laptop. In the second post we scaled that fix across every store with a DNS server we called mitm-dns. We've had enough people ask how that server actually works that we're walking through how it's built and how to run your own copy. Reach out to support@homemadesoftware.net if you'd like to explore the tool we can deploy the tool for you for free!.
What it actually is
mitm-dns is a DNS server . It listens for regular DNS queries over UDP and TCP, answers the ones it has been told about from a JSON config file, and forwards everything else to real upstream resolvers like Cloudflare or Google. From a device's point of view it's just another DNS server. It only behaves differently for the handful of names you've explicitly listed.
How a request is handled
Every query goes through the same resolver logic:
- Find the closest configured domain: The resolver walks the requested name label by label (
feedback.salesdomain.com, thensalesdomain.com, thencom) until it finds a domain that exists in the config. - Check for a domain-specific upstream: A domain can override where unmatched requests get forwarded, or disable forwarding entirely for anything under it.
- Answer from local records first: If the domain has a matching record for the requested name and type, it answers directly from the config.
- Forward as a last resort: If nothing local matches, the request goes upstream to the configured resolvers. If even that fails, it returns NXDOMAIN.
A background thread reloads the config file on an interval, so editing records doesn't require restarting the server. Every reload is validated against a JSON schema first, so a typo in the file gets logged and ignored instead of taking the server down.
The config file
Everything the server knows lives in one file, config/dns-records.json:
A few things worth knowing about the format:
name:@means the domain itself, anything else is a subdomain of it.type: supports A, AAAA, CNAME, MX, TXT, and NS records.forward_to: set at the top level for the default upstream resolvers, or inside a domain to override it just for that domain. Setting it to an empty list disables forwarding for that domain, so anything not explicitly listed under it returns NXDOMAIN instead of leaking out to the real internet.enabled: can be set on any record to turn it off without deleting it.
Deploying it
This is a DNS server, not a browser extension or a per-laptop script. It needs somewhere to run continuously so every device on a network can query it. Before deploying, you need one of two things: a Linux VM you control, or a machine that can run Docker.
Quickest path: Docker Compose
On any machine with Docker installed, once you have a copy of the source:
Edit config/dns-records.json and the running server picks up the change automatically, no restart needed.
Automated deployment with Ansible
For a dedicated DNS box that real devices will actually point at, we maintain two Ansible playbooks that handle the whole setup, including redirecting real port 53 traffic to the server:
ansible-vm/ — plain Linux VM
Installs the app on the linux server directly
ansible-docker/ — Docker host
Installs the app on the linux server using Docker and docker-compose
To use either one, edit that folder's hosts inventory file with your server's address and SSH details, then run:
If you also want DNS lookups made by the VM itself redirected through mitm-dns, add -e enable_localhost_routing=true to the command.
Pointing devices at it
Once it's running somewhere reachable, wire devices to it the same way we described in the rollout post: set it as the DNS server in your router's DHCP settings so every device on the network picks it up automatically, or set it manually on individual machines that roam off that network.
Did this help you?
Want to try this solution?both Ansible playbooks, and the test suite? Reach out and we'll deploy it for you. If you have a software problem you would like us to look at, we would love to hear from you.
support@homemadesoftware.netFollow us to know more about the exciting products we build: