HostedDB - Dedicated UNIX Servers

-->
@(#)Securing BIND v1.0 12 AUG 2000 Rob Thomas robt@cymru.com
Securing BIND 8.X

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.  This article presents a template for de-
ploying a secure BIND configuration, thus mitigating some of the risk of
running the BIND server.

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 8, and 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 with a twist - the two "sides" of DNS are
contained within completely distinct spaces.  The files and address space
are separate, thus providing a great deal of protection against an attack
that targets one side of the DNS topology.

For our purposes, we will assume that our internal network is 7.7.7.0/24,
and that our external network is 8.8.8.0/24.  Our name server has a NIC in
each subnet, with the internal NIC as 7.7.7.1 and the external NIC as
8.8.8.1.  It is often the case that the name server is also the firewall,
so the addressing scheme and dual NIC configuration likely fits many net-
work topologies.

First, 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.

Since there will be two BIND daemons running on the host, distinct UIDs
and directories must be created.  First, create two UIDs and GIDs,
intnamed and extnamed.  The intnamed user and group will be used for our
internal DNS, and the extnamed user and group will be used for our ex-
ternal DNS.  Assign each a unique, non-zero UID and GID.  I recommend
using a shell that will allow no access, such as /bin/false or my own
denial shell, nocando.  The nocando denial shell, which includes de-
tailed logging, can be found at http://www.enteract.com/~robt/Tools.
The home directories for these accounts will be the directories we
create in the next step.

Next, create two directory structures to contain our configuration files.
For example, use /var/named/extnamed and /var/named/intnamed.  In each di-
rectory, create a subdirectory named master for our master zones and slave
for our slave zones, if such zones exist.

Configure the zone files normally, and place them in the proper subdirec-
tories.  Remember to place the internal zone files in /var/named/intnamed,
and the external zone files in /var/named/extnamed.  Each subdirectory
must also have a hint file and a named.conf file.  Don't forget to create
a loopback zone file for each subdirectory!  Details regarding the crea-
tion of the hint and zone files can be found in the August 2000 issue of
Inside Solaris, in the article entitled "Configuring BIND 8," by Don Kuenz.
See also _DNS and BIND_, by Albitz and Liu, published by O'Reilly and
Associates.

We will now configure the two named configuration files, one for internal
DNS and another for external DNS.  Pay close attention to the subtle
differences between them.

External DNS - ext-named.conf

The external DNS configuration file is built to service externally based
queries, recursively answer internally based queries, and to mitigate
many of the attacks commonly found on the Internet.  If an attack does
succeed in breaching or halting the external named daemon, service on the
internal named daemon for queries of internal names and addresses is
largely unaffected.

// @(#)ext-named.conf 12 AUG 2000 Rob Thomas robt@cymru.com
// Set up our ACLs
acl "xfer" {
    none;   // Allow no transfers.  If we have other
            // name servers, place them here.
};

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.
    0.0.0.0/8;
    1.0.0.0/8;
    2.0.0.0/8;
    169.254.0.0/16;
    192.0.2.0/24;
    10.0.0.0/8;
    172.16.0.0/12;
    192.168.0.0/16;
    224.0.0.0/3;
    240.0.0.0/4;
};

// Set options for security
options {
    directory "/var/named/ext-named";
    pid-file "/var/named/ext-named/ext-named.pid";
    statistics-file "/var/named/ext-named/ext-named.stats";
    dump-file "/var/named/ext-named/ext-named.dump";
    query-source address 8.8.8.1;

    listen-on { 8.8.8.1; };
        // Listen on our external interface
        // only.

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

    allow-query {
        // Accept all queries except from the bogons.
        any;
    };

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

// Link in our zones
zone "." in {
    type hint;
    file "db.cache";
};

// Ensure that all attempts to query for BIND.TXT are logged
zone "bind" chaos {
    type master;
    file "master/db.bind";

    allow-query {
        none;
    };

    allow-transfer {
        none;
    };
};

// Allow queries for the 127/8 network, but not zone transfers.
// Every name server, both slave and master, will be a master
// for this zone.
zone "0.0.127.in-addr.arpa" in {
    type master;
    file "master/db.127.0.0";

    allow-transfer {
        none;
    };
};

zone "ournetwork.net" in {
    type master;
    file "master/db.ournetwork";
};

zone "8.8.8.in-addr.arpa" in {
    type master;
    file "master/db.8.8.8";
};

Internal DNS - int-named.conf

The internal DNS configuration file is built to service queries from hosts
on the internal network(s).  It is also built to forward queries for ex-
ternal hosts to the named daemon servicing the external side of the name
server.

// @(#)int-named.conf 12 AUG 2000 Rob Thomas robt@cymru.com
// Set up our ACLs

acl "xfer" {
    none;   // Allow no transfers.  If we have other
            // name servers, place them here.
};

acl "trusted" {
    // Place our internal subnet in here so that intranet
    // clients may send DNS queries.
    7.7.7.0/24;
    localhost;
};

acl "bogon" {
    0.0.0.0/8;
    1.0.0.0/8;
    2.0.0.0/8;
    169.254.0.0/16;
    192.0.2.0/24;
    10.0.0.0/8;
    172.16.0.0/12;
    192.168.0.0/16;
    224.0.0.0/3;
    240.0.0.0/4;
};

options {
    directory "/var/named/int-named";
    pid-file "/var/named/int-named/int-named.pid";
    statistics-file "/var/named/int-named/int-named.stats";
    dump-file "/var/named/int-named/int-named.dump";
    listen-on { 7.7.7.1; };

    forwarders { 8.8.8.1; };
    // Send all queries for external hosts to the external
    // named on this same host.  The external named daemon
    // will recursively seek the answer to the internal
    // query, then return the answer.

    allow-transfer {
        xfer;
    };

    allow-query {
        trusted;
    };

    blackhole {
        bogon;
    };
};

zone "." in {
    type hint;
    file "db.cache";
};

zone "bind" chaos {
    type master;
    file "master/db.bind";

    allow-query {
        none;
    };

    allow-transfer {
        none;
    };
};

zone "0.0.127.in-addr.arpa" in {
    type master;
    file "master/db.127.0.0";

    allow-transfer {
        none;
    };
};

zone "internal.ournetwork.com" in {
    type master;
    file "master/db.internal";
};

zone "7.7.7.in-addr.arpa" in {
    type master;
    file "master/db.7.7.7";
};

Internal DNS - db.cache

The hint file for the external DNS server should be the standard hint file.
The hint file for the internal DNS server, however, should be configured
with only the names and addresses of our external DNS server(s).  An ex-
ample would be:

; @(#)db.cache for internal DNS 12 AUG 2000 Rob Thomas robt@cymru.com
.   99999999    IN  NS  ns1.ournetwork.net.

;
; hotwire the addresses
;

ns1.ournetwork.net.      IN  A   8.8.8.1

The bind zone file

A common trick of the malicious is to query the name server for the ver-
sion of BIND code it is running.  This allows the attacker to quickly
select a version-specific vulnerability.  To hide the version number,
one could insert the version directive in the options section.  However,
this does not provide any logging of the attempt.  Instead, we create a
bind zone file, link it into both our external and internal configuration,
and now receive notification of any attempts to query for version.bind.

; @(#)db.bind 12 AUG 2000 Rob Thomas robt@cymru.com
$TTL    1D
$ORIGIN bind.
@   CHAOS   SOA localhost. root.localhost. (
        2000081201  ; serial
        3H      ; refresh
        1H      ; retry
        1W      ; expiry
        1D )        ; minimum
    CHAOS NS    localhost.

If anyone attempts to obtain the version number, the logs will report the
following:

Aug 12 18:28:42 ns1 named[17809]: unapproved query from [X.X.X.X].33112 for
"version.bind"

Add this bit of text to your alert mechanism!

Starting the two named daemons

Once the configuration is complete, it is time to launch the two named
daemons.  Without changing /etc/init.d/inetsvc, it is wise to test the
configurations first.  To start the external DNS service, type:

/usr/local/sbin/named -u extnamed -c /var/named/extnamed/ext-named.conf

By typing the ps -fu extnamed command, you can verify that our external
named daemon is running.  To start our internal DNS service, type:

/usr/local/sbin/named -u intnamed -c /var/named/intnamed/int-named.conf

Again, typing ps -fu extnamed will verify that our internal name service
is up and running.

Once you have /etc/resolv.conf properly configured (use the internal
address for the nameserver line), 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 forwarding
is properly working.  If you have secondary name servers, ensure that
zone transfers are functional and complete.

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

# Start external DNS
if [ -f /usr/local/sbin/named -a -f /var/named/extnamed/ext-named.conf ]; 
then
    echo "Starting external BIND server."
    /usr/local/sbin/named -u extnamed -c /var/named/extnamed/ext-named.conf
fi

# Start internal DNS
if [ -f /usr/local/sbin/named -a -f /var/named/intnamed/int-named.conf ];
then
    echo "Starting internal BIND server."
    /usr/local/sbin/named -u intnamed -c /var/named/intnamed/int-named.conf
fi

Conclusion

The BIND is a necessary application on almost all networks.  However, it
is not without certain risks.  By implementing a secure configuration and
a separation of internal and external name services, we can increase the
security and reliability of our name services and protected networks.

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