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
By default /etc/hosts may contain the following lines:
netbeez.net$ cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback ff02::1 ip6-allnodes ff02::2 ip6-allrouters 127.0.1.1 raspberrypi
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:
netbeez.net$ ping localhost -c 1 PING localhost(localhost (::1)) 56 data bytes 64 bytes from localhost (::1): icmp_seq=1 ttl=64 time=0.125 ms --- localhost ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.125/0.125/0.125/0.000 ms
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:
netbeez.net$ ping localhost -c 1 ping: localhost: Name or service not known
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:
netbeez.net$ cat /etc/hosts #127.0.0.1 localhost #::1 localhost ip6-localhost ip6-loopback ff02::1 ip6-allnodes ff02::2 ip6-allrouters 127.0.1.1 raspberrypi #My configurations 172.31.0.25 box1
Now to ssh to “172.31.0.25” I simply type:
netbeez.net$ ssh box1 pi@box1's password:
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:
netbeez.net$ cat /etc/hosts #127.0.0.1 localhost #::1 localhost ip6-localhost ip6-loopback ff02::1 ip6-allnodes ff02::2 ip6-allrouters 127.0.1.1 raspberrypi #My configurations 172.31.0.25 box1 0.0.0.0 yahoo.com 0.0.0.0 www.yahoo.com
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:
netbeez.net$ curl yahoo.com curl: (7) Failed to connect to google.com port 80: Connection refused
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 “188.8.131.52” as follows:
netbeez.net$ cat /etc/hosts #127.0.0.1 localhost #::1 localhost ip6-localhost ip6-loopback ff02::1 ip6-allnodes ff02::2 ip6-allrouters 127.0.1.1 raspberrypi #My configurations 172.31.0.25 box1 0.0.0.0 yahoo.com 0.0.0.0 www.yahoo.com 184.108.40.206 google.com
If I ping “google.com” I end up pinging “220.127.116.11”:
netbeez.net$ ping google.com -c 1 PING google.com (18.104.22.168) 56(84) bytes of data. 64 bytes from google.com (22.214.171.124): icmp_seq=1 ttl=55 time=13.8 ms --- google.com ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 13.800/13.800/13.800/0.000 ms
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 “126.96.36.199” and not “188.8.131.52” as configured in /etc/hosts:
netbeez.net$ nslookup google.com Server: 184.108.40.206 Address: 220.127.116.11#53 Non-authoritative answer: Name: google.com Address: 18.104.22.168
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.