Linux for Network Engineers: Poor Man’s DNS

By August 7, 2019Linux

Public DNS servers are great for everyday use, however, sometimes we just need to set up our own DNS server. Having your own server allows you to experiment, learn how DNS works, or even have better DNS performance compared to public servers. There are products that do DNS management, but in this post, we will discuss a readily available option to manage hostname resolution on a Linux box.

There are different ways to do that. For example, you can set up your own DNS by using named or djbdns. This would be the more generic option but is scalable and can handle DNS dynamically. However, it takes some upfront effort to the set up.

Poor’s Man DNS

Another solution that is easier to set up, is to manually configure host resolution via “/etc/hosts.” The configuration is easy, but it is manual and the changes are only applicable on one host; hence “Poor man’s DNS.”

You can use this local DNS configuration to:

  • Resolve a local hostname to an IP
  • Block a website
  • Redirect an existing hostname to another IP

Configuration

By default /etc/hosts may contain the following lines:

In the example above we see:

  • “127.0.0.1”: IPv4 localhost or loopback
  • “::1”: IPv6 localhost or loopback
  • “ff01::1”: All nodes on the local network segment
  • “ff01::2”:  All routers on the local network segment
  • “127.0.0.1”: Hostname for the loopback set to “raspberrypi”

If your /etc/hosts contains more lines, you might be able to find what it means here.

Many of you are used to accessing local resources on your machine by using “localhost.” For example, you can ping localhost this way:

If you didn’t know how “localhost” is mapped to “127.0.0.1”, now you do! If you edit /etc/hosts and comment out (by adding ‘#’ at the beginning of the line) the first two lines that define “localhost”, you will see the following:

Resolve a local hostname to an IP

Most often, I edit /etc/hosts to map a local host/IP in my network to a specific hostname. For example, if I have a test box with IP “172.31.0.25” which I access often with ssh and I want to be able to access by simply using “box1” I can append a line in my /etc/hosts as follows:

Now to ssh to “172.31.0.25”  I simply type:

Block a website

If you don’t want specific websites to be accessible on your machine you can redirect them to a null or invalid IP. For example, if want to block access to yahoo.com and www.yahoo.com I can point that URL to 0.0.0.0 as follows:

If you try to open yahoo.com on a browser you will get an error that the page cannot be found. On the command line, if you try to get a response from yahoo.com with curl you will see the following:

Of course, this blocking mechanism can be easily bypassed if you know one of the IPs of yahoo.com. However, even in that case you may still be unable to reach yahoo.com, since most popular websites (including yahoo.com) can’t be accessed by an IP address (or your browser might throw a security warning).

Redirect an existing hostname to another IP

Similarly, you can redirect an existing hostname to a different IP. As an example, I can redirect “google.com” to Cloudflare’s DNS server webpage “1.1.1.1” as follows:

If I ping “google.com” I end up pinging “1.1.1.1”:

Keep in mind that URL resolution utilities such as “dig”, “nslookup”, and “host”, do the lookup by using a DNS server, and they don’t take /etc/hosts into consideration. As an example, if I try to resolve google.com I get “172.217.164.110” and not “1.1.1.1” as configured in /etc/hosts:

By no means does /etc/hosts replace a DNS server, but it’s useful to know its purpose! It’s a great tool  to configure for testing but also for quick changes to host resolution on your machine.