BIND

BIND is one of the premiere DNS servers on the Internet. Supplied by the ISC (Internet Systems Consortium), BIND is used, no doubt, by many of the domains with which you interact. A 2004 Survey showed that over 70% of nameservers on the Internet ran BIND at the time.

This article aims to explain how to install and configure BIND for use as a local caching, forwarding DNS server. The server can also be used to serve separate information externally. Automatic DNS updates from a DHCP server and other advanced configurations are currently beyond the scope of this document.

Why Use BIND?
There are easier to use DNS solutions out there, so why use BIND? The ISC's DNS server supports a number of features that many DNS solutions lack. If you wish to define your own domains (public or internal) and/or write and serve DNS records, BIND is for you. If you are tired of referring to hosts by IP, but do not want to maintain and distribute a hosts file, BIND is for you. Finally, if you wish to take advantage of the flexibility provided by administrative authority over your domain records (rrDNS, mx records, &c.) BIND is for you.

What is DNS?
DNS, the Domain Name System, is the primary method of discovering an IP address of a computer based on its name. Using DNS Record lookups, names like 'google.com' can be mapped to ip addresses like 72.14.207.99. DNS records also can be used to map an IP back to a name, to look up the mail hub for a given host, and for many other purposes. DNS could even be used to serve arbitrary data through TXT records.

How DNS Works
It will pay off to understand the essentials of DNS now, when we configure records below.

DNS servers provide records in answer to queries for various pieces of information, such as the address of a computer, or the geographical location of a network. (In fact, DNS could serve just about any information, but in practice is widely used only for network, host name,  and address information). The primary use of DNS is to allow domain names such as en.gentoo-wiki.com into ip addresses like 69.73.89.180, or to map the addresses back to host names like static-69-73-89-180.knology.net.

A DNS client, such as the web browser at which you look, connects to a DNS server when it needs to resolve domain names like en.gentoo-wiki.com. The host on which the browser runs - the computer you're using - is equipped with software libraries to contact the host's DNS server (generally provided via DHCP these days, or manually set), ask for the IP address of en.gentoo-wiki.com, and be told the answer.

A mail server also queries a DNS server to decide where to deliver mail. If you send an email to user@domain.com, your outgoing mail server will look up domain.com's mx records, and find that sentry.domainbank.com delivers domain.com's mail. (it will then query DNS again to discover sentry.domainbank.com's IP address). Mail servers also often use DNS to do reverse IP lookups - to look up a particular IP's given name (whether the host appears to be who it says it is when delivering mail), or to access additional information about who's allowed to send mail for that domain.

Queries consist of a given domain or subdomain, and a record type and name to be queried. For example, the first example query above was for an A record for en.gentoo-wiki.com. The second queried the MX record of domain.com. And the third query was for PTR records. Each of these queries was answered with a DNS hostname (like sentry.domainbank.com) or an IP address (like 69.73.89.180). Other types of queries might be for TXT records, which provide arbitrary textual data.

A discussion of each of the common record types follows.

Server Prerequisites
A DNS server doesn't require much. For a few dozen zones, you can expect named to use perhaps 24MB of memory and a few seconds processing time for every hour it's running.

Assume you are configuring a BIND server to answer some public queries as well as recursively look up and answer local queries. In this case, we assume the nameserver has three separate IP addresses:
 * 127.0.0.1: our local loopback device IP.
 * 192.168.1.1: our local area network IP.
 * 1.2.3.4: our external IP address.
 * home.local: our local-only, internal DNS domain.
 * home.net: our externally served domain.

USE Flags
As usual, the portage ebuild for BIND can be configured by USE flags. The only USE flag relevant to this discussion is SSL, which may or may not be necessary for your configuration.

Emerge
That's it! You're ready to start configuring BIND. Wasn't that easy? Thanks, Gentoo!

Editing named.conf
The hardest part of configuring BIND is writing named.conf. This file contains configuration for named, the BIND server daemon. Actual DNS records live elsewhere, as explained below.

Creating a Logging Configuration
Though not strictly required, adding a logging configuration like the one shown below is strongly recommended. Without logs, troubleshooting Internet services like BIND is nearly impossible. The following file sets out a logging configuration that will split various log entries into different files, thereby enhancing the usefulness of your logs.

Below, we define a number of files, each of which live in. We could also have included this information in named.conf directly, but then named.conf would be more difficult to read.

Before named can create the log files, you must create the directory /var/log/bind and change its permissions so that the named daemon can write to it, as shown below.

named.conf

 * options: global configuration options
 * view: a group of zones with an allow-query option that defines the clients to which to serve that zone

Using Views
Views are not a required part of a BIND configuration. However, views are a convenient way to avoid running different BIND servers with different zone information on the same box. Instead you can choose which clients see which zones as shown below. You can also configure different options (like recursion) for each view.

The tricky thing about views is that each client will be matched to the first view that client can query. For example, consider this snippet from named.conf, which provides a zone declaration for 'home.local' on the local view ("A"), and for 'home.net' on the unrestricted view ("B").

In the above case, a request from 127.0.0.1 for a host IP in 'home.net' would match view A first, but the zone doesn't exist in view A. You might expect the server to then match view B, the next view, which also matches 127.0.0.1 - but it won't!  Clients will only be served data from the first view they matched.

We will use views to provide a local-only domain for our LAN and to restrict recursion to local queries.

Zone Records
Zone records are fairly straightforward. There are many different kinds of records; the most relevant are SOA, NS, MX, A, and PTR records.

An example zone record
$ORIGIN local.tld. $TTL 1200


 * Everything under the following "@" block is for $ORIGIN.

@	IN	SOA	ns1.local.tld. hostmaster.local.tld. (				2009032201	; serial (YYYYMMDDrr)				1800		; refresh (30 minutes)				900		; retry (15 minutes)				1209600		; expire (2 weeks)				1200		; minimum TTL (20 minutes)			)

NS	ns1.local.tld. ; First nameserver. NS	ns2.local.tld. ; Second nameserver. (Two is most common, and better for redundancy.)

A	123.134.145.1		; Setting $ORIGIN to have this A record and therefore point to this IP.

MX	10 mail.local.tld. ; Setting $ORIGIN to use this MX record with a priority of 10. ; It is most common to begin with 10 and increase in tens.


 * Alphabetical order helps with clarity.

mail	A	192.168.1.89 ns1	A	192.168.1.90 ns2	A	192.168.1.91 www	CNAME	@				; This sets "www.local.tld" to point at "local.tld", because @ is substituted with $ORIGIN.

$ORIGIN

$ORIGIN is simply a variable appended to host names that do not end with a period, for ease and clarity. For example, the first $ORIGIN appends "local.tld." to the hostname of the SOA record: "@" becomes "local.tld.". Below, $ORIGIN is used in place of "local.tld" to avoid clutter.

The SOA Record

We have defined an Internet Start Of Authority record for the domain "local.tld," a zone which we have configured in named.conf. ns1.local.tld is the authoritative nameserver of the domain, and hostmaster.local.tld is the Admin's email address; note that the "@" symbol has become a "." so that "hostmaster@local.tld" is written "hostmaster.local.tld".

The serial number is incremented each time we change the zone record, so that BIND knows it's new. BIND can use any integer, but the standard syntax for the record contains a day of edit and version: YYYYMMDDrr. YYYYMMDD is the date it was last edited (year, month, and day) and "rr" is the revision number that day, starting at 01 and going up each time it is edited in the same day. We can tell from the serial shown above that the zone record was last edited on the 22nd of March, 2009, and that it was the first revision (edited only once that day).

The remaining TTLs describe how long served records are considered current. Higher values decrease lookups on the nameservers (because provided data will expire seldom) but would be a bad choice for domains that change their records frequently.

NS Records

NS records associate nameservers with the domain. This zone record itself would be provided to ns1.local.tld while ns2.local.tld would commonly be a slave nameserver that would synchronize with the master server after the TTL (Time To Live) expires. It is good practice to use two different nameservers for a domain; this is up to you on intranet zones, but you'll have a hard time configuring public domain names with only one server.

A Records

The IPv4 address of a host is stored in an A record. This core DNS feature allows names like yourbox.local.tld to point to an IP address. These records, though fundamental, are straightforward; the hostname goes on the left, the address on the right. The first A record shown here is for the domain name 'local.tld' itself. You might want to provide such a record if you wanted to be able to type your domain name into a browser and lookup a webserver. Intranet-only domains do not necessarily benefit from such a record, but if you find yourself both outside and inside your network regularly, it would be convenient to use the same domain names in browsers, mail clients, etc., from both locations. [In fact, the ability to 'redefine' your external addresses to point inside your firewalls is one of the primary benefits of running BIND in a small home environment, and indeed, the reason I started to use bind!] What we've done here, presumably listing our external IP address, might also work from the inside as it would from without, but only if no port-forwarding firewalls lived in between!

MX Records

The MX record of a host describes where the mail for that host should be delivered. In the example zone, we presume mail.local.tld is a mail hub of some kind, capable of delivering (or storing) mail for the specified host, $ORIGIN - local.tld. Although these records are technically mandatory for every host, they are only required if you wish mail to somebody @local.tld to be delivered.

CNAME Records

CNAMEs simply provide an alias; for example, in this configuration, a "www" host does not really exist, but will lookup the same as "domain.tld" itself, in essence making "www" optional at the beginning of web addresses. This may not be necessary or even desirable, however, I recommend it for records primarily used to refer to websites, as requiring either the presence or the lack of "www" confuses and annoys some people.

PTR Records

PTR records are probably the most difficult of records; this is good news actually, because even they aren't too tricky. They provide the - a - name of a host, given it's IP address. This presents 2 difficulties; we must fit the IP addressing scheme into DNS's data record scheme; and 2) we must decide which of a host's name is the one true name of the host.

Firstly, the technical challenge: the domain name system provides a hierarchical database where names start specific and end general, whereas the reverse is true of IP addresses. Take as an example of a long domain name, web16.webservers.google.com. web16 refers to the specific host, webservers the subdomain, and google.com the domain. In the case of IP addresses, the first few bytes of data generally define the network, and only the last several bits define the specific hosts. To address this inconsistency, the good people that have devised DNS for us have arbitrarily created the 'in-addr.arpa' domain, which exists solely to denote IP addresses and subnets. An example is in order: let's map out the IPv4 address 192.168.1.100 to an in-addr.arpa address. We start by reversing the octets of the ip address, obtaining 100.1.168.192. We now append in-addr.arpa, and we have the DNS equivilent of our given address: 100.1.168.192.in-addr.arpa. Fairly straightforward, right?

The second issue exists because we often specify multiple names for the same IP address. Perhaps the best example might be for virtual webservers; above, you may have noticed that the PTR record for the address to which we resolved en.gentoo-wiki.com was not en.gentoo-wiki.com; static-69-73-89-180.knology.net. is a webserver that serves webpages for en.gentoo-wiki.com as well as serving various other websites for various other domains. en.gentoo-wiki.com may well be served from other websevers with other IP addresses, each with unique PTR records. Since they are all virtual hosts, none of these servers could truly be called en.gentoo-wiki.com.

When you provide PTR records for your own hosts, you'll have to decide how to identify each IP address you list. Ideally, each IP address listed in an A record will have a corresponding PTR record.

PTR records must be defined after a SOA for an in-addr.arpa domain. Here is an example of a less complete reverse zone record, this one being for 192.168.1.0/24. It is the internal reverse record for local.tld, which we created the forward zone for above.

An example reverse zone record
$ORIGIN. ; We could also have used in-addr.arpa here, which we would then have removed from the SOA accordingly. $TTL 7200	; 2 hours

1.168.192.in-addr.arpa. IN SOA 1.168.192.in-addr.arpa. root.local.tld. (	2009041301	; serial	7200		; refresh (2 hours)	1800		; retry (30 minutes)	604800		; expire (1 week)	7200		; minimum (2 hours) )
 * We define the SOA:

NS ns1.local.tld. ; A nameserver for 1.168.192.in-addr.arpa. NS ns2.local.tld.

; It wouldn't make sense to list an A or MX record for an in-addr.arpa domain!

89	PTR	mail.local.tld. 90	PTR	ns1.local.tld. 91	PTR	ns2.local.tld.


 * Our domain IP, 123.134.145.1, does not belong in this zone. We therefore cannot list it here.


 * After you have created a zone record, make sure you run the following command to ensure the ownership of all zone records belongs to named:

Configuring a Secondary DNS Server
DNS is a critical component of a properly operating modern network. Since lacking dns generally equates to "the internet not working" for the lesser folk, it's imperative that network admins like ourselves take care of them and provide more than one DNS server. Thus we shall review configuring a slave server to accompany our master server.

Conveniently, secondary DNS servers are trivially easy to configure. Insofar as they do not require the master server to function, they are suitable as alternatives to the master server for any domain they replicate. Aside from updates sent from zone masters, DNS slave servers operate more or less independently of their masters.

Let's dive in. Hopefully, this named.conf file will look familiar:

No Records Provided
We won't need to give the slave server any zones; as long as it has write permissions, it will create its own zone files at the locations specified in named.conf.

Troubleshooting Your Configuration
So, configuring is not so bad! But what happens if you get everything set up just right then it fails to start!? Lucky you, there are several little tools you can use to troubleshoot your bind installation:

Run the following command:

This will install the bind-tools package that has a number of tools such as dig, nslookup, host, nsupdate, dnssec-keygen.

There are also a number of smaller utilities that come with bind. Namely, named-checkconf, named-checkzone, and named-compilezone.

After you have created your zones and set up named.conf the way you need it done, be sure to check these out!

1. Run named-checkconf without any parameters to check the status of your configuration file. If the script finds errors, it will let you know.

2. Once you've completed that, move onto the zone files. Each zone file must be fed into the named-checkzone script individually. Here is an example:

The script will inform you if your syntax is incorrect.

Troubleshooting a Working Server
So, named started and your DNS server is running, but you aren't seeing the results you expect. Time to look into the source of the problem! For the purposes of this exhibit, we'll be examining the domain danf.us, so you can see the results of a real domain.

First, let's try to determine the servers listed for the domain by the registrar.

We Get:

Name Server:                                NS1.FARRELLIT.NET Name Server:                                NS2.FARRELLIT.NET

In this case the nameserver responds:
 * <<>> DiG 9.4.3-P1 <<>> @ns1.farrellit.net danf.us
 * (1 server found)
 * global options: printcmd
 * Got answer:
 * ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53885
 * flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2
 * WARNING: recursion requested but not available


 * QUESTION SECTION:
 * danf.us.                      IN      A

danf.us. 7200   IN      A       66.191.143.115
 * ANSWER SECTION:

danf.us. 720    IN      NS      ns1.farrellit.net. danf.us. 720    IN      NS      ns2.farrellit.net.
 * AUTHORITY SECTION:

ns1.farrellit.net. 604800 IN      A       66.191.143.116 ns2.farrellit.net. 604800 IN      A       66.191.143.114
 * ADDITIONAL SECTION:


 * Query time: 60 msec
 * SERVER: 66.191.143.116#53(66.191.143.116)
 * WHEN: Mon Jul 6 16:48:51 2009
 * MSG SIZE rcvd: 122

Here is listed the answer to our query; the A record for danf.us (66.191.143.115) as well as the authority section (the nameservers listed by the registrar, as we already know) and the IP addresses of those authoritative servers (66.191.143.116 and ...114).

These results lead us to conclude that 1. The DNS server is picking up on the danf.us zone within 'named.conf. 2. The danf.us record is correct. 3. The registrar lists the correct nameservers for the domain.

Now Let's view some erroneous output.

Here we have intentionally queried the wrong domain name server: ns1.farrellit.net does not handle dns for gentoo-wiki.com and therefore would not be expected to answer the query. These results are analogous to a query for a domain that was not properly listed in the queried nameserver's named.conf.


 * <<>> DiG 9.4.3-P1 <<>> @ns1.farrellit.net gentoo-wiki.com
 * (1 server found)
 * global options: printcmd
 * Got answer:
 * ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26833
 * flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 13, ADDITIONAL: 0
 * WARNING: recursion requested but not available


 * QUESTION SECTION:
 * gentoo-wiki.com.              IN      A

.                      518400  IN      NS      C.ROOT-SERVERS.NET. .                      518400  IN      NS      A.ROOT-SERVERS.NET. .                      518400  IN      NS      I.ROOT-SERVERS.NET. .                      518400  IN      NS      B.ROOT-SERVERS.NET. .                      518400  IN      NS      G.ROOT-SERVERS.NET. .                      518400  IN      NS      E.ROOT-SERVERS.NET. .                      518400  IN      NS      J.ROOT-SERVERS.NET. .                      518400  IN      NS      F.ROOT-SERVERS.NET. .                      518400  IN      NS      K.ROOT-SERVERS.NET. .                      518400  IN      NS      L.ROOT-SERVERS.NET. .                      518400  IN      NS      H.ROOT-SERVERS.NET. .                      518400  IN      NS      M.ROOT-SERVERS.NET. .                      518400  IN      NS      D.ROOT-SERVERS.NET.
 * AUTHORITY SECTION:


 * Query time: 68 msec
 * SERVER: 66.191.143.116#53(66.191.143.116)
 * WHEN: Mon Jul 6 16:57:12 2009
 * MSG SIZE rcvd: 244

These results show that the domain in question is not listed in named.conf, either by deliberate omission or by error propogated by a type-o or misconfiguration in name.conf.

Now let's view the result of such a query if named.conf is correct but a zone file is missing. For this example, I've configured ns2.farrellit.net to serve the someplace.net zone, but have changed the permissions on the someplace.net zone record file to disallow reading by any user. In effect, the zone file does not exist.

We see the following [lack of] results:


 * <<>> DiG 9.4.3-P1 <<>> @ns2.farrellit.net someplace.net
 * (1 server found)
 * global options: printcmd
 * Got answer:
 * ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 17397
 * flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
 * WARNING: recursion requested but not available


 * QUESTION SECTION:
 * someplace.net.                IN      A

The answer in this case is different from the previous query for a domain not listed in named.conf. Instead of listing the root nameservers, tacitly admitting that it doesn't and oughtn't know the answer to this query, the server simply provides no answer. the status line near the top of DiG's output says SERVFAIL, meaning the server has failed to answer the request.
 * Query time: 60 msec
 * SERVER: 66.191.143.114#53(66.191.143.114)
 * WHEN: Mon Jul 6 17:12:17 2009
 * MSG SIZE rcvd: 31

Finally we look at a response from the nameserver if the file exists and is accessible, but does not list the record for which we search. In this case I have left the zone record absent of A records.

; <<>> DiG 9.4.3-P1 <<>> @ns2.farrellit.net someplace.net
 * (1 server found)
 * global options: printcmd
 * Got answer:
 * ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 18426
 * flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
 * WARNING: recursion requested but not available


 * QUESTION SECTION:
 * someplace.net.                IN      A

someplace.net. 720    IN      SOA     ns1.farrellit.net. dan.farrellit.net. 2009021601 7200 1800 7200 7200
 * AUTHORITY SECTION:

Here we see the result list the SOA record, indicating that it is parsing the zone record section. The combination of the status of NOERROR and the lack of an answer (ANSWER: 0) indicates that the record simply does not exist.
 * Query time: 57 msec
 * SERVER: 66.191.143.114#53(66.191.143.114)
 * WHEN: Mon Jul 6 17:24:06 2009
 * MSG SIZE rcvd: 85

Configuring Gentoo to Query your newly configured DNS server
When you're done with your server and all works you need to set /etc/conf.d/net so that it points to your dns server.

The following will configure the network startup scripts (such as /etc/init.d/net.eth0) of a gentoo box using DHCP to ignore DNS (as well as NTP and NIS) servers provided by DHCP and to use the manually provided DNS server instead.

These instructions are appropriate for any host that should use a specific DNS server rather than the server provided by DHCP. As written here, they are meant for the DNS server itself, but if 127.0.0.1 below were changed to an external address, the host would resolve domain names using that address.

1. nano /etc/conf.d/net

2. Adding the line dhcp_ethX="nodns nontp nonis" X marks the network card that is connected to the internet

3. now we need to set the ip for your name server it is 127.0.0.1 you do it like this dns_servers_ethX=( "127.0.0.1" ) X marks the network card that is connected to the internet

4. press Control-X to exit and save

Updating Backbone DNS Cache
Although this is not a Gentoo-specific issue, you should probably do this at least once, shortly after getting everything working. Run the following command: