If you've chosen to run your own DNS servers on your local network and you use Linux, you will probably want to set up BIND (Berkeley Internet Name Domain) to manage your DNS records. This configuration is quite detail oriented, and the smallest error can cause the entire service to grind to a halt. Pay attention while you're working, and make sure that you enable whatever security tools will safeguard your site most effectively.
Installing BIND on a Linux or UNIX machine can be a bit confusing, especially on Red Hat-based systems. While the general service is called the Domain Name Service, the actual RPM package is called bind:
# rpm -q bind bind-9.2.2.P3-9
Even more confusing, the daemon is called neither bind nor DNS, but named! This can be very annoying, especially if you are an administrator who does not have regular responsibilities for DNS services but needs to troubleshoot an immediate crisis while your DNS guru is on vacation. Your immediate response might be
# service bind restart bind: unrecognized service
Obviously, this won't work. Instead, you need to issue this command:
# service named restart Stopping named: [ OK ] Starting named: [ OK ]
Just another one of those UNIX idiosyncrasies that enhances job security.
Note |
In this section, we assume that you have a domain name registered to you. If you don't have a domain name yet, see the Registering Domain Names sidebar earlier in this chapter. |
Before you begin to configure BIND9 on your DNS server, take a moment to study the directory structure. BIND9 files live in the /bin directory:
/bin/ /boot/ /dev/ /etc/named.conf /home/ /initrd/ /lib/ /lost+found/ /misc/ /mnt/ /mnt-usb/ /opt/ /proc/ /root/ /sbin/ /tftpboot/ /tmp/ /usr/ /var/named/ localhost.zone example.com.zone named.ca named.local slaves/ /var/named/chroot/ local host.zone example.com.zone named.ca named.local slaves/
If you are running BIND in chroot mode, all the files must be under /var/named/chroot/.If you are running in nonchrooted mode, all the files must be under /var/named.
The /bin/etc/named.conf file contains the configurations for the named daemon. If you choose to run BIND in chroot mode (the default, and most secure choice), as described later in the BIND9 Security section of this chapter, you will store zone files in the /var/named/ chroot subdirectory.
Caution |
Read the BIND9 Bug sidebar later in this chapter to learn more about a serious security risk that may affect your installation. If you choose to run in chroot mode, you will need to copy some files into /var/named/chroot/ before you start the service. |
The /etc/named.conf file handles all configurations for the name daemon, or named. In order for DNS service to work properly, you will need to make a number of changes to this file. If DNS isn't working for some reason, chances are that it's an error in /etc/named. conf that is causing the problem.
Tip |
The named daemon is pronounced "name-dee," not "named" (as in "My geeky sister named her dog Denethor"). This is one of those Secret Passwords of UNIX Competence, like knowing how to pronounce Linus Torvalds. |
In this section, we show you a complete /etc/named.conf file, interspersed with comments and explanations. If you have a running installation of BIND9 already, look at your own /etc/named. conf to see what configurations have already been made.
Note |
If you do not have an /etc/named.conf file and you're on a Red Hat-based system, then you must also install the caching-nameserver RPM package. This will create /etc/named. conf. Also be aware that if your BIND DNS server is running in chrooted mode, you may find the file under /var/named/chroot/etc/named.conf, which is installed by the related Red Hat package bind-chroot. On a Red Hat system, issue the command rpm -qa|grep -e ^bind -e nameserv to see the bind-related packages you have installed. On a non-Red Hat system that has been running for at least 24 hours, you can issue the command locate named. conf as root to help you find your named config file. |
// generated by named-bootconf.pl options ( directory "/var/named";
The directory setting determines the directory where all zone flies should be stored. If you store zone files in any other directory, DNS will break.
/* * If there is a firewall between you and nameservers you * want to talk to, you might need to uncomment the query- * source directive below. Previous versions of BIND * always asked questions using port 53, but BIND 8.1 uses * an unprivileged port by default. */ // query-source address * port 53; };
This block doesn't look like normal UNIX commenting. In /etc/named.conf, you will find three different comment methods:
C style: /* comment inside here */
C++ style: // to the end of line
Unix style: # to the end of line
You can probably determine what is commentary and what is not, but it's good to be aware of the various notations.
// // a caching only nameserver config // controls { inet 127.0.0.1 allow { localhost; } keys { rndckey; }; };
The controls setting tells named how to run rndc, the BIND9 name server control utility.
The next sections contain the zone file definitions. Any line that says
file "somedomain.com.zone"
indicates that the zone file for this zone, or domain, is located at /var/named/somedomain . com. zone. Be sure that whatever you have in /etc/named. conf points to the actual file that you create. The name itself is irrelevant; it's the location and filename accuracy that matters.
zone "." IN { type hint; file "named.ca"; };
The first line of the preceding section indicates that the section will define the root zone. The third line identifies the file that contains the root of the zone.
zone "localhost" IN { #<--Good to use as a template type master; #<-- The master zone file "localhost.zone"; #<--The name of zone file located allow-update {none; }; # In /var/named/ };
This section is an excellent template for actual zone settings later in the file. The first line names the zone, the second line indicates that this is a master DNS server for that zone, and the third line specifies the location of the zone file in /var/named. To add your own zones, copy the preceding block in your named.conf file, paste it further down, and fill it in with your own zone file information.
zone "example.com" IN { type master; file "example.com.zone"; allow - update { none; } };
Caution |
Whenever copying blocks like this, be sure to include the all-important closing }; characters. |
As you can see here, the administrator has simply replaced the template information with actual zone information. Doing this through copy-and-paste is the safest way to be sure that your zone entries are formatted properly.
The next two blocks of information define how BIND handles reverse lookups for your domain:
The first configuration file block controls reverse lookups for your loopback device's IP.
Note |
Reverse lookups function like a phone book in reverse, to find a name associated with an IP address. The following entry, and its related zone file, is one that will allow anyone to nslookup the IP address 10.1.1.x. This zone will associate the IP back to a reverse (or PTR) name record. |
zone "1.1.10.in-addr.arpa" IN { type master; file "1.1.10.in-addr.arpa.zone"; allow-update { none; };
Tip |
Just as you copied down the 0.0.127 block as a template within the named.conf file, you can also copy the actual zone file it references named.local (usually in /var/named/) to use for a new reverse zone file called 1.1.10.in-addr.arpa.zone for the 10.1.1.x IP block. |
If you actually own the IP block that you use (unlikely, since most of us rent IP addresses from upstream providers), you would use the aforementioned configuration file block. Those who own an IP block control the reverse lookup authority for that entire block.
include "/etc/rndc.key";
This final line contains a pointer to the Remote Name Daemon Controller configuration file, which sets up local and remote secure control for the BIND9 server. Unless you are prepared to research this key-based secure service thoroughly, it is recommended to not make any changes to this reference or the file it references.
Note |
Good information on implementing RNDC/TSIG can be found at www.apnic.net/training/download/2004/20040115-in-dns/7-rndc-tsig.pdf. |
Now that you've seen an /etc/named.conf file in action, you can begin to edit your own. When adding your own zone blocks and file references, we strongly recommend typing the filename for new zones into named.conf, then copying it to the clipboard, and saving the filename from your paste. One of the most common errors is a typo in a zone filename, either in the named.conf file or in the /var/named/ filename itself. For example, if you use the vi text editor, you might issue the command
# vi /var/named/paste-file-name-here
or just copy the named.local file as a template:
Caution |
More DNS-related problems are caused by typing errors than anything else. The entries in /etc/named. conf and the zone filename must be identical or named will fail. |
After you have finished adding zone references to /etc/named.conf, it's time to create the actual zone files. Remember that you must store these files in the location you defined in /etc/named.conf. For example, in the /etc/named.conf file, we set up a zone reference for example.com, which has its zone files stored at /var/named/example.com.zone.
Before you begin creating zone files for actual domains, take a look at the localhost zone file. This defines information for your local machine, which uses the reserved IP address 127.0.0.1.
Note |
There are two typographical conventions found in zone files. If a line has a space in its left-most column then that line's configuration adopts the domain name from the previous line. The @ symbol is used as a placeholder for the full domain or zone name defined in the /etc/named.conf file. |
# cat /var/named/localhost.zone $TTL 86400
This line defines the default zone TTL, or the length of time for which zone information is authoritative. TTLs are written in seconds, so the value 86400 equals 1 day. Caching name servers use this value to ignore or refresh their cached information about a given domain name.
$ORIGIN localhost.
This line defines the domain name. The domain name must always end with a trailing dot. Later in example.com, this line would read $ORIGIN example.com. (note the trailing dot).
@ ID IN SOA @ root ( \ 42 ; serial (d. adams) 3H ; refresh 15M ; retry 1W ; expiry 1D ) ; minimum
This section creates the Start of Authority Record, or SOA. The SOA configures zone behavior and determines how the zone information may be pulled down by other name servers.
The serial number (42) found in the first indented line is used as a date stamp. It is written in the format YYYYMMDD##, where the ## is an actual number. Increment this number by one every time you make a change to the zone file (starting at 00 or 01). If you make a change to the zone file and do not increment this number, then caching name servers as well as your slave servers will ignore all following data and assume that their stored data is correct. For example, if today is January 16, 2008, and you are making the first change of the day, the serial number should be 20080011701. (Those of you who are Douglas Adams fans will be amused by the default placeholder for the serial number. It's set to 42 instead of the proper YYYYMMDD## date code.)
Tip |
You can learn more about Start of Authority records and their construction at http://secu.zzu.edu.cn/book/NetWork/NetworkingBookshelf_2ndEd/tcp/appc_03.htm. |
1D IN NS @ 1D IN A 127.0.0.1
Finally, these lines define the internet-type (IN) name server (NS) record for the domain this zone file represents. Written in an expanded format, these lines could also be
localhost. 1D IN NS localhost. ^^^ ^^ ^^ ^^ ^^^ the domain TTL NameServer
The name server for the domain localhost. (represented by the unseen space at the front of the line) is the server FQDN, localhost.; that is, you can find the IP address assigned to this name server at the name server called localhost..
NS records declare the machines that provide DNS service for the zone in question. Even after the registrars have pointed requests to your DNS server, this is still required.
Because this zone file is authoritative for the loca1host domain (in this case, because localhost is always locally authoritative), you will also see the A record defined:
1D IN A 127.0.0.1
which could be rewritten as
@ 1D IN A 127.0.0.1
or
localhost. 1D IN A 127.0.0.1
Note |
An A record always points a name to an IP address. An NS record always points to whoever should be doing DNS for this domain (which in the case of localhost. will always be you). |
If your DNS client is set to query your own machine before it queries the DNS server for the network, then your own name server will respond with this information:
# nslookup localhost Server: 192.168.128.2 Address: 192.168.128.2#53 Name: localhost Address: 127.0.0.1
Note |
The nslookup command has been deprecated, and may be removed from future Red Hat releases. Consider using the dig or host programs instead. If you like using nslookup, run it with the silent option to prevent this message from appearing, as in nslookup-sil. |
Note that in the preceding example ns1ookup did not actually query the name server running on the local machine. The Server and Address fields show that the resolver client went out and queried another DNS server running on IP 192.168.128.2. In order to query your own DNS server directly, you must supply the correct IP address. Issue the command like this:
# nslookup -sil localhost 10.1.1.1 Server: 10.1.1.1 Address: 10.1.1.1#53 Name: localhost Address: 127.0.0.]
This is much better. Now you're querying against your own machine (assuming that you are 10.1.1.1), and the output is correct. Compare the output from nslookup to the information you receive from the newer tools host and dig:
# host localhost 10.1.1.1 Using domain server: Name: 10.1.1.1 Address: 10.1.1.1 # 53 Aliases:localhost has address 127.0.0.1
The usage and output from host is generally the same as that from nslookup. With the dig command, however, you'll see quite different information. dig takes slightly different syntax to query a name server other than the default, with @nameserverIP rather than the plain IP address:
# dig localhost @10.1.1.1 ;<<>> DIG 9.2.2-P3 <<>> localhost @10.1.1.1 ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 27676 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 0 ;; QUESTION SECTION: ;localhost. IN A ;; ANSWER SECTION: localhost. 86400 IN A 127.0.0.1 ;; AUTHORITY SECTION: localhost. 86400 IN NS localhost. ;; Query time: 2 msec ;; SERVER: 10.1.1.1#53(10.1.1.1) ;; WHEN: Sat Jan 17 22:44:18 2004 ;; MSG SIZE rcvd: 57
This is quite a bit more information than that from the other tools. The dig output contains data about the query itself and the various answers, as well as statistics about the queried domain, including its TTL and authoritative name server. With the information from the AUTHORITY section, you can use dig to "walk down the DNS tree" for a given domain.
For example, use dig to step down through the DNS tree for yahoo.com. In the first query, use dig to find the gTLD name server(s) for the .com TLD:
# dig com [...] ;; QUESTION SECTION: ; com. IN A ;; AUTHORITY SECTION: com. 10737 IN SOA a.gtld- servers.net. nstld.verisign-grs.com. 2004011701 1800 900 604800 86400
Next, query the gTLD server that you found in the first output for information about the yahoo.com domain:
# dig yahoo.com @a.gtld-servers.net [...] ;; QUESTION SECTION: ;yahoo.com. IN A ;; AUTHORITY SECTION: yahoo.com. 172800 IN NS nsl.yahoo.com. yahoo.com. 172800 IN NS ns2.yahoo.com. yahoo.com. 172800 IN NS ns3.yahoo.com. yahoo.com. 172800 IN NS ns4.yahoo.com. yahoo.com. 172800 IN NS ns5.yahoo.com. ;; ADDITIONAL SECTION: nsl.yahoo.com. 172800 IN A 66.218.71.63 ns2.yahoo.com. 172800 IN A 66.163.169.170 ns3.yahoo.com. 172800 IN A 217.12.4.104 ns4.yahoo.com. 172800 IN A 63.250.206.138 ns5.yahoo.com. 172800 IN A 216.109.116.17
Here you see a request to the world gTLD name servers serving the .com TLD for the IP address of yahoo.com. It gave back authoritative name servers and their IPs. In this output, you can see that there are a number of authoritative name servers for this domain.
Now you can ask one of those servers to answer your question about the yahoo.com domain directly:
# dig yahoo.com @66.218.71.63 ;<<>> DiG 9.2.2-P3 <<>> yahoo.com @66.218.71.63 ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5356 ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 5, ADDITIONAL: 5 ;; QUESTION SECTION: ;yahoo.com. IN A ;; ANSWER SECTION: yahoo.com. 1800 IN A 66.218.71.198 ;; AUTHORITY SECTION: yahoo.com. 172800 IN NS ns1.yahoo.com. yahoo.com. 172800 IN NS ns2.yahoo.com.
There you have it: the authoritative IP address for the yahoo.com domain as defined by its own DNS server's zone file.
This is the work that your ISP or network provider's DNS server does when it performs recursive requests for their clients. Name servers that recurse, or search, for domains on behalf of their client's requests are usually also set up as caching name servers. Caching servers retain the information they gather for a set period of time, defined by the remote domain's TTL setting in its own zone file. In this way, by running your own DNS server, not only do you control the IP addresses that people get resolved to but also (with the TTL) how long they can hold onto this information. This helps to speed up DNS and keep DNS chatter on the Internet to a minimum.
Tip |
Learn more about recursive DNS requests at www.intac.com/~cdp/cptd-faq/section2.html#iterrec. |
Now that you have your DNS server running and doing recursive lookups, be sure that /etc/named.conf points to the correct zone file for your domain. Once the pointer is in place, you can create the authoritative zone file. In this section, we set up a file for the fictitious domain example.com.
As we warned earlier, don't type in the name of this file manually when you save it for the first time. Cut and paste from your /etc/named.conf to save yourself from later work due to fumbling fingers. In fact, save yourself a lot of typing by using a template taken from the localhost.zone file. Issue this command:
# cp -p /var/named/localhost.zone /var/named/example.com.zone
Be sure to paste the copied zone filename at the end of the line, where we have italicized our zone filename.
Open this new file in your favorite text editor. If your text editor has search and replace capabilities, use it to replace every occurrence of localhost. with example.com. (If you don't have search and replace in your editor, you'll have to do this by eye.) Be sure to include those trailing dots. Check the default settings and see if you need to change them at this time:
$TTL 86400
Is this TTL an appropriate length? 86400 seconds is 1 day. If you want caching name servers to hold your information longer, thus reducing load on your local machine, consider lengthening this setting:
$ORIGIN example.com.
Be sure that your domain name ends in a trailing dot.
@ 1D IN S0A ns.example.com tom.yahoo.com. ( 2004011700 ;
Remember to change the name server for this domain (ns.example.com) and the e-mail address (without the @ here is tom.yahoo.com). Also, change the serial number to the date format YYYYMMDD##. Increment the serial number by one each time you make any changes to this file from now on.
3H ; refresh 15M ; retry 1W ; expiry 1D ) ; minimum @ 1D IN NS ns.example.com. @ 1D IN NS ns2.example.com. ns 1D IN A 10.1.1.1 ns2.example.com. 1D IN A 192.168.128.1
Note |
The only reason that this sample zone file must have A records for its NS records is that the DNS servers for this domain exist inside the domain. That is, the DNS server ns.example.com exists inside the example.com domain, which is being defined by this file. If the name servers were outside this domain (for example, in ns . mydns . com), you would not use A records in this zone file since this zone file is not authoritative for the domain mydns.com. |
Since our name servers are also in this domain, we need to include A records that point to a specified IP address for the servers. There is an entry for the master name server and one for each slave server.
Note |
In the aforementioned example, the record for ns could also be written as ns.examaple.com. or just as ns<space>, which expands out to the FQDN. Either of these work, but sometimes using just the last part of the hostname (ns in this case) is clearer and easier to read. |
www 1D IN CNAME @ ; ftp 1D IN CNAME @ ; mail 1D IN CNAME @ ; webdav 1D IN CNAME @ ; @ lD IN A 10.1.1.1 ;
While A records point domain names to IP addresses (last line), CNAME records are aliases that point names to other names. These names must resolve to an A record (ultimately to a defined IP address).
Note |
The e-mail address for this domain is tom@yahoo.com, and it can be found in the third line, expressed as tom.yahoo.com. This form is used because the @ symbol is used in zone files to represent the entire domain name. The standard syntax for e-mail addresses in zone files is user.domain.gtld. |
Note that this zone file defines two name servers. The IPs you would use to define these servers are usually the primary and secondary servers that you provided when you registered your domain name. In this case, we used ns .example.com/10.1.1.1 and ns2.example.com/ 192.168.128.1. This is a bit more complex than the usual practice of most DNS administrators, who would use the equally functional method:
@ 1D IN NS ns @ 1D IN NS ns2 ns 1D IN A 10.1.1.1 ns2 ID IN A 192.168.128.3
This usage requires less typing, and thus less room for human error. However, while you're learning to set up zone files, there is something to be said for writing everything out at least once to get a feel for doing it correctly.
The only other element of note is that all the Canonical Name, or CNAME, entries point to the same server, @. Remember that @ is shorthand for the example.com. domain. It is only in the final record where the example.com. name is pointed to the IP address 10.1.1.1 with an Address Resource record, or A record.
If you have control over your own IP space, as you would on a corporate LAN, you will need to be able to service reverse lookups. As we explained earlier, reverse lookups are queries that seek a domain name to match a known IP address, whereas forward lookups seek an IP address to match a known domain name. If you do forward lookups for your own IP space, then you need to do reverse lookups as well.
To set up reverse lookup resolution, open the /etc/named.conf file in your text editor of choice:
zone "1.1.10.in-addr.arpa" IN { type master; file "1.1.10.in-addr.arpa.zone"; allow-update { none ; }; allow-transfer { 192.168.128.3; 127.0.0.1; 192.168.128.25; }; };
The zone file needs to have a name that means "/var/named/ for the IP block of 10.1.1.*", more precisely expressed as 10.1.1.0/24. This file is most easily created by copying the existing file /var/named/named.local to the new zone filename, and then editing it as necessary. For example, the 1.1.10.in-addr.arpa.zone file named in the previous example might look like this if we started adding additional machines:
$TTL 86400 @ IN SOA ns.example.com. root.1ocalhost. { 2004011600 ; Serial 28800 ; Refresh 14400 ; Retry 3600000 ; Expire 86400 ) ; Minimum IN NS ns.example.com. IN NS ns2.example.com. 1 IN PTR nsl.example.com. 2 IN PIR bob.example.com. 3 IN PTR ns2.example.com. 4 IN PTR 4-1-1-10.example.com. 5 IN PTR 5-1.1.10.example.com. 6 IN PTR 6.1.10.example.com. 7 IN PTR staging-server.example.com. ... 254 IN PTR netmon.example.com.
The last block of records are PTR, or reverse, records. They simply point known IP addresses back to the associated domain name. Typically, only the owner of that IP network block is granted the authority to "do reverse" on a public IP address. In this situation, however, these are not public IP addresses. Rather, they are nonroutable from the 10.* class-A block. The only stipulation is that you must at least control the DNS servers on your network so that internal users look at the local DNS server for this block.
Note |
Remember that the default DNS server setting for every PC on your network is typically pushed out to the client PCs by your own network's DHCP server. If you issue your own IP addresses on your network, you control what DNS server(s) they go to. Instructions for pointing your DHCP clients to your DNS servers are beyond the scope of this chapter. |
To test your configuration, use the host command to resolve an IP (10.1.1.5 in this example) against your own name server:
# host 10.1.1.5 10.1.1.1 Using domain server: Name: 10.1.1.1 Address: 10.1.1.1#53 Aliases: 5.1.1.10.in-addr.arpa domain name pointer 10-1-1-5.example.com.
or
As long as you remember a few basic pieces of information, configuring your local DNS server and zone files will be no problem:
The main configuration file /etc/named.conf (or if chrooted, /var/named/chroot/etc/named.conf) defines how the server runs and determines which zone files are loaded into memory.
The domains, or zone files, are stored in the /var/named/ directory. If you are running BIND9 in chroot mode, they are stored in /var/named/chroot/var/named/.
Know the difference between A records, NS records, and CNAMEs.
Terminate fully qualified domain names, or FQDNs, with a trailing dot. If not, your www.example.com will become www.example.com.example.com!
If you make a change to the zone file, increment the serial number by one. If you exit without changing the serial number, the changes will not take effect on all external name servers.
Whenever you make a zone addition or change, be sure to reload or restart the named daemon with the command /etc/init.d/named restart or service named reload.