Secure BIND Template Version 5.1 05 JAN 2006

By Rob Thomas, robt at cymru.com

Changes in version 5.1: Changes in version 5.0: Changes in version 4.9: Changes in version 4.8: Changes in version 4.7: Changes in version 4.6: Changes in version 4.5: Changes in version 4.4: Changes in version 4.3: Changes in version 4.2: Changes in version 4.1: Changes in version 4.0: Changes in version 3.9: Changes in version 3.8: Changes in version 3.7a: Changes in version 3.7: Changes in version 3.6: Changes in version 3.5:

Changes in version 3.4:


Changes in version 3.0:


Changes in version 3.1:


Changes in version 3.2:


Changes in version 3.3:

Introduction

The ubiquitous BIND (Berkeley Internet Name Domain) server is distributed with most UNIX variants and provides name services to countless networks.  However, the BIND server is not without certain vulnerabilities, and is often a choice target for Internet vandals.  These vandals utilize BIND vulnerabilities to gain root access to the host or to turn the host into a launching platform for DDOS attacks.  An improper or insufficiently robust BIND configuration can also "leak" information about the hosts and addressing within the intranet.  Miscreants can also take advantage of an insecure BIND configuration and poison the cache, thus permitting host impersonation and redirecting legitimate traffic to black holes or malicious hosts. This article presents a template for deploying a secure BIND configuration, thus mitigating some of the risk of running the BIND server.

If you are not familiar with BIND configuration, I highly recommend that you pick up a copy of DNS and BIND, by Albitz and Liu, published by O'Reilly and Associates.

There are numerous RFCs and FAQs associated with DNS. I value the following most of all:

Obtaining assistance with the BIND is easily done, as there is a large community of clueful folks both developing and using the BIND. You may wish to subscribe to the BIND9 mailing list.

There are several documents detailing the risks of improperly configured BIND servers, or risks in the older versions of BIND. Please take a look at the following:

As a prerequisite, the host on which the BIND is run should be secured with the latest patches and armoring techniques. The IP stack should also be tuned to provide robust performance and resistance to DoS attacks. Please review my IP Stack Tuning Guide for suggestions along these lines.

If you are looking for the previous version of the Secure BIND Template that includes the split-brain DNS method and support for BIND 8, please read the Secure BIND Template Version 2.2 . Versions of the BIND template prior to 3.0 are no longer under active development, though I will continue to answer questions on version 2.2.

While I list the bogon ranges in this template on /8 boundaries, you may prefer a greater level of aggregation. For this please see my Bogon List.

It is not enough to secure the name server itself or the BIND software configuration. The border must also be resistant to attacks, and can be used to defend the name servers. Please take a look at the Secure IOS Template as well as the Secure BGP Template for ideas on border defense using Cisco routers.

Please feel free to share any suggestions or bug reports with me. This template would not be half as useful without the suggestions and insights of those who have read it. Feedback is always welcome! Send all feedback to robt@cymru.com.

Credits

My thanks to several folks who offered suggestions, input, and took the time to review this document. Special thanks go out to Roy Arends, who contributed copious amounts of time, numerous reviews, lots of great ideas, and several valuable lessons. :)

Tools

There exist myriad tools for debugging BIND configuration errors.  Aside from the log files, I recommend that you include the following tools in your DNS toolbox. Keep in mind that the miscreants often use these tools when scanning a network, so it is a good idea to test your network security before someone with evil intent scans your network.

Secure the BIND Configuration

The following configuration presumes that the host network is connected to the Internet.  It is assumed that the reader has a working knowledge of the BIND version 9, as this article will not detail the creation of zone files or general DNS configuration and maintenance.  Instead, this article supplements and protects an existing BIND configuration.  This is a "split brain" DNS model using the views feature of BIND 9.

For our purposes, we will assume that our external (visible to the Internet) network is 8.8.8.0/24.  Our internal network is 7.7.7.0/24. In your network, this may be a netblock from the RFC1918 address space. Our name server has the IP address 8.8.8.1.

Technicality: Our bogon ACL would block all queries from hosts in the 7.7.7.0/24 netblock. This is an example only, after all, so please do not use 7.7.7.0/24 as your internal netblock, and do not remove 7.7.7.0/24 from the bogon ACL list. See RFC1918 for the details regarding the three netblocks (10/8, 172.16/12, and 192.168/16) designated for internal only use.

Ensure that you have the latest version of the BIND.  You can obtain the latest version by visiting the Internet Software Consortium BIND site at http://www.isc.org/products/BIND/  The compilation and installation of the BIND is well detailed at this site. This template has been most recently tested with BIND version 9.1.3.

BIND 9.1.3 contains two interesting records in the CHAOS class - version.bind and authors.bind, both type TXT.  The version.bind TXT record will return the version of BIND running on the server.  The authors.bind TXT records (by default, there are multiple TXT records for authors.bind) will return a list of the authors of the BIND 9.X.  While the version.bind TXT record may assist admins, it runs counter to the philosophy of "keep the miscreants guessing."  Some of the scanning tools used by the miscreants query for the BIND version. For this reason, it is recommended that you hide these records from external hosts.  This is done through a view, and it will be demonstrated in the template below.

You may wish to ensure that your BGP configuration does not dampen the netblocks that contain the DNS root servers.  Please consult my Secure BGP Template for further details on this topic.

The chroot Jail

It is best to run BIND in a chroot'd jail.  This will prevent a miscreant from using named to access or manipulate other files on the host system, as well as preventing an overflow in BIND from granting a shell to the miscreant.  Presently, this document contains links to a chroot jail for Solaris, FreeBSD, and Linux.  Other will be added as time and testing allow.

After building the chroot environment, create a small passwd file in the jail.  The passwd file should contain only a root account and the BIND user.  Call the user under which BIND will run named.  Assign a UID greater than 100 to the named user, and remember to sync up the passwd file with the shadow file (pwconv in Solaris).  Do not create a password for this accounts.  Instead, lock it with entries in the shadow file such as this one:

root:*LK*:6445::::::
named:*LK*:11136::::::

I recommend using a shell that will allow no access, such as my own denial shell, nocando.  The nocando denial shell, which includes detailed logging, can be found in the Tools section of my web site.  The home directory for this account will be the directory we create below.

Next, create a directory structure to contain our configuration files.  For example, use /jail/bind/var/named. In this directory, create a subdirectory named master for our master zones and slave for our slave zones, if such zones exist.  Change the ownership of these subdirectories to the proper named UID, e.g.:

chown -R named:named /jail/bind/var/named

Configure the zone files normally, and place them in the proper subdirectories.  Don't forget the hint file (often named db.cache), the loopback zone, and a named.conf file.  Details regarding the creation of the hint and zone files can be found in the following:

We will now configure the named configuration files, with views for internal and external clients.

named.conf

The ordering of our views is very important. The named daemon accepts the first match. Because our external view permits all clients, our internal clients also match this view. For this reason we place our internal view first (permitting only our approved internal hosts) and our external view second (permitting all comers).

// @(#)named.conf 02 OCT 2001 Rob Thomas robt@cymru.com
// Set up our ACLs
// In BIND 8, ACL names with quotes were treated as different from
// the same name without quotes. In BIND 9, both are treated as
// the same.
acl "xfer" {
    none;   // Allow no transfers.  If we have other
            // name servers, place them here.
            // Note that in the Netherlands, for example,
            // the TLD servers 193.176.144.2, 194.53.253.100, and 193.176.144.128/28
            // are allowed to perform zone tranfers from the domains under .nl. The
            // RIPE NCC had requested in the past that reverse (in-addr.arpa) zones
            // permit zone transfer requests from 193.0.0.0/23.
};

acl "trusted" {


};

acl "bogon" {
    // Filter out the bogon networks.  These are networks
    // listed by IANA as test, RFC1918, Multicast, experi-
    // mental, etc.  If you see DNS queries or updates with
    // a source address within these networks, this is likely
    // of malicious origin. CAUTION: If you are using RFC1918
    // netblocks on your network, remove those netblocks from
    // this list of blackhole ACLs!
    0.0.0.0/8;
    1.0.0.0/8;
    2.0.0.0/8;
    5.0.0.0/8;
    7.0.0.0/8;
    10.0.0.0/8;
    23.0.0.0/8;
    27.0.0.0/8;
    31.0.0.0/8;
    36.0.0.0/8;
    37.0.0.0/8;
    39.0.0.0/8;
    42.0.0.0/8;
    49.0.0.0/8;
    50.0.0.0/8;
    77.0.0.0/8;
    78.0.0.0/8;
    79.0.0.0/8;
    92.0.0.0/8;
    93.0.0.0/8;
    94.0.0.0/8;
    95.0.0.0/8;
    96.0.0.0/8;
    97.0.0.0/8;
    98.0.0.0/8;
    99.0.0.0/8;
    100.0.0.0/8;
    101.0.0.0/8;
    102.0.0.0/8;
    103.0.0.0/8;
    104.0.0.0/8;
    105.0.0.0/8;
    106.0.0.0/8;
    107.0.0.0/8;
    108.0.0.0/8;
    109.0.0.0/8;
    110.0.0.0/8;
    111.0.0.0/8;
    112.0.0.0/8;
    113.0.0.0/8;
    114.0.0.0/8;
    115.0.0.0/8;
    116.0.0.0/8;
    117.0.0.0/8;
    118.0.0.0/8;
    119.0.0.0/8;
    120.0.0.0/8;
    169.254.0.0/16;
    172.16.0.0/12;
    173.0.0.0/8;
    174.0.0.0/8;
    175.0.0.0/8;
    176.0.0.0/8;
    177.0.0.0/8;
    178.0.0.0/8;
    179.0.0.0/8;
    180.0.0.0/8;
    181.0.0.0/8;
    182.0.0.0/8;
    183.0.0.0/8;
    184.0.0.0/8;
    185.0.0.0/8;
    186.0.0.0/8;
    187.0.0.0/8;
    192.0.2.0/24;
    192.168.0.0/16;
    197.0.0.0/8;
    223.0.0.0/8;
    224.0.0.0/3;
};


logging {


};

// Set options for security
options {
    directory "/var/named";
    pid-file "/var/named/named.pid";
    statistics-file "/var/named/named.stats";
    memstatistics-file "/var/named/named.memstats";
    dump-file "/var/adm/named.dump";
    zone-statistics yes;

    // Prevent DoS attacks by generating bogus zone transfer
    // requests.  This will result in slower updates to the
    // slave servers (e.g. they will await the poll interval
    // before checking for updates).
    notify no;

            // Generate more efficient zone transfers.  This will place
    // multiple DNS records in a DNS message, instead of one per
    // DNS message.
    transfer-format many-answers;

    // Set the maximum zone transfer time to something more
    // reasonable.  In this case, we state that any zone transfer
    // that takes longer than 60 minutes is unlikely to ever
    // complete.  WARNING:  If you have very large zone files,
    // adjust this to fit your requirements.
    max-transfer-time-in 60;

    // We have no dynamic interfaces, so BIND shouldn't need to
    // poll for interface state {UP|DOWN}.
    interface-interval 0;

    allow-transfer {
        // Zone tranfers limited to members of the
        // "xfer" ACL.
        xfer;
    };

    allow-query {
        // Accept queries from our "trusted" ACL.  We will
        // allow anyone to query our master zones below.
        // This prevents us from becoming a free DNS server
        // to the masses.
        trusted;
    };

    blackhole {
        // Deny anything from the bogon networks as
        // detailed in the "bogon" ACL.
        bogon;
    };
};


view "internal-in" in {
    // Our internal (trusted) view. We permit the internal networks
    // to freely access this view. We perform recursion for our
    // internal hosts, and retrieve data from the cache for them.

    match-clients { trusted; };
    recursion yes;
    additional-from-auth yes;
    additional-from-cache yes;


};

// Create a view for external DNS clients.
view "external-in" in {
    // Our external (untrusted) view. We permit any client to access
    // portions of this view. We do not perform recursion or cache
    // access for hosts using this view.

    match-clients { any; };
    recursion no;
    additional-from-auth no;
    additional-from-cache no;


};

// Create a view for all clients perusing the CHAOS class.
// We allow internal hosts to query our version number.
// This is a good idea from a support point of view.

view "external-chaos" chaos {
    match-clients { any; };
    recursion no;


};

The db.bind zone file

The db.bind zone file is used to track miscreants who attempt to query the CHAOS TXT records version.bind and authors.bind.  You can also use this zone file to change the strings returned by such queries.  Using the "version" directive in the options stanza will block the version.bind query, but it will not log such attempts.

; @(#)db.bind v1.2 25 JAN 2001 Rob Thomas robt@cymru.com
;
$TTL    1D
$ORIGIN bind.
@       1D      CHAOS   SOA     localhost. root.localhost. (
                2001013101      ; serial
                3H              ; refresh
                1H              ; retry
                1W              ; expiry
                1D )            ; minimum
        CHAOS NS        localhost.

version.bind.   CHAOS  TXT "BIND 9.1.3+robhacks"
authors.bind.   CHAOS  TXT "are better coders than I. :)"
 

Once the creation of the named.conf and zone file is completed, it is wise to verify the syntax of these files. This can be accomplished with two tools:

Starting the chroot named daemon

Once the configuration is complete, it is time to start the chroot named daemon.  Without changing /etc/init.d/inetsvc on Solaris, it is wise to test the configurations first.  Remember that we are running our named daemon in a chroot jail.  To start the DNS service, type:

cd /jail/bind
/usr/sbin/chroot /jail/bind usr/local/sbin/named -u named

By typing ps -fu named, you can verify that the chroot named daemon is running.

Once you have /etc/resolv.conf properly configured, you should be able to launch queries.  Test a few basic queries for both internal and external names and addresses.  Then test an intranet client to ensure that the ACLs are functioning properly.  If you have secondary name servers, ensure that zone transfers are functional and complete.  If possible, test the name server from an external host to ensure that the ACLs are functional and that logging is working.

Once all testing is successfully completed, modify /etc/init.d/inetsvc to start the chroot named daemon at boot.  Comment out the current named lines and insert the following:

# Start chroot DNS
if [ -f /jail/bind/usr/local/sbin/named -a -f /jail/bind/usr/local/etc/named.conf ];
then
    echo "Starting chroot BIND server."
    (cd /jail/bind; /usr/sbin/chroot /jail/bind usr/local/sbin/named -u named)
fi

Conclusion

The BIND is a popular application used by many to provide name services.  However, it is not without certain risks.  By implementing a secure configuration, with a separation of internal and external name services, we can increase the security and reliability of our name services and protected networks.
 

       [ Documents ]        [ Home ]

Rob Thomas, robt@cymru.com, http://www.cymru.com