MacDevCenter    
 Published on MacDevCenter (http://www.macdevcenter.com/)
 See this if you're having trouble printing code examples


Implementing BIND on Mac OS X

by Jason Deraleau
04/15/2003

Editor's note: The Berkeley Internet Name Domain distribution, or BIND, is a suite of Unix utilities that works with the Domain Name System. The nslookup and dig utilities are a part of the BIND distribution, but the named DNS server is what people most often refer to as BIND. The DNS server portion is what Jason will be focusing on in this article.

If you are new to DNS, then you might want to wait for Dan Benjamin's article in which he'll introduce you to the concepts behind DNS, especially as it applies to Mac OS X system administrators. (It should run within a week or two.) After having absorbed that information, you can then return here to read about BIND. If you'd like to do a little background reading right now, take a look at Alan Graham's Homemade Dot-Mac with OS X and James Duncan Davidson's Setting Up a Site Server with Jaguar.

Getting BIND

Mac OS X 10.2 "Jaguar" includes the BIND suite. The current release of Mac OS X (10.2.5) includes version 8.3.4-REL of BIND. The named daemon is located in the /usr/sbin folder by default. Apple has also provided a SystemStarter bundle for BIND, which is located in /System/Library/StartupItems/BIND. If you are not running Jaguar or would like to run the latest version of BIND, you can download the source distribution of BIND from the Internet Software Consortium's web site. The instructions below will help you get the most recent release of BIND (9.2.2-REL). If you wish to use the version of BIND that is included with Jaguar, you can skip ahead to the "Launching BIND at Startup" section.

Installing BIND 9

Compiling BIND requires the Mac OS X Developer Tools. If you do not have the Developer Tools, you can download them from Apple's Developer Connection. The commands below will help you download and install BIND 9.2.2-REL on your system:

% cd ~/Desktop
% curl -O ftp://ftp.isc.org/isc/bind9/9.2.2/bind-9.2.2.tar.gz
% tar zxvf bind-9.2.2.tar.gz
% cd bind-9.2.2
% ./configure --prefix=/usr/local/bind9
% make
% sudo make install

Now that you have installed the BIND distribution, you must modify (or create) the necessary SystemStarter bundle. The bundle is located in /System/Library/StartupItems/BIND. The file that you need to change is called BIND. Below is what you will need to make the file contain. To edit the file, use the command sudo pico /System/Library/StartupItems/BIND/BIND:

#!/bin/sh

##
# BIND name service.
##

. /etc/rc.common

if [ "${DNSSERVER:=-NO-}" = "-YES-" ]; then
        ConsoleMessage "Starting named"

        /usr/local/bind9/sbin/named -c /etc/named.conf
fi

For those of you who are not using Jaguar, you will first need to create the BIND folder in /Library/StartupItems by using the commands below. You will also need a parameters file, which you can download here. Place the file in the /Library/StartupItems/BIND folder and name it StartupParameters.plist.

% sudo mkdir /Library/StartupItems
% sudo mkdir /Library/StartupItems/BIND

The last step is to give your BIND script executable permissions by using the command sudo chmod 0755 /Library/StartupItems/BIND/BIND.

Launching BIND at Startup

After installing BIND and creating the necessary SystemStarter bundle, edit (or add) the line below in your /etc/hostconfig file. To edit the file, use the command sudo pico /etc/hostconfig.

DNSSERVER=-YES-

During your next reboot, SystemStarter will start named automatically. If you are having trouble loading named, be sure to use the Console utility to check your /var/log/system.log file for messages to help you (or others) troubleshoot.

DNS and BIND

Related Reading

DNS and BIND
By Paul Albitz, Cricket Liu

Creating DNS Zones

The BIND DNS Server, named, uses flat files to store DNS zone information. Each zone has its own file, which is located in /var/named by default. Within a zone, resource records are used to differentiate the various types of DNS information. The most common resource records are SOA, NS, A, CNAME, and PTR, all of which I will discuss below.

BIND zone files often follow a file-naming convention. Forward lookup zones are named db.domain.ext, such as db.oreilly.com, while reverse lookup zones are named db.addr, such as db.216.194.67. A semicolon prefaces commenting in zone files and white space is ignored. In the following sections, I will also discuss four different files. Two of the files contain reverse lookup zones, while one other contains a forward lookup zone. The remaining file is what is known as a hint zone.

Hint Zones

The hint zone is kept in a file most often called named.ca. It contains a list of the root DNS name servers. These servers don't change very often, but a good rule of thumb is to download a new version of the file once a month. You can automate this process by adding the following to your /etc/crontab file:

0 0 1 * * root /usr/bin/curl \ 
 ftp://ftp.rs.internic.net/domain/named.root > /var/named/named.ca

To load a hint zone, place the entry below in your named.conf file. The zone is declared as ".", which indicates it is the root zone. The type is specified as hint, and the file is the name of the file within the /var/named folder.

zone "." in
{
    type    hint;
    file    "named.ca";
};

Forward Lookup Zones

Forward lookup zones contain hostname to address DNS mappings. If you want to resolve www.yahoo.com, your query will end up getting information from a forward lookup zone. The most used resource record in a forward lookup zone is the A record. A records represent a mapping between a hostname and an IP address. For example:

www.oreilly.com.     IN  A   216.194.67.88

This entry would indicate to BIND that the www host within the oreilly.com domain has an IP address of 216.194.67.88. Notice that this entry is broken up into three primary sections: the record name, the resource record type, and the value of the record. Notice also that there is a trailing period at the end of the host portion. Be sure to specify a fully qualified domain name (including the trailing period) in the record name.

Another common record found in forward lookup zones is the CNAME record. CNAME records are used to alias one name to another. You can alias two names that are within the same name space or even to another name space. The example below declares ftp.example.com as an alias of www.example.com and news.example.com as an alias of www.cnn.com:

www.example.com.            IN  A   192.168.1.5
ftp.example.com.            IN  CNAME   www.example.com.
news.example.com.           IN  CNAME   www.cnn.com.

Before you can start entering your various resource records, your zone needs to contain a default TTL and a section called the Start of Authority or SOA record. The default TTL is declared at the beginning of the file and is used for any records that do not specify their own TTL. SOA records contain general information about a zone, such as the name of the zone in question, the administrator's email address, a serial number, and caching information. Below is an example of an SOA record:

$TTL 86400
example.com.     IN  SOA ns.example.com. root.example.com. (
                     2003040101      ; Serial
                     10800           ; Refresh after 3 hours
                     3600            ; Retry after 1 hour
                     604800          ; Expire after 1 week
                     86400 )         ; Minimum TTL of 1 day

The first entry (example.com.) represents the zone in question. You can tell it is a forward lookup zone because this contains a domain name instead of an IP network. There is the declaration of the record type (SOA) and then the entry ns.example.com. This entry indicates the primary master name server for the zone. The root.example.com. entry tells us the email address of the contact for the zone. In this case, it is root@example.com. It can be any valid email address, just replace the at (@) with a period (.) and put it in your zone file.

The next section of the SOA record contains caching data for the zone. The values given are good for most DNS setups. One important field to note is the serial number. The serial number should be incremented every time a change is made to your zone. If you do not increment it, DNS servers that are caching your entry will not realize that there is new data being used. You can number the zone any way you like, but a common practice is to use the format YYYYMMDDNN. Where NN is a daily version number. In the example SOA, the serial is 2003040101, which would indicate this is the first revision of the zone file on 04/01/03.

Following the SOA record, your zone must contain a listing of name servers that are authoritative for the zone. The example below indicates that the name servers ns1.example.com and ns2.example.com are authoritative for the example.com domain:

example.com.          IN  NS  ns1.example.com.
example.com.          IN  NS  ns2.example.com.

Once your zone contains an SOA record as well as the appropriate NS records, you can start to enter your A records. Below is an example zone for example.com that contains the information we've covered thus far:

;
; /var/named/db.example.com. - Zone file for example.com domain
;
$TTL 86400  ; 1 day
example.com.          IN  SOA ns.example.com. root.example.com. (
                          2003040101      ; Serial
                          10800           ; Refresh after 3 hours
                          3600            ; Retry after 1 hour
                          604800          ; Expire after 1 week
                          86400 )         ; Minimum TTL of 1 day

; name servers
example.com.          IN  NS  ns1.example.com.
example.com.          IN  NS  ns2.example.com.

; host to address mappings
www.example.com.      IN  A   192.168.1.5
ns1.example.com.      IN  A   192.168.1.2
ns2.example.com.      IN  A   192.168.1.3

To load a forward lookup zone, place the entry below in your named.conf file. The name of the zone is declared as "example.com." The type here is master, which means that the server is a master server for the zone in question. The notify field is used to tell BIND to notify any slave servers of changes to the zone data. Finally, the file indicates which file contains the zone.

zone "example.com" in
{
    type    master;
    file    "db.example.com";
};

Reverse Lookup Zones

Reverse lookup zones contain data for reverse DNS queries. A reverse query is used to resolve an address to a hostname.

As far as structure goes, a reverse lookup zone is the same as a forward lookup zone:

;
; /var/named/db.192.168.1 - Zone file for 192.168.1 network
;
$TTL 86400  ; 1 day
1.168.192.in-addr.arpa  IN  SOA ns.example.com. root.example.com. (
                            2003040101      ; Serial
                            10800           ; Refresh after 3 hours
                            3600            ; Retry after 1 hour
                            604800          ; Expire after 1 week
                            86400 )         ; Minimum TTL of 1 day

; name servers
1.168.192.in-addr.arpa  IN  NS  ns1.example.com.
1.168.192.in-addr.arpa  IN  NS  ns2.example.com.

; address to host mappings
1                       IN  PTR gateway.example.com.
2                       IN  PTR ns1.example.com.
3                       IN  PTR ns2.example.com.
5                       IN  PTR www.example.com.

You might notice that the main difference is in the use of PTR records instead of A records. PTR records are the most used record in a reverse lookup zone. The first field of a PTR record contains the last octet of the host's IP address. So, in the case of 192.168.1.1, it would be just 1. The value of the record is the fully qualified domain name of the host in question (for example, gateway.example.com.). Remember those trailing periods in fully qualified domain names!

The other portion that is different is the name of the zone. Reverse lookup zones are named by inverting the network address and adding ".in-addr.arpa" to it. For example, for a host with an IP address of 192.168.1.5, its network would be 192.168.1 (well, assuming you're using a /24 subnet mask). The reverse of the network would be 1.168.192. Slap on the ".in-addr.arpa" and you get the "1.168.192.in-addr.arpa" found in the zone above. Conversely, the filename for this zone would be db.192.168.1.

To load a reverse lookup zone, place the entry below in your named.conf file. The fields used are the same as those for a forward lookup zone.

zone "1.168.192.in-addr.arpa" in
{
    type    master;
    file    "db.192.168.1";
};

Zone Notation Shorthand

There are a few different shortcuts you can take when creating zone files. One allows you to use an @ symbol in place of $ORIGIN. The $ORIGIN for a zone file is specified in the named.conf configuration file in the zone field. In the reverse lookup example above, the $ORIGIN would be "1.168.192.in-addr.arpa". A revised version of the SOA and NS records for our reverse zone that uses @ notation would be:

@                   IN  SOA ns.example.com. root.example.com. (
                        2003040101      ; Serial
                        10800           ; Refresh after 3 hours
                        3600            ; Retry after 1 hour
                        604800          ; Expire after 1 week
                        86400 )         ; Minimum TTL of 1 day
                                
; name servers
@                   IN  NS  ns1.example.com.
@                   IN  NS  ns2.example.com.

Note that if a different $ORIGIN is declared within the zone file then it will be used instead. A similar shortcut is that if you do not declare a new name for a record, named will substitute the last one used. For example, the zone above and the zone below both do the same thing:

@                   IN  SOA ns.example.com. root.example.com. (
                        2003040101      ; Serial
                        10800           ; Refresh after 3 hours
                        3600            ; Retry after 1 hour
                        604800          ; Expire after 1 week
                        86400 )         ; Minimum TTL of 1 day
                                
; name servers
                    IN  NS  ns1.example.com.
                    IN  NS  ns2.example.com.

Notice that there is no indication of which host the NS records are for. Instead, it is assumed that the records are for the last entry used, which in this case is the @ record. These shortcuts should save you some time when creating zone files. By using them, you can also create generic zone files that will work with more than one lookup. A good use for this would be if you're running a web hosting service and have several zones that contain the exact same data. Create a single zone file that contains @ notation and then use it multiple times in your named.conf file.

The last shortcut I'll discuss is the use of non fully qualified domain names in zone files. In the example.com zone above, the www record is declared as:

www.example.com.    IN  A   192.168.1.5

If I were to specify just the host portion of this address, named will append the $ORIGIN to the end of the entry. This is the reason that you must be sure to put a trailing period on fully qualified domain names. The entry above and the entry below have the same result:

www                 IN  A   192.168.1.5

The named Configuration File

Using the blocks of data at the end of the various zone types above, you can create the majority of your named.conf configuration file with ease. The only remaining section is the options section declared at the top of the configuration file. The options section is used to specify parameters which affect named as a whole. Below is the example named.conf file, followed by explanations of the various sections:

//
// /etc/named.conf - Configuration file for named DNS server
//

// General Parameters
options
{
    directory "/var/named";
    
    forward first;
    forwarders
    {
        63.240.76.19;
        204.127.198.19;
    };
    
    allow-transfer
    {
        none;
    };
};


// Hint Zone
zone "." in
{
    type    hint;
    file    "named.ca";
};


// Domains (forward)
zone "example.com" in
{
    type    master;
    file    "db.example.com";
};


// Networks (reverse)
zone "0.0.127.in-addr.arpa" in
{
    type    master;
    file    "db.127.0.0";
};

zone "1.168.192.in-addr.arpa" in
{
    type    master;
    file    "db.192.168.1";
};

General Parameters

The options specified above work as follows: The directory declaration is used to determine where all of your zone files and other named configuration data is kept (this does not necessarily mean named.conf). The forward first and forwarders declarations tell named to forward all queries to the DNS servers listed before attempting to resolve the query on its own. Using query forwarding allows you to speed up your resolution process (it is usually quicker to query your ISP's server instead of the root servers). The allow-transfer section prevents unauthorized users from downloading entire copies of your zones. This is a security precaution that is similar to limiting someone to using directory assistance for telephone number lookups instead of giving them a phone book. The end user can only query for specific records instead of having access to the entire directory.

Domains and Networks

These sections contain the declarations for the zones above. Notice that in the Networks section there is a declaration for 0.0.127.in-addr.arpa. This zone represents the reverse lookup information for your machine's loopback address. Below is the zone's contents:

$TTL    86400
@       IN      SOA     localhost. root.localhost.  (
                                      1997022700 ; Serial
                                      28800      ; Refresh
                                      14400      ; Retry
                                      3600000    ; Expire
                                      86400 )    ; Minimum
              IN      NS      localhost.

1       IN      PTR     localhost.

Slave Servers and Zone Transfers

The final portion of the named.conf file that I'm going to cover is the configuration of slave servers. The DNS standards recommend that at least two name servers (on separate systems, networks, etc.) should be authoritative for your domain. While it is entirely possible to maintain two separate copies of a zone's data on two separate servers by hand, most administrators will instead choose to make one of the servers a master and the other a slave.

Slave servers use zone transfers to acquire their zone data from master servers. On the master server, you must allow your slave server to request whole zones. One the slave server, you must configure the slave to request zones from the master. Below are the two entries necessary; the first for the master, second for slave:

// master zone
zone "example.com" in
{
    type    master;
    file    "db.example.com";
    allow-transfer
    {
        192.168.1.3;
    };
};

// slave zone
zone "example.com" in
{
    type    slave;
    file    "db.example.com";
    masters
    {
        192.168.1.1;
    };
};

Final Thoughts

While I haven't touched upon every portion of BIND, this article provides enough information to get you started with a basic DNS setup. For further reading, I highly recommend DNS and BIND by Paul Albitz and Cricket Liu. It's a must read for anyone who will be working with BIND on a regular basis.

Jason Deraleau works as a systems administrator by day, IT consultant and technical writer by night, and is the coauthor of the upcoming Running Mac OS X Tiger.


Return to the Mac DevCenter.


Copyright © 2009 O'Reilly Media, Inc.