What I'm up to these days

Making my DNS servers talk to one another


My home network done in gns3 My home network is pretty cool. I have 4 OpenWRT devices, 2 routers and 2 APs, across 2 households joined together through wireguard site-to-site VPN. Everything is cheap, easy and fun, which is what I expect from my Linux devices. Each router has a static route set up so clients on either network can forward packets between subnets without having to know anything about VPNs. Other than the poor upload speed from my ISP everything works surprisingly well.

There was just one rub, I couldn't use DNS between each network. What's the point in having computers if you've got to go around remembering long IP addresses? DNSmasq's DNS server makes life livable by giving all your local network computers easy to remember host names. On one network I can ping piprinter.lan but on the other network I'd need to resort to ping 192.168.1.156, and that's after doing something drastic like manually looking up the IP address on my router's web interface.

There's a few solutions to this problem. One would be to use a centralized server that could keep track of DNS and DHCP assignments for the entire network. That would involve either more hardware, or less redundancy (barring a hot standby situation). More hardware in the form of a 3rd device that both the routers would talk to, or less redundancy by making one router completely dependent on the other for DNS and DHCP. That's not going to fly with my setup (it's cheap and easy remember?). So instead I went with the anoother solution: having both DNS servers talk each other only when they need to look up hosts on each other's LANs.

Talk to me - DNSmasq upstream sever definitions

We are going to configure each DNS server to speak to each other when they need to look up their respective local domains. To do this we need to accomplish the following

  1. Set up separate local domains for each router
  2. Set each DNSmasq server as an upstream server for their respective domains
  3. Disable DNS rebinding protection for our local domains

This lan is my lan and that lan is your lan

OpenWRT uses the .lan domain by default. We're going to look up domain names when their outside of our domain, and so we can't both be using the same domain name. Our separate lans will need a separate domain name each.

config DNSmasq
    option local /<yourdomaingoeshere>.lan/
    option domain <yourdomaingoeshere>.lan

Notice that there's two settings here, local and domain. Domain actually sets your domain name, so what's local do? The local option tells DNSmasq to try appending the given domain name to any queries that are just single words lacking any domain suffix. E.g a DNSmasq server with the setting option local /allmycatsarecool.lan/ that received the query "nyan" would append the domain given in the option to make "nyan.allmycatsarecool.lan".

For me I chose reddwarf and holly as the domains for my two lans.

DNSmasq's upstream --server option

One router needs to be told to lookup domains on the other site through the other router's DNS server. DNSmasq lets us specify upstream server for specific domain names. We're going to use that option to specify reddwarf.lan should be looked up at reddwarf.lan's router and holly.lan should be looked up at holly.lan's router.

Configuring DNSmasq on OpenWRT is a two window operation: You need one window with the man page for DNSmasq and another browser window with OpenWRT's /etc/config/dhcp page

Looking first in the manual for DNSmasq we see that --server has the ability to specify certain upstream servers for certain domains. Say if we want only google's DNS server when we resolve google it would look like this on the command line for DNSmasq --server "/google.com/8.8.8.8". Looking at the OpenWRT page we see this translates into OpenWRT's UCI configuration as list server '/google.com/8.8.8.8' line in the DNSmasq config.

Putting it all together we can now specify our upstream servers.

config DNSmasq
        ...
        list server '/google.com/8.8.8.8'
        list server '/holly.lan/192.168.8.1'
        list server 1.1.1.1
        list server 1.0.0.1
        ...

After doing the same on our other router and restart DNSmasq (service DNSmasq restart) things should work, right?

DNS rebinding attack mitigation stops us

When I first did this nothing worked. I had to investigate a little to find out what was going. To do so I temporarily enabled logging to a file in DNSmasq.

config DNSmasq
    ....
    option logqueries '1'
    option logfacility '/tmp/DNSmasq.log'

Then tailing the file (tail -f /tmp/DNSmasq.log) I was able to see DHCP requests, but to get statistics on DNS requests I needed to send SIGUSR1 to the DNSmasq process with kill -SIGUSR1 <DNSmasq pid>. That causes DNSmasq to dump its query statistics to the log and it showed that although requests were being steered correctly to different upstream servers, they were all failing when they were destined for our second LAN. After a while I could see messages telling me that requests were being dropped due to DNS rebinding protection. This is different from getting an NXDOMAIN and so it appeared rather strange in the output of nslookup and dig.

In order to suppress this protection DNSmasq allows you to maintain a list of domains for which it would be ok to return a private IP address. At the DNSmasq command line it looks like --rebind-localhost-ok '/holly.lan/' and in our /etc/config/dhcp file it looks like list rebind_domain '/holly.lan'.

What is a DNS rebinding attack?

DNS rebinding attacks attempt to trick a user into contacting another computer by quickly changing the DNS record for a domain to point somewhere else after a script has been loaded on the victim's machine. This allows a malicious script in a web browser to circumvent same-origin policies, since the host name is still the same but the IP address has changed, as well as gain access to private resources on the victim's local area network.

With DNS rebinding attack mitigation enabled DNSmasq would drop any DNS queries that resolved to local IP addresses as that could be a sign of such an attack occurring.

Conclusion

I've got two DNSmasq servers talking to each other over a VPN. I can now resolve domains that exist on one subnet from another subnet. I was briefly stopped by DNS rebinding attack mitigation, but after some searching I found a solution. The whole experience was easy and fun, because I'm using Linux and Linux is cool.