Don't let DNS get you into a BIND; read on to sort out port 53.
In this article, I cover DNS, arguably the most “Rube Goldberg” of all services. (Well, except for Sendmail, but that's really just one application, not an entire service.) DNS (Domain Name Services) quite simply maps domain names to IP addresses. For some reason, it's easier for humans to remember words than strings of numbers, so rather than remembering 12.34.56.78, we remember www.linuxjournal.com.
Using DNS instead of remembering IP addresses not only helps prove Linux users aren't really cyborgs, it also allows some pretty cool magic in the server department. Instead of one server per Web site, a single server with a single IP address can host multiple Web sites. Unfortunately, the way DNS works on a global scale means it's not without its faults and frustrations. G.I. Joe always said, “knowing is half the battle”, so in this article, I walk you through being a knowledgeable DNS user, without ever delving into the complexities of the underlying system.
For most Linux distributions, you configure “how” the computer looks up URLs by setting the options in /etc/nsswitch.conf. If you look at your nsswitch.conf file, you'll probably find the line:
hosts: files dns
This line tells the computer that before it asks its DNS server for the IP address, it should look into its /etc/hosts file for a domain mapping. By default, there probably is a line defining the localhost address and possibly an entry defining whatever hostname and IP you set for the computer. This file has the following format:
# IP Address Domain Name 127.0.0.1 localhost 192.168.1.1 router 192.168.1.10 homeserver 192.168.1.20 xbmc
Once entered into the file, you can use the names defined in place of an IP address. This is truly domain name resolution in its simplest form. If you need only to map an address for your local computer, this is the ideal way to configure your computer. Keep in mind that the order specified in nsswitch.conf is the order your computer will search, so if you put an entry like this:
192.168.1.20 www.google.com
it won't ever look up the proper address for Google. It will query the server at 192.168.1.20 as if it were www.google.com. This is a feature rather than a bug. Although it certainly allows for some easy pranking (you didn't hear that from me), it also can be used to block specific sites. If you wanted to block Facebook on your home computer, for example, you could add:
127.0.0.1 www.facebook.com
Then, when the user tries to access Facebook, it will fail. Note that this is not a foolproof way to block Internet sites, but it works in most situations. This method often is used to block ads on Web pages. It's possible to find a list of ad servers and then put the list into your /etc/hosts file. Again, it's not foolproof, but the logic is sound. The hosts file is also useful for other purposes too, which I'll come back to later.
If you're using an off-the-shelf router for your home network, chances are it's running DNSMasq as a DNS server. DNSMasq is a DNS forwarder that queries a remote DNS server and returns the value to the client requesting the information. It has the handy feature of querying the router's /etc/hosts file first, and most routers have a way to add DNS entries. It's not always simple, like the case of DD-WRT. In order to add an address to the DNSMasq server on DD-WRT, you need to add lines to the DNSMasq config section like this:
address=/homeserver/192.168.1.10 address=/xbmc/192.168.1.20
See Figure 1 for a DD-WRT screenshot. By adding addresses to your router's DNSMasq server, you effectively can make an /etc/hosts file for every computer on your network. DNSMasq also is tied into the DHCP server, allowing for automatic mapping of hostnames to DHCP assignments, but that's a bit outside the scope of this column.
When it comes to DNS on the greater Internet, BIND is the de facto standard server. Unfortunately, BIND also is where the vast complexities of the Domain Naming System come into play. Don't get me wrong, the complexities aren't frivolous, just frustrating at times. If you are managing a DNS server for a business, chances are you need to work with BIND. Because BIND supports every facet of the DNS concept, I think it's important for a little terminology lesson before we dig into configuration. See the sidebar for some DNS terms you should be familiar with before delving into BIND configuration.
First off, if you're going to configure BIND, I recommend using a tool like Webmin for your first time. There are some quirks when you edit the BIND configuration file that aren't apparent at first. For example, when you edit a zone file (usually stored in /var/named), you need to increment the serial number at the top, or other servers won't see your information as the most recent.
Assuming your zone files are created, it's fairly easy to see how to add or modify records. The only thing I'll specifically mention here about the zone file is the TTL setting. This setting tells clients how many seconds the domain information is “good” for. If you plan to change Web hosts, it's good practice to set this TTL setting to something low about a week before the change, so when you do make the change, propagation time across the Internet goes much more quickly. Some DNS hosting companies set this to DAYS by default, so your well-planned host migration could take a week to propagate instead of a couple hours.
Although messing with the DNS servers is how you adjust settings, testing them isn't as straightforward as you might think. If you change a setting on one server, it takes a while to propagate to other servers, so testing can be frustrating. Thankfully, it's not hard to query specific servers.
For years, nslookup was the tool for doing DNS lookups. For some reason, several years ago, nslookup became deprecated, and no one bothered to tell me about it. I'm telling you now, so you don't look foolish trying to use nslookup on your machine. The new dog in town is the dig command, and it's pretty cool.
Issuing the dig command on its own will query whatever DNS server is assigned to your system. So typing:
dig www.linuxjournal.com
will yield something like this:
spowers@server:~$ dig www.linuxjournal.com ; <<>> DiG 9.8.1-P1 <<>> www.linuxjournal.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 50038 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;www.linuxjournal.com. IN A ;; ANSWER SECTION: www.linuxjournal.com. 388 IN A 76.74.252.198 ;; Query time: 34 msec ;; SERVER: 192.168.1.1#53(192.168.1.1) ;; WHEN: Wed Aug 1 10:32:23 2012 ;; MSG SIZE rcvd: 54
You'll notice at the bottom that the server responding is my local router at 192.168.1.1. If I want to query a different DNS server, however, it's as easy as typing:
dig @8.8.8.8 www.linuxjournal.com
which gives this:
spowers@server:~$ dig @8.8.8.8 www.linuxjournal.com ; <<>> DiG 9.8.1-P1 <<>> @8.8.8.8 www.linuxjournal.com ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 27150 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;www.linuxjournal.com. IN A ;; ANSWER SECTION: www.linuxjournal.com. 270 IN A 76.74.252.198 ;; Query time: 30 msec ;; SERVER: 8.8.8.8#53(8.8.8.8) ;; WHEN: Wed Aug 1 10:34:21 2012 ;; MSG SIZE rcvd: 54
Notice that the response is the same, but at the bottom you can see the server I queried was 8.8.8.8 (Google's public DNS server, which is terribly easy to remember).
One important thing to note is that the dig command will not honor entries in your /etc/hosts file. It's strictly a DNS lookup tool, so it only knows to query servers.
Now that you have at least a loose understanding of how DNS works, I want to share a few of the really nifty things you can do with it in your network.
Simply by adding multiple A Records for a single domain, it's possible to create a load-balancing situation for your servers. The BIND server will respond to queries in a round-robin fashion when there are multiple A Records. If you have a service you'd like to split across servers without configuring actual load balancing, round-robin DNS is a viable solution.
It's important to keep in mind that this solution has several failings. It doesn't actually load balance, it just alternates DNS responses. So, luck of the draw might mean one server is far busier than another. Round-robin DNS also breaks reverse lookups. If your application requires reverse DNS to function, a round-robin scenario will not work. Also, with a low TTL, constantly changing IP information likely will have an adverse effect on most services.
I touched on this concept earlier with regard to putting false entries in the /etc/hosts file. It's sometimes called “fake DNS” or “DNS hijacking” or any of several nefarious-sounding titles. Basically, the concept is that you host a zone locally and declare yourself authoritative for your clients. Because you've told your BIND server it was authoritative for a zone, it will serve only the IP information you configure and not query the greater Internet for actual IP mapping. This is very useful if you want to map internal domain names to private IPs. This is also useful if you want certain domains (like intranet.example.com) to exist only inside your company and not even resolve from the Internet.
It's important to note that this is a hack of the protocol and can have its failings too. In fact, some routers will detect split DNS as a DNS-spoofing attack (which technically it is) and not allow you to use those false addresses.
This isn't a hack at all, but rather a feature of most Web servers. Because the number of Web sites far surpasses the number of available IP addresses, Web servers now allow separate Web sites using the same IP address. For example, let's say three friends share a server. The DNS entries for their blogs might be:
12.34.56.78 shawnblog.example.com 12.34.56.78 julieblog.example.com 12.34.56.78 frankblog.example.com
You'll notice the three different domains share the same IP address. If you try to access http://12.34.56.78, the Web server won't know whose blog you're trying to access. By configuring virtual domains, however, the Web server running at 12.34.56.78 can differentiate between the blogs by which address you are querying. So http://shawnblog.example.com will get one Web site, and http://julieblog.example.com will get an entirely different one.
This ability for DNS entries to share a common IP address and Web servers to serve pages based on which domain name was requested has allowed for the modern Internet to work. Without that feature, shared hosting wouldn't be possible.
While Internet Web hosting relies on virtual hosts for most sites, a Web developer or sysadmin often can become frustrated waiting for propagation time when a DNS change is made. Let's say you've created a fancy new Web site on a new Web server, and you want to make sure it's working once the DNS change propagates through the Internet. Since Web servers reply based only on the domain request they receive, until DNS propagates, it's impossible to make sure the new Web site is working.
Thankfully, the Web server itself doesn't do DNS lookups; it knows only the domain names it's supposed to respond for. If you change your local /etc/hosts file with the new DNS information before you make the change on the Internet, you can test your new server using your local DNS information. In fact, without the ability to make this local bogus DNS change, testing your new server would be close to impossible!
DNS is a complex system of root servers, zone transfers, propagation time and reverse lookups. As you can see, however, it does a lot more than just map names to IP addresses. Without DNS, the Internet would be a lot less useful, and company Web sites would be far more difficult to remember. (“Come check us out at http://224.143.77.155 !!” doesn't really roll off the tongue very well.)
By using DNS on your local network, you can save a lot of time and make future changes far less painful. If BIND overwhelms you, don't let that bother you too much. You certainly don't have to be an expert on zone transfers in order to grasp DNS. The easiest way to start is to play with your /etc/hosts file. Playing with someone else's /etc/hosts file also can be fun, but be sure to use your super powers only for good!