FreeBSD Handbook
Prev | Chapter 29 Network Servers | Next

# 29.6 Domain Name System (DNS)

Contributed by Chern Lee, Tom Rhodes, and Daniel Gerzo.

## 29.6.1 Overview

FreeBSD utilizes, by default, a version of BIND (Berkeley Internet Name Domain), which is the most common implementation of the DNS protocol. DNS is the protocol through which names are mapped to IP addresses, and vice versa. For example, a query for `www.FreeBSD.org` will receive a reply with the IP address of The FreeBSD Project's web server, whereas, a query for `ftp.FreeBSD.org` will return the IP address of the corresponding FTP machine. Likewise, the opposite can happen. A query for an IP address can resolve its hostname. It is not necessary to run a name server to perform DNS lookups on a system.

FreeBSD currently comes with BIND9 DNS server software by default. Our installation provides enhanced security features, a new file system layout and automated chroot(8) configuration.

DNS is coordinated across the Internet through a somewhat complex system of authoritative root, Top Level Domain (TLD), and other smaller-scale name servers which host and cache individual domain information.

Currently, BIND is maintained by the Internet Systems Consortium https://www.isc.org/.

## 29.6.2 Terminology

To understand this document, some terms related to DNS must be understood.

Term | Definition
--- | ---
Forward DNS | Mapping of hostnames to IP addresses.
Origin | Refers to the domain covered in a particular zone file.
named, BIND | Common names for the BIND name server package within FreeBSD.
Resolver | A system process through which a machine queries a name server for zone information.
Reverse DNS | Mapping of IP addresses to hostnames.
Root zone | The beginning of the Internet zone hierarchy. All zones fall under the root zone, similar to how all files in a file system fall under the root directory.
Zone | An individual domain, subdomain, or portion of the DNS administered by the same authority.

Examples of zones:

- `.` is how the root zone is usually referred to in documentation.

- `org.` is a Top Level Domain (TLD) under the root zone.

- `example.org.` is a zone under the `org.` TLD.

- `1.168.192.in-addr.arpa` is a zone referencing all IP addresses which fall under the `192.168.1.*` IP address space.

As one can see, the more specific part of a hostname appears to its left. For example, `example.org.` is more specific than `org.`, as `org.` is more specific than the root zone. The layout of each part of a hostname is much like a file system: the `/dev` directory falls within the root, and so on.

## 29.6.3 Reasons to Run a Name Server

Name servers usually come in two forms: an authoritative name server, and a caching name server.

An authoritative name server is needed when:

- One wants to serve DNS information to the world, replying authoritatively to queries.

- A domain, such as `example.org`, is registered and IP addresses need to be assigned to hostnames under it.

- An IP address block requires reverse DNS entries (IP to hostname).

- A backup or second name server, called a slave, will reply to queries.

A caching name server is needed when:

- A local DNS server may cache and respond more quickly than querying an outside name server.

When one queries for `www.FreeBSD.org`, the resolver usually queries the uplink ISP's name server, and retrieves the reply. With a local, caching DNS server, the query only has to be made once to the outside world by the caching DNS server. Every additional query will not have to look to the outside of the local network, since the information is cached locally.

## 29.6.4 How It Works

In FreeBSD, the BIND daemon is called named.

File | Description
--- | ---
named(8) | The BIND daemon.
rndc(8) | Name server control utility.
`/etc/namedb` | Directory where BIND zone information resides.
`/etc/namedb/named.conf` | Configuration file of the daemon.

Depending on how a given zone is configured on the server, the files related to that zone can be found in the `master`, `slave`, or `dynamic` subdirectories of the `/etc/namedb` directory. These files contain the DNS information that will be given out by the name server in response to queries.

## 29.6.5 Starting BIND

Since BIND is installed by default, configuring it all is relatively simple.

The default named configuration is that of a basic resolving name server, running in a chroot(8) environment, and restricted to listening on the local IPv4 loopback address (127.0.0.1). To start the server one time with this configuration, use the following command:

    # /etc/rc.d/named onestart

To ensure the named daemon is started at boot each time, put the following line into the `/etc/rc.conf`:

    named_enable="YES"

There are obviously many configuration options for `/etc/namedb/named.conf` that are beyond the scope of this document. However, if you are interested in the startup options for named on FreeBSD, take a look at the `named_`*`` flags in `/etc/defaults/rc.conf` and consult the rc.conf(5) manual page. The Section 11.7 section is also a good read.

## 29.6.6 Configuration Files

Configuration files for named currently reside in `/etc/namedb` directory and will need modification before use unless all that is needed is a simple resolver. This is where most of the configuration will be performed.

### 29.6.6.1 `/etc/namedb/named.conf`

    // $FreeBSD$
    //
    // Refer to the named.conf(5) and named(8) man pages, and the documentation
    // in /usr/share/doc/bind9 for more details.
    //
    // If you are going to set up an authoritative server, make sure you
    // understand the hairy details of how DNS works.  Even with
    // simple mistakes, you can break connectivity for affected parties,
    // or cause huge amounts of useless Internet traffic.

    options {
        // Relative to the chroot directory, if any
        directory   "/etc/namedb";
        pid-file    "/var/run/named/pid";
        dump-file   "/var/dump/named_dump.db";
        statistics-file "/var/stats/named.stats";

    // If named is being used only as a local resolver, this is a safe default.
    // For named to be accessible to the network, comment this option, specify
    // the proper IP address, or delete this option.
        listen-on   { 127.0.0.1; };

    // If you have IPv6 enabled on this system, uncomment this option for
    // use as a local resolver.  To give access to the network, specify
    // an IPv6 address, or the keyword "any".
    //  listen-on-v6    { ::1; };

    // These zones are already covered by the empty zones listed below.
    // If you remove the related empty zones below, comment these lines out.
        disable-empty-zone "255.255.255.255.IN-ADDR.ARPA";
        disable-empty-zone "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA";
        disable-empty-zone "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA";

    // If you've got a DNS server around at your upstream provider, enter
    // its IP address here, and enable the line below.  This will make you
    // benefit from its cache, thus reduce overall DNS traffic in the Internet.
    /*
        forwarders {
            127.0.0.1;
        };
    */

    // If the 'forwarders' clause is not empty the default is to 'forward first'
    // which will fall back to sending a query from your local server if the name
    // servers in 'forwarders' do not have the answer.  Alternatively you can
    // force your name server to never initiate queries of its own by enabling the
    // following line:
    //  forward only;

    // If you wish to have forwarding configured automatically based on
    // the entries in /etc/resolv.conf, uncomment the following line and
    // set named_auto_forward=yes in /etc/rc.conf.  You can also enable
    // named_auto_forward_only (the effect of which is described above).
    //  include "/etc/namedb/auto_forward.conf";

Just as the comment says, to benefit from an uplink's cache, `forwarders` can be enabled here. Under normal circumstances, a name server will recursively query the Internet looking at certain name servers until it finds the answer it is looking for. Having this enabled will have it query the uplink's name server (or name server provided) first, taking advantage of its cache. If the uplink name server in question is a heavily trafficked, fast name server, enabling this may be worthwhile.

> Warning: `127.0.0.1` will not work here. Change this IP address to a name server at your uplink.

       /*
           Modern versions of BIND use a random UDP port for each outgoing
           query by default in order to dramatically reduce the possibility
           of cache poisoning.  All users are strongly encouraged to utilize
           this feature, and to configure their firewalls to accommodate it.

           AS A LAST RESORT in order to get around a restrictive firewall
           policy you can try enabling the option below.  Use of this option
           will significantly reduce your ability to withstand cache poisoning
           attacks, and should be avoided if at all possible.

           Replace NNNNN in the example with a number between 49160 and 65530.
        */
        // query-source address * port NNNNN;
    };

    // If you enable a local name server, don't forget to enter 127.0.0.1
    // first in your /etc/resolv.conf so this server will be queried.
    // Also, make sure to enable it in /etc/rc.conf.

    // The traditional root hints mechanism. Use this, OR the slave zones below.
    zone "." { type hint; file "named.root"; };

    /*  Slaving the following zones from the root name servers has some
        significant advantages:
        1. Faster local resolution for your users
        2. No spurious traffic will be sent from your network to the roots
        3. Greater resilience to any potential root server failure/DDoS

        On the other hand, this method requires more monitoring than the
        hints file to be sure that an unexpected failure mode has not
        incapacitated your server.  Name servers that are serving a lot
        of clients will benefit more from this approach than individual
        hosts.  Use with caution.

        To use this mechanism, uncomment the entries below, and comment
        the hint zone above.
    */
    /*
    zone "." {
        type slave;
        file "slave/root.slave";
        masters {
            192.5.5.241;    // F.ROOT-SERVERS.NET.
        };
        notify no;
    };
    zone "arpa" {
        type slave;
        file "slave/arpa.slave";
        masters {
            192.5.5.241;    // F.ROOT-SERVERS.NET.
        };
        notify no;
    };
    zone "in-addr.arpa" {
        type slave;
        file "slave/in-addr.arpa.slave";
        masters {
            192.5.5.241;    // F.ROOT-SERVERS.NET.
        };
        notify no;
    };
    */

    /*  Serving the following zones locally will prevent any queries
        for these zones leaving your network and going to the root
        name servers.  This has two significant advantages:
        1. Faster local resolution for your users
        2. No spurious traffic will be sent from your network to the roots
    */
    // RFC 1912
    zone "localhost"    { type master; file "master/localhost-forward.db"; };
    zone "127.in-addr.arpa" { type master; file "master/localhost-reverse.db"; };
    zone "255.in-addr.arpa" { type master; file "master/empty.db"; };

    // RFC 1912-style zone for IPv6 localhost address
    zone "0.ip6.arpa"   { type master; file "master/localhost-reverse.db"; };

    // "This" Network (RFCs 1912 and 3330)
    zone "0.in-addr.arpa"       { type master; file "master/empty.db"; };

    // Private Use Networks (RFC 1918)
    zone "10.in-addr.arpa"      { type master; file "master/empty.db"; };
    zone "16.172.in-addr.arpa"  { type master; file "master/empty.db"; };
    zone "17.172.in-addr.arpa"  { type master; file "master/empty.db"; };
    zone "18.172.in-addr.arpa"  { type master; file "master/empty.db"; };
    zone "19.172.in-addr.arpa"  { type master; file "master/empty.db"; };
    zone "20.172.in-addr.arpa"  { type master; file "master/empty.db"; };
    zone "21.172.in-addr.arpa"  { type master; file "master/empty.db"; };
    zone "22.172.in-addr.arpa"  { type master; file "master/empty.db"; };
    zone "23.172.in-addr.arpa"  { type master; file "master/empty.db"; };
    zone "24.172.in-addr.arpa"  { type master; file "master/empty.db"; };
    zone "25.172.in-addr.arpa"  { type master; file "master/empty.db"; };
    zone "26.172.in-addr.arpa"  { type master; file "master/empty.db"; };
    zone "27.172.in-addr.arpa"  { type master; file "master/empty.db"; };
    zone "28.172.in-addr.arpa"  { type master; file "master/empty.db"; };
    zone "29.172.in-addr.arpa"  { type master; file "master/empty.db"; };
    zone "30.172.in-addr.arpa"  { type master; file "master/empty.db"; };
    zone "31.172.in-addr.arpa"  { type master; file "master/empty.db"; };
    zone "168.192.in-addr.arpa" { type master; file "master/empty.db"; };

    // Link-local/APIPA (RFCs 3330 and 3927)
    zone "254.169.in-addr.arpa" { type master; file "master/empty.db"; };

    // TEST-NET for Documentation (RFC 3330)
    zone "2.0.192.in-addr.arpa" { type master; file "master/empty.db"; };

    // Router Benchmark Testing (RFC 3330)
    zone "18.198.in-addr.arpa"  { type master; file "master/empty.db"; };
    zone "19.198.in-addr.arpa"  { type master; file "master/empty.db"; };

    // IANA Reserved - Old Class E Space
    zone "240.in-addr.arpa"     { type master; file "master/empty.db"; };
    zone "241.in-addr.arpa"     { type master; file "master/empty.db"; };
    zone "242.in-addr.arpa"     { type master; file "master/empty.db"; };
    zone "243.in-addr.arpa"     { type master; file "master/empty.db"; };
    zone "244.in-addr.arpa"     { type master; file "master/empty.db"; };
    zone "245.in-addr.arpa"     { type master; file "master/empty.db"; };
    zone "246.in-addr.arpa"     { type master; file "master/empty.db"; };
    zone "247.in-addr.arpa"     { type master; file "master/empty.db"; };
    zone "248.in-addr.arpa"     { type master; file "master/empty.db"; };
    zone "249.in-addr.arpa"     { type master; file "master/empty.db"; };
    zone "250.in-addr.arpa"     { type master; file "master/empty.db"; };
    zone "251.in-addr.arpa"     { type master; file "master/empty.db"; };
    zone "252.in-addr.arpa"     { type master; file "master/empty.db"; };
    zone "253.in-addr.arpa"     { type master; file "master/empty.db"; };
    zone "254.in-addr.arpa"     { type master; file "master/empty.db"; };

    // IPv6 Unassigned Addresses (RFC 4291)
    zone "1.ip6.arpa"       { type master; file "master/empty.db"; };
    zone "3.ip6.arpa"       { type master; file "master/empty.db"; };
    zone "4.ip6.arpa"       { type master; file "master/empty.db"; };
    zone "5.ip6.arpa"       { type master; file "master/empty.db"; };
    zone "6.ip6.arpa"       { type master; file "master/empty.db"; };
    zone "7.ip6.arpa"       { type master; file "master/empty.db"; };
    zone "8.ip6.arpa"       { type master; file "master/empty.db"; };
    zone "9.ip6.arpa"       { type master; file "master/empty.db"; };
    zone "a.ip6.arpa"       { type master; file "master/empty.db"; };
    zone "b.ip6.arpa"       { type master; file "master/empty.db"; };
    zone "c.ip6.arpa"       { type master; file "master/empty.db"; };
    zone "d.ip6.arpa"       { type master; file "master/empty.db"; };
    zone "e.ip6.arpa"       { type master; file "master/empty.db"; };
    zone "0.f.ip6.arpa"     { type master; file "master/empty.db"; };
    zone "1.f.ip6.arpa"     { type master; file "master/empty.db"; };
    zone "2.f.ip6.arpa"     { type master; file "master/empty.db"; };
    zone "3.f.ip6.arpa"     { type master; file "master/empty.db"; };
    zone "4.f.ip6.arpa"     { type master; file "master/empty.db"; };
    zone "5.f.ip6.arpa"     { type master; file "master/empty.db"; };
    zone "6.f.ip6.arpa"     { type master; file "master/empty.db"; };
    zone "7.f.ip6.arpa"     { type master; file "master/empty.db"; };
    zone "8.f.ip6.arpa"     { type master; file "master/empty.db"; };
    zone "9.f.ip6.arpa"     { type master; file "master/empty.db"; };
    zone "a.f.ip6.arpa"     { type master; file "master/empty.db"; };
    zone "b.f.ip6.arpa"     { type master; file "master/empty.db"; };
    zone "0.e.f.ip6.arpa"       { type master; file "master/empty.db"; };
    zone "1.e.f.ip6.arpa"       { type master; file "master/empty.db"; };
    zone "2.e.f.ip6.arpa"       { type master; file "master/empty.db"; };
    zone "3.e.f.ip6.arpa"       { type master; file "master/empty.db"; };
    zone "4.e.f.ip6.arpa"       { type master; file "master/empty.db"; };
    zone "5.e.f.ip6.arpa"       { type master; file "master/empty.db"; };
    zone "6.e.f.ip6.arpa"       { type master; file "master/empty.db"; };
    zone "7.e.f.ip6.arpa"       { type master; file "master/empty.db"; };

    // IPv6 ULA (RFC 4193)
    zone "c.f.ip6.arpa"     { type master; file "master/empty.db"; };
    zone "d.f.ip6.arpa"     { type master; file "master/empty.db"; };

    // IPv6 Link Local (RFC 4291)
    zone "8.e.f.ip6.arpa"       { type master; file "master/empty.db"; };
    zone "9.e.f.ip6.arpa"       { type master; file "master/empty.db"; };
    zone "a.e.f.ip6.arpa"       { type master; file "master/empty.db"; };
    zone "b.e.f.ip6.arpa"       { type master; file "master/empty.db"; };

    // IPv6 Deprecated Site-Local Addresses (RFC 3879)
    zone "c.e.f.ip6.arpa"       { type master; file "master/empty.db"; };
    zone "d.e.f.ip6.arpa"       { type master; file "master/empty.db"; };
    zone "e.e.f.ip6.arpa"       { type master; file "master/empty.db"; };
    zone "f.e.f.ip6.arpa"       { type master; file "master/empty.db"; };

    // IP6.INT is Deprecated (RFC 4159)
    zone "ip6.int"          { type master; file "master/empty.db"; };

    // NB: Do not use the IP addresses below, they are faked, and only
    // serve demonstration/documentation purposes!
    //
    // Example slave zone config entries.  It can be convenient to become
    // a slave at least for the zone your own domain is in.  Ask
    // your network administrator for the IP address of the responsible
    // master name server.
    //
    // Do not forget to include the reverse lookup zone!
    // This is named after the first bytes of the IP address, in reverse
    // order, with ".IN-ADDR.ARPA" appended, or ".IP6.ARPA" for IPv6.
    //
    // Before starting to set up a master zone, make sure you fully
    // understand how DNS and BIND work.  There are sometimes
    // non-obvious pitfalls.  Setting up a slave zone is usually simpler.
    //
    // NB: Don't blindly enable the examples below. :-)  Use actual names
    // and addresses instead.

    /* An example dynamic zone
    key "exampleorgkey" {
        algorithm hmac-md5;
        secret "sf87HJqjkqh8ac87a02lla==";
    };
    zone "example.org" {
        type master;
        allow-update {
            key "exampleorgkey";
        };
        file "dynamic/example.org";
    };
    */

    /* Example of a slave reverse zone
    zone "1.168.192.in-addr.arpa" {
        type slave;
        file "slave/1.168.192.in-addr.arpa";
        masters {
            192.168.1.1;
        };
    };
    */

In `named.conf`, these are examples of slave entries for a forward and reverse zone.

For each new zone served, a new zone entry must be added to `named.conf`.

For example, the simplest zone entry for `example.org` can look like:

    zone "example.org" {
        type master;
        file "master/example.org";
    };

The zone is a master, as indicated by the `type` statement, holding its zone information in `/etc/namedb/master/example.org` indicated by the `file` statement.

    zone "example.org" {
        type slave;
        file "slave/example.org";
    };

In the slave case, the zone information is transferred from the master name server for the particular zone, and saved in the file specified. If and when the master server dies or is unreachable, the slave name server will have the transferred zone information and will be able to serve it.

### 29.6.6.2 Zone Files

An example master zone file for `example.org` (existing within `/etc/namedb/master/example.org`) is as follows:

    $TTL 3600        ; 1 hour default TTL
    example.org.    IN      SOA      ns1.example.org. admin.example.org. (
                                    2006051501      ; Serial
                                    10800           ; Refresh
                                    3600            ; Retry
                                    604800          ; Expire
                                    300             ; Negative Reponse TTL
                            )

    ; DNS Servers
                    IN      NS      ns1.example.org.
                    IN      NS      ns2.example.org.

    ; MX Records
                    IN      MX 10   mx.example.org.
                    IN      MX 20   mail.example.org.

                    IN      A       192.168.1.1

    ; Machine Names
    localhost       IN      A       127.0.0.1
    ns1             IN      A       192.168.1.2
    ns2             IN      A       192.168.1.3
    mx              IN      A       192.168.1.4
    mail            IN      A       192.168.1.5

    ; Aliases
    www             IN      CNAME   example.org.

Note that every hostname ending in a “.” is an exact hostname, whereas everything without a trailing “.” is relative to the origin. For example, `ns1` is translated into `ns1.`example.org.``

The format of a zone file follows:

    recordname      IN recordtype   value

The most commonly used DNS records:

SOA

  start of zone authority

NS

  an authoritative name server

A

  a host address

CNAME

  the canonical name for an alias

MX

  mail exchanger

PTR

  a domain name pointer (used in reverse DNS)

    example.org. IN SOA ns1.example.org. admin.example.org. (
                            2006051501      ; Serial
                            10800           ; Refresh after 3 hours
                            3600            ; Retry after 1 hour
                            604800          ; Expire after 1 week
                            300 )           ; Negative Reponse TTL

`example.org.`

  the domain name, also the origin for this zone file.

`ns1.example.org.`

  the primary/authoritative name server for this zone.

`admin.example.org.`

  the responsible person for this zone, email address with “@” replaced. (`<admin@example.org>` becomes `admin.example.org`)

`2006051501`

  the serial number of the file. This must be incremented each time the zone file is modified. Nowadays, many admins prefer a `yyyymmddrr` format for the serial number. `2006051501` would mean last modified 05/15/2006, the latter `01` being the first time the zone file has been modified this day. The serial number is important as it alerts slave name servers for a zone when it is updated.

           IN NS           ns1.example.org.

This is an NS entry. Every name server that is going to reply authoritatively for the zone must have one of these entries.

    localhost       IN      A       127.0.0.1
    ns1             IN      A       192.168.1.2
    ns2             IN      A       192.168.1.3
    mx              IN      A       192.168.1.4
    mail            IN      A       192.168.1.5

The A record indicates machine names. As seen above, `ns1.example.org` would resolve to `192.168.1.2`.

                    IN      A       192.168.1.1

This line assigns IP address `192.168.1.1` to the current origin, in this case `example.org`.

    www             IN CNAME        @

The canonical name record is usually used for giving aliases to a machine. In the example, `www` is aliased to the “master” machine whose name happens to be the same as the domain name `example.org` (`192.168.1.1`). CNAMEs can never be used together with another kind of record for the same hostname.

                   IN MX   10      mail.example.org.

The MX record indicates which mail servers are responsible for handling incoming mail for the zone. `mail.example.org` is the hostname of the mail server, and 10 being the priority of that mail server.

One can have several mail servers, with priorities of 10, 20 and so on. A mail server attempting to deliver to `example.org` would first try the highest priority MX (the record with the lowest priority number), then the second highest, etc, until the mail can be properly delivered.

For in-addr.arpa zone files (reverse DNS), the same format is used, except with PTR entries instead of A or CNAME.

    $TTL 3600

    1.168.192.in-addr.arpa. IN SOA ns1.example.org. admin.example.org. (
                            2006051501      ; Serial
                            10800           ; Refresh
                            3600            ; Retry
                            604800          ; Expire
                            300 )           ; Negative Reponse TTL

            IN      NS      ns1.example.org.
            IN      NS      ns2.example.org.

    1       IN      PTR     example.org.
    2       IN      PTR     ns1.example.org.
    3       IN      PTR     ns2.example.org.
    4       IN      PTR     mx.example.org.
    5       IN      PTR     mail.example.org.

This file gives the proper IP address to hostname mappings of our above fictitious domain.

It is worth noting that all names on the right side of a PTR record need to be fully qualified (i.e., end in a “.”).

## 29.6.7 Caching Name Server

A caching name server is a name server whose primary role is to resolve recursive queries. It simply asks queries of its own, and remembers the answers for later use.

## 29.6.8 Security

Although BIND is the most common implementation of DNS, there is always the issue of security. Possible and exploitable security holes are sometimes found.

While FreeBSD automatically drops named into a chroot(8) environment; there are several other security mechanisms in place which could help to lure off possible DNS service attacks.

It is always good idea to read CERT's security advisories and to subscribe to the FreeBSD security notifications mailing list to stay up to date with the current Internet and FreeBSD security issues.

> Tip: If a problem arises, keeping sources up to date and having a fresh build of named would not hurt.

## 29.6.9 Further Reading

BIND/named manual pages: rndc(8) named(8) named.conf(5)

- Official ISC BIND Page

- Official ISC BIND Forum

- O'Reilly DNS and BIND 5th Edition

- RFC1034 - Domain Names - Concepts and Facilities

- RFC1035 - Domain Names - Implementation and Specification

Prev | Home | Next
Automatic Network Configuration (DHCP) | Up | Apache HTTP Server

This, and other documents, can be downloaded from ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

For questions about FreeBSD, read the documentation before contacting <questions@FreeBSD.org>.
For questions about this documentation, e-mail <doc@FreeBSD.org>.