Getting an internally routed subdomain working

(Note: This post is originally from 2017, and is copied to this new site for historical reasons. Opinions, network infrastructure, and other things may have changed since this was first written.)

One of the things those fancy-pants corporate networks do that I’ve always wanted to set up is have an internally routed intranet kind of subdomain. They might call it or, and you’d be able to access certain services or perhaps specific boxes with an FQDN like

Today, I set up for all addresses in my VPN’s subnet, Right at the moment, I’ve only got a handful of servers, so this doesn’t really do me a whole lot of practical good, but it’s a great party trick and a skill that will come in handy should I be put in charge of a network large enough to need this kind of thing.


  • dnsmasq, one (or perhaps more) master server(s) and one for each additional Linux box that doesn’t have NetworkManager or something similar installed. Windows clients and Linux clients with NetworkManager or whatever installed can be made to automatically add the extra DNS information through a directive in OpenVPN’s server config: push "dhcp-option DNS"
  • /etc/hosts.d/, a file that dnsmasq will be configured to exclusively read DNS information from. dnsmasq doesn’t particularly give half a damn exactly what the file is named or what directory it’s in as long as it’s formatted like a hosts file, but it’s configured to read /etc/hosts by default, and I’d rather keep it organized in case I can configure it to consider a whole directory later.
  • At least one fallback DNS server address. If your dnsmasq server doesn’t have an entry for it, it will query the fallback address for you (and cache the result if you’re into that kind of thing) and then forward the result to you. This is the part where you put in Google DNS, or OpenDNS, or both.

Server side

This is my server-side /etc/dnsmasq.conf file:

# these two lines enable DNSSEC related things
# this file path is valid in Ubuntu 16.04, but you might want
# to double check it yourself

# Google DNS

# OpenDNS

# define addresses to listen on
# is not included by default, interestingly

# prevent reading /etc/resolv.conf, which is configured to point to this server
# infinite loops aren't a good thing

# hosts file related. disables reading from /etc/hosts and reads from
# /etc/hosts.d/ instead

expand-hosts and the domain lines are perhaps the most interesting part. Consider these two lines of /etc/hosts.d/  andariel     andariel

All of my hosts are defined in this file similarly – using short names. dnsmasq was configured to expand those short names (the expand-hosts directive), so the first line defines the IP as The default domain is (the first domain line), and dnsmasq will assume that’s the domain for every short host it finds, if it has no reason to decide otherwise.

But there’s two domain lines, and the second one defines a specific subnet that it applies to. Because the second line defining falls within the subnet specified by the second domain line, the short host there expands to

In short, those two lines after expansion, according to the rules above, would look like this:

Client side

This configuration file for the client defines Google DNS and OpenDNS as defaults, and defines as the nameserver address for and the subnet (reverse DNS lookups). This has the added bonus of only making requests to the internal DNS for resources within the network.

{% capture dnsmasqcli %} server= server= server= server= server=/ server=/ listen-address= no-resolv no-hosts {% endcapture %} {% include filebox.html filename=”/etc/dnsmasq.conf” content=dnsmasqcli desc=”Client side configuration” %}

How, precisely, each client would need to be configured to use your dnsmasq instance as the primary DNS server depends on your distro, and in some cases some variables specific to that distro. Generally, getting nameserver into /etc/resolv.conf somehow will do it. This whole section can, again, be ignored if your Linux client has NetworkManager installed, or if it’s a Windows client. Macs, I don’t know anything about.

Does it work?

So how does one check to make sure you’ve applied these configurations correctly? Reconnect to the VPN and try to do some DNS lookups, of course.

(internal address check)
% nslookup


(outside addresses, did we isolate ourselves?)
% nslookup

Non-authoritative answer:

With defined as the default DNS server, it’s exactly like Google or OpenDNS, except with extra entries for overlaid on top. I’d call that mission accomplished.

Now to get in the habit of typing internal DNS addresses everywhere so I can feel smug about it.

  • October 13, 2022