Hardening the BIND DNS Server - Page 4

By Sean Boran | Posted Dec 5, 2000
Page 4 of 5   |  Back to Page 1
Print ArticleEmail Article
  • Share on Facebook
  • Share on Twitter
  • Share on LinkedIn



Configuration Notes


Note 1: BIND's Built-in chroot

BIND 8 had its own chroot function, which works by giving named an option "-t" which points to the chroot jail, for example "named -t /home/dns." When BIND starts up, it chroot's to the jail, after processing command line options and before it starts to answer queries. By compiling BIND and installing directly into the jail, all the bind programs will be correctly in place. Since BIND chroot's after reading user/group information, it doesn't need the other /etc and /usr/lib files noted above.

If BIND is set up as described above, it can still be started using this method, for example,
/home/dns/usr/local/sbin/named -t /home/dns -u named

This method is simpler than the general chroot method below, but it does have the disadvantage that we rely on the BIND code to be executed before the chroot is bug-free. Also, a general chroot can be used to "jail" other programs too.
For the moment, I'll continue using the general chroot method described below, and update this article as problems are found/solved. See also the Known Problems section.


Note 2: The BIND Configuration File

The following is an example named.conf with many comments to explain individual features. The file consists of an options section, ACL and server definitions, and Zone data.

acl "trusted-nameservers" {
  localhost;
  193.A.B.C; // my secondary
  193.A.B.D; // another secondary
  X.A.A.A;   // ISP
  X.Y.Z.X;   // NIC for your country                                                     
};

options {         
  directory "/var/named";                       /* /etc/named is also common */
  //forward only;
  // for Internal DNS servers, forward all unknown queries to external servers:
  //forwarders { 193.a.b.c; 193.a.b.d; };
  /* If there is a firewall between you and nameservers you want
   * to talk to, you might need to uncomment the query-source
   * directive below.  Previous versions of BIND always asked
   * questions using port 53, but BIND 8.1 uses an unprivileged
   * port by default.
   */
  query-source address * port 53;
  pid-file "/var/run/named.pid";
  check-names master warn;                  /* default. */
  datasize 20M;
  // The following will restrict transfers for all zones, if enabled:
  // allow-transfer { trusted-nameservers; };
  recursion yes;          // default

  //allow-query { 193.a.b.c/24; };
};

logging {
  channel syslog_errors {
    //syslog daemon;
    syslog local1;           // choose local1 since rarely used
    severity info;
  };
  category default {                                                                                 
    syslog_errors;            // you can log to as many channels
    //default_syslog;          // by default goes to daemon in syslog
  };
  // ignore all "lame server" errors (only do this if none of the lame 
  // servers belong to you; otherwise, fix them)
  category lame-servers{ null; }; 
};

// Example definition of a Primary
zone "mytestdomain.com" {
  type master;
  file "mytestdomain.com";
  allow-query    { any; };      // no restriction on queries
  allow-update   { none; };    // don't allow dynamic updates
  allow-transfer { trusted-nameservers; }; // restrict zone transfers
};

// Example definition of a secondary
zone "mytestdomain2.com" {
  type slave;
  file "mytestdomain2.com";
  masters          { A.B.C-D };  // IP address of the primary
  allow-query    { any; };
  allow-update   { none; };
  allow-transfer { trusted-nameservers; };
};

// if you get servers giving bad data, ignore them with:
//server 10.0.0.2 { bogus yes; };

// this is the main file for the domain name server. Each line gives
// the file where is stored the name table for a particular domain.
// named.root can be downloaded from ftp.rs.internic.net/domain 

zone "." {
  type hint;
  file "named.root";
};

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


Note 3: TSIG, Transaction Signatures

BIND provides some new security features in its latest release. Here we examine one: the use of TSIG (transaction signatures) to authenticate zone transfers.

Zone transfers are usually limited to a list of IP addresses (via the ACL mechanism) which correspond to specific DNS servers for a zone. Since only IP addresses are used, this mechanism is open to IP spoofing. BIND 8.2 and later allow authentication and verification of zone data. A key is configured on primary and secondary name servers and used to sign messages exchanged between the servers. It's important that the server times are synchronized. If the transfer is not authenticated with the correct key, no zone transfer may take place.

Let's look at an example where we use TSIG to restrict the zone transfers between a DNS primary "prim" (IP address 10.1.1.2) and DNS slave secondary "sec1" (IP address 10.1.2.2).

a) Generate an MD5 key, which will be used as a shared secret between the DNS servers. The "dnskeygen" tool is used. The key is written to a file.

# /usr/local/sbin/dnskeygen -H 128 -h -n prim-sec1.
Generating 128 bit HMAC-MD5 Key for prim-sec1.
Generated 128 bit Key for prim-sec1. id=0 alg=157 flags=513

# cat Kprim-sec1.+157+00000.private
Private-key-format: v1.2
Algorithm: 157 (HMAC)
Key: bFs2bXnLTYTI7r0WJv7HMA==

b) Create an identical key entry on both servers in named.conf:

key prim-sec1 {
	algorithm hmac-md5;
	secret "bFs2bXnLTYTI7r0WJv7HMA==";
};

c) Add an ACL on both servers to limit transfers to specific hosts, for example:

acl "my-nameservers" {
	localhost;
	10.1.1.2;
	10.1.2.2;
};

d) For each host in the ACL, tell the BIND which key to use (do this for each server), for example on the primary:

server 10.1.2.2 {
  transfer-format many-answers;
  keys { prim-sec1 ; };
};
zone "mytestdomain.com" {
  type master;
  file "mytestdomain.hosts";
  allow-query    { any; };
  allow-update   { none; };
  allow-transfer { my-nameservers; };
}

e) Restart both named servers (send a HUP signal), then check the (syslog) logs for errors.

Testing if it works:

  • On the secondary, stop named, delete one of the zone files and restart. Watch the logs. A message indicating a successful zone transfer should appear and the corresponding zone file be created.

  • To make sure the TSIG key is really being used, change the key on the primary (e.g. add the letters "TEST" as the first few letters), stop both name servers, delete the zone file on the secondary, and restart both. The zone transfer will not take place, an error message like
    "named-xfer[16280]: [ID 745729 daemon.notice] SOA TSIG verification from server [10.1.1.2], zone mytestdomain.com: BADKEY (-17)"
    appears in the log, and the zone file is not recreated. Changing back the key on the primary and restarting BIND on primary and secondary fixes our deliberate fault.

So it's really not so difficult to significantly increase the security of your zone transfers. It is important that the file permissions on named.conf be restrictive so that it cannot be read by everyone on a system. The secret string used in the key must remain secret.

Comment and Contribute
(Maximum characters: 1200). You have
characters left.
Get the Latest Scoop with Enterprise Networking Planet Newsletter