2019 / 09 / 11 - article

Conditional DNS for multiple intranet upstreams with Dnsmasq

I recently had the need to use my workplace’s internal DNS to access its internal services, but this DNS also forwards queries it can’t answer to an upstream DNS.

This is annoying, as it bypasses my own intranet’s DNS, which gives me access to my own internal services, and also block ads, trackers and bloat through an installed PiHole server.

My system’s DNS client, like most, doesn’t support conditional forwarding, so I either have my workplace or my own intranet, but not both.

What I need

I need something lightweight (it will constantly run on my desktop, I don’t want to drain my battery or consume power for nothing).

I need to have the ability to add a DNS resolver for a given TLD, and add a DNS resolver list for defaults.

Additionally, I wanted to also resolve the local TLD as 127.0.0.1 for every query.

Dnsmasq

Dnsmasq provides Domain Name System (DNS) forwarder, Dynamic Host Configuration Protocol (DHCP) server, router advertisement and network boot features for small computer networks, created as free software.

https://en.wikipedia.org/wiki/Dnsmasq

We need a DNS forwarder, which is what Dnsmasq does.

It bundles a few other features we don’t need, but thankfully, we’re able to disable them.

Configuring it

The configuration file is located at /etc/dnsmasq.conf on my environment.

General configuration

The first thing is to disable every other service than DNS, which is done with no-dhcp-interface=.

I’ll set my general-purpose upstream resolvers in /etc/resolv.conf, starting with my PiHole.

nameserver 10.0.10.1
nameserver 1.1.1.1
nameserver 1.0.0.1

I want dnsmasq to always query my own DNS, and only if not available, to query CloudFlare ones.

This can be configured with the key strict-order in the Dnsmasq configuration file.

That means that, in the rare cases in which I’m not logged onto my intranet’s VPN, I’ll need to wait for the query to the first nameserver to timeout before getting my DN.

Right now, the dnsmasq configuration file looks like this.

no-dhcp-interfaces=
strict-order

Mapping TLDs to addresses

I’ll start by adding the configuration to resolve .local domains to 127.0.0.1.

This is done with address=/local/127.0.0.1.

This is the only TLD I wanted to map to an address, so let’s start with conditional upstreams.

Mapping TLD querying to upstreams

The first TLD I want to resolve differently is my workplace’s intranet.

The other TLD I want to resolve is my own intranet’s one.

I just need to add the two following clauses to the Dnsmasq configuration file.

server=/work/10.0.1.3
server=/space/10.0.10.1

And that is all I need!

Final configuration file

My final dnsmasq.conf is the following, and works just fine.

no-dhcp-interface=
strict-order

address=/local/127.0.0.1

server=/work/10.0.1.3
server=/space/10.0.10.1