There’s not much work to installing and using a typical hardware router. Just plug it in, attach cables from your non-wireless computers, and it will automatically connect them to the internet without any special configuration. That’s because the out-of-the-box router/firewall acts as both a DHCP server and DNS relay. The DHCP server assigns a unique private IP address like “192.168.0.101” to each device on your local network (which is often called a “subnet”, but here I’ll call it the “LAN”); the DNS relay forwards requests for any internet address like “mail.google.com” to your ISP’s nameserver(s) and receives back its answer – the IP for that name – which it passes in turn to your computer.

Typical DNS forwarding provided by a router

This hand-off approach works perfectly well as long as you only need to resolve names on the public internet. No special coniguration is necessary on either the router or its clients. Whether you’re running Windows, OSX or Linux, your computer’s default configuration will reach out to the DHCP server. The router will tell your computers to use its IP as the gateway for all traffic beyond your LAN, and also assign itself as the DNS. Your computer doesn’t know or care that the router is just a middleman for the DNS requests.

The problems begin when you need to resolve names between the computers on your LAN. Say that you want to connect to another computer using VNC or another remote desktop, or one running a web server or SSH daemon. Unless you use the remote computer’s exact IP address (e.g., “http://192.168.0.103", not “http://mywebserver.mydomain.net"), you won’t succeed. That’s because your router is designed to gets all its DNS information from your ISP’s nameservers, through the cable or DSL modem connected to its WAN port. Your ISP’s nameservers don’t know anything about the computers connected to the router’s LAN ports.

Static DNS to the Rescue

The solution is to set up a local DNS on one computer on the LAN, then configure the router with static DNS entries. The local DNS will be the primary nameserver; the secondary nameserver will be your ISP’s DNS. We will disable DNS relay on the router. Once the process is complete, the flow of DNS requests will look like this:

DNS forwarding using static routing and a local nameserver

The router will assign the DNS entries to the client computers, but after that it will not be involved in DNS requests. Regardless of which nameserver is used, all requests for addresses beyond your LAN/subnet will be forwarded to your ISP’s DNS. The rest of this article explains how I did that using Debian/Ubuntu Linux on a home network. Although the nameserver installation steps are specific to Linux, the rest of the configuration should be similar regardless of which router or operating system you’re using.

Before you begin, understand that this solution also depends on your computers having fixed IP addresses. You can ensure that your router’s DHCP server always assigns the same IP number to a particular device by browsing to its admin screen and looking for a way to convert a currently dynamic lease into a fixed lease. You specify the hardware (MAC) address and couple it to an IP address.

Installing the DNS Server

In this example, my…

  • local domain is “softpoint.int” (this is made-up, not a real registered domain); all IP addresses on this local subnet begin with 192.168.0
  • personal computer is pauldev.softpoint.int, IP is 192.168.0.122
  • computer on which the nameserver is installed is services.softpoint.int, IP is 192.168.0.139
  • router’s IP on the LAN is 192.168.0.1
  • ISP’s DNS is 66.90.139.210 (you can discover yours by checking the router’s status page)

We’re going to install the “bind” nameserver. My server runs Debian 5.0. The steps in Ubuntu should be almost identical. You could also install bind in a virtual machine, so long as that VM has a fixed IP and is visible to other computers on your network.

sudo apt-get install bind9

Next, we need to edit a number of files. Add these lines to the end of /etc/named.conf.local, replacing “softpoint.int” and “db.softpoint.int” with your own domain:

zone "softpoint.int" {
        type master;
        file "db.softpoint.int";
};

zone "0.168.192.in-addr.arpa" {
        type master;
        file "db.192.168.0";

Add these allow-recursion and forwarders sections near the bottom of /etc/named.conf.options, above the line beginning “auth-nxdomain”. Replace “66.90.139.210” with your ISP’s nameserver. Note that we are forwarding DNS requests direct to the ISP nameserver (66.90.139.210), not to the router (192.168.0.1):

    allow-recursion {
        localhost;
        192.168.0.0/24;
     };
    forwarders {
        66.90.139.210;
    };

Change your current directory from /etc/bind to /var/cache/bind and create a pair of files there (unlike the ones in /etc/bind, these files don’t yet exist). The first file to create is /var/cache/bind/db.softpoint.int. It does a lookup from a name to locate the IP address. Replace “softpoint.int” and “services” respectively with your domain and the machine running this nameserver. Enter the computers on your network below the line that begins “www”.

$TTL 604800
@ IN SOA services.softpoint.int. admin.softpoint.int. (
                2008080101      ;serial
                04800           ;refresh
                86400           ;retry
                2419200         ;expire
                604800          ;negative cache TTL
                )
@       IN      NS      services.softpoint.int.
@       IN      A       192.168.0.169
@       IN      MX      10      services.softpoint.int.
services    IN      A       192.168.0.169
www     IN      CNAME   main

router   IN       A      192.168.0.1
lanserv  IN      A       192.168.0.100
vonage   IN      A       192.168.0.102
pauldev  IN      A       192.168.0.122
mediawin IN      A       192.168.0.123

The second file to create is /var/cache/bind/db.192.168.0. It does the reverse lookup, from IP number to name. Enter the computers below the line that reads “@ IN A 192.168.0.1”:

$TTL 604800
@ IN SOA services.softpoint.int. admin.softpoint.int. (
                2008080101      ;serial
                604800          ;refresh
                86400           ;retry
                2419200         ;expire
                604800          ;negative cache TTL
                )
@         IN      NS      services.softpoint.int.
@         IN      A       192.168.0.1

1         IN      PTR     router.softpoint.int.
100       IN      PTR     lanserv.softpoint.int.
102       IN      PTR     vonage.softpoint.int.
122       IN      PTR     pauldev.softpoint.int.
123       IN      PTR     mediawin.softpoint.int.

We’re ready to restart the nameserver with this new configuration:

sudo /etc/init.d/bind9 restart

Before we change anything on the router, let’s make sure that the new local nameserver is doing its job. On any computer (including the one on which you installed the nameserver), check the file /etc/resolv.conf. In Ubuntu, it should look like this, still using your router as its nameserver:

# Generated by NetworkManager
domain grandenetworks.net
search grandenetworks.net
nameserver 192.168.0.1

Temporarily edit that file and replace the nameserver IP with that of your new local DNS server:

# Generated by NetworkManager
domain grandenetworks.net
search grandenetworks.net
nameserver 192.168.0.139

Try a lookup of an internet domain:

dig google.com

Try a lookup of one of the hostnames you defined in your local domain:

dig mediawin.softpoint.int

If the lookups worked, the response you receive should contain an answer section reporting the IP for that domain or hostname, e.g.:

;; ANSWER SECTION:
mediawin.softpoint.int. 604800  IN  A   192.168.0.123

Don’t skip over these tests. There’s no point in messing with the router until both of these lookups pass. Othewise, you’re likely to replace your working DNS setup with one that’s worse.

Reconfiguring the Router

Browse through the admin pages for your router and find the one where you can manually edit the DNS addresses. These may currently be set as blanks or as “0.0.0.0”, meaning they will be dynamically assigned by your ISP. Replace them with static IP numbers. For the Primary DNS address, use the IP of your local nameserver; for the Secondary DNS address, use the IP of your ISP’s nameserver:

Assign static DNS numbers

One more very important thing: we need to disable the router’s DNS relay feature. On my router, this setting was on entirely different conguration screen. Also, as we’ll soon see, it’s worth entering the “Local Domain Name” you invented for your LAN.

Turn off DNS relay on your router

Save the settings and allow the router time to reboot, if necessary.

We’re ready to test name resolution once again. Instead of manually jury-rigging /etc/resolv.conf this time, we’re going to check if our new router settings will enable our computer to auto-configure itself. Try restarting your network connection on your computer, or releasing and renewing your DHCP lease. In Windows, you can force this by the commands “ipconfig /release” and “ipconfig /renew”. In Ubuntu, clicking on “Auto eth0” in the Network Manager icon of the top panel will take care of it.

Your /etc/resolv.conf file should now look like this (in Windows, “ipconfig /all” will show you your current DNS servers:

# Generated by NetworkManager
domain softpoint.int
search softpoint.int
nameserver 192.168.0.139
nameserver 66.90.139.210

Note that the router passed on to us the two DNS servers we defined in it, and that the router itself is no longer a nameserver.

Try some more digs or pings or web browsing to confirm that your new configuration is working. You should also be able to connect to local computers without appending their domain names, e.g. “ping mediawin” should work just as well as “ping mediawin.softpoint.int”.

Questions and Answers

Some readers may be puzzled by this setup, and wonder about other options.

Q: Most of my traffic is going to the public internet, so shouldn’t my ISP’s nameserver be the primary nameserver?

A: No, because the first working nameserver our computer can contact will be used for the lookup, and your ISP’s nameserver knows nothing about your private domain. It can only hand off lookups further upstream to more authoritative nameservers. The secondary DNS will be used only if the primary nameserver is unavailable. Thus, if you list your ISP’s DNS first, the connection will succeed, but every lookup concerning a device on your LAN will fail. By putting your local DNS first, your local lookups will work. Also, you can shut down or take your local DNS server offline and still surf the web without interruption. In that case, your computer will fail to connect to it as the primary nameserver, so it will contact the secondary nameserver (your ISP’s DNS) as a fallback.

Q: Wouldn’t it be easier to avoid all this work and just use a local hosts file on each computer?

A: Yes, if you have a very simple network with a couple of computers and don’t mind manually configuring them for every operating system you boot. You can create an /etc/hosts file and add lines like:

192.168.0.1     router mediawin.softpoint.int
192.168.0.101   lanserver lanserv.softpoint.int
192.168.0.123   mediawin mediawin.softpoint.int

You’ll have to remember, however, to update those individual files whenever you add a device to the LAN, or change its IP address.

Q: Do I need a local DNS server if I only want to share files and printers using Windows Networking (SMB, often called “Samba” in Linux)?

A: No, you can find and connect to one another without installing a local DNS. Computers using the SMB protocol announce their availability by broadcasting themselves on the LAN. They don’t need a nameserver.