DNS & DHCP Setup

Introduction

This document describes how DNS and DHCP work on the Arda Network. I’ve managed to use many of the features of DNS and DHCP in my setup so this document should provide a fairly comprehensive guide as to how to get things working. Features you’ll find described here include:

  • Dynamic updates between DHCP and DNS
  • Automatic zone updates between master and slave name servers
  • Control of DNS using rndc
  • Secure DNS operations using TSIG
  • Access control lists
  • Views
  • CIDR networks

This document does not presume to be a tutorial on how DNS or DHCP work. It does not even presume to teach how to use the particular software described. This document provides an example of a working DNS/DHCP setup. If you are new to DNS or DHCP, you will almost certainly need to reference additional resources to understand what will be presented here. Don’t panic, since DNS and DHCP are fundamental to the operation of IP networks, such resources are easy to come by.

Preliminaries

I chose to use the Internet Systems Consortium’s (ISC) implementations of DNS and DHCP for the Arda Network. Why you ask? Because they are both in wide use so I thought I would be able to find a lot of resources to assist me in setting up the software. It turned out that I was correct in this assumption. In particular, I relied on an excellent book from O’Reilly Press called ‘DNS and BIND’. This book provides much useful information; I highly recommend it.

The particular versions of software I use are:

  • BIND 9.3.2 and 9.3.1
  • DHCP 3.0.4

Knowing the software versions is especially important. For BIND, configuration syntax has changed dramatically between versions so what you see described here can be reliably applied only to BIND 9.

In the DHCP configuration file, the option used to invoke dynamic updates with a DNS server is also sensitive to the particular version of DHCP you are using.

You will find an overview, including a very nice diagram, of the Arda Network here.

Why have I gone to the trouble to set up DNS and DHCP on my network you ask? Well, the simplest answer is because I wanted to. The more involved answer is in two parts. I find updating host files tedious and having DNS allows me to update two zone files on the master DNS server whenever something changes on my network. I also sometimes bring home a laptop from work and I wanted to be able to plug it into my home network to do things like transfer files to and from it. Since it uses DHCP at work, I thought I’d set things up that way at home too. I expect there are a lot of simpler ways to accomplish what I wanted but I don’t imagine they would be as interesting as the way I’ve done things.

One thing to keep in mind when reading this document is that DNS on the Arda Network is set up to serve machines on my local network only. I have not set up DNS to serve zone data to the outside world and, in fact, I have options in my DNS configuration files specifically to prevent the outside world from reading my zone data. If you want to serve zone data from your domain to the internet at large, you’ll have to do some things differently than what I describe here. If all you want to do is create a DNS cache (a server that caches the results of DNS queries but does not serve zone data), have a look at the DNS cache I’ve set up on Thebe using djbdns.

DNS

DNS on the Arda Network is handled by two machines, Europa and Io, that act as a master/slave pair. These two machines use automated zone transfers, secured using TSIG keys, to stay in sync. The master DNS server is also dynamically updated by the DHCP server. Dynamic updates are also secured using TSIG.

On both Europa and Io, all TSIG keys were generated using this command.

    dnssec-keygen -a HMAC-MD5 -b 256 -n HOST <key name>

Keys were cut and pasted into configuration files as appropriate. In the configuration files listed below, when two keys in different files are referred to by the same name, it is because the same key is used in both files.

Two domains are described in my DNS setup, arda.homeunix.net and arda.homelinux.net. The first domain is your typical internet domain. All the machines on my home network are part of this domain. The second domain is a so-called virtual domain. It is used by Callisto, my mail server, so that I can route email addressed to this domain. No actual machines belong to the arda.homelinux.net domain. Although I include only one virtual domain in this document, I am not limited to one. I could have as many virtual domains set up as I want simply by adding the appropriate zone files and updating the named.conf files of my DNS servers.

Master DNS Server

Configuration Files

Because I’m using TSIG to secure such things as zone transfers and rndc, getting the permissions on the various configuration files right is very important. Here are the ownership and permissions of the various configuration files on Europa. Take note of the ownership and permissions of the rndc related files. They are set up this way so that named can read these files but only a process with root privileges can change them.

File Name Owner Permissions
/etc/namedb/etc/named.conf root:root 644
/etc/namedb/etc/rndc.key root:named 640
/etc/rndc.conf root:root 600
/etc/resolv.conf root:root 644

Here is my named.conf file.

// named.conf

// secret must be the same as in /etc/rndc.conf
include "/etc/rndc.key";

acl "internal-net" { 192.168.10/27; 127.0.0.1; };
acl "colonies" { 10.10.0.1; };

controls {
    inet 127.0.0.1 allow { any; } keys { "rndc-key"; };
};

logging {
    channel "named_log" {
        // send most BIND logs to a dedicated log file
        file "/var/log/named.log" versions 10 size 500k;
        severity dynamic;
        print-category yes;
        print-severity yes;
        print-time yes;
    };

    channel "query_log" {
        // query logs go to a separate file
        file "/var/log/query.log" versions 10 size 500k;
        severity debug;
        print-severity yes;
        print-time yes;
    };

    category default { named_log; };
    category queries { query_log; };
};

options {
    directory "/";
    pid-file "var/run/named.pid";
    statistics-file "master/named.stats";
    dump-file "master/named.dump";
    listen-on { "internal-net"; };
    allow-query { "internal-net"; "colonies"; };
    allow-transfer { none; };
    notify no;

    forwarders { <ISP DNS server 1>; <ISP DNS server 2>; };

    /*
     * 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;
};

view "standard-in" in {

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

    zone "arda.homeunix.net" {
        type master;
        file "master/arda.homeunix.net.zone";
        allow-transfer { key "europa-io"; };
        //allow-update { key "europa-dhcp"; };
        update-policy { grant europa-dhcp subdomain arda.homeunix.net. A TXT; };
        notify yes;
    };

    zone "arda.homelinux.net" {
        type master;
        file "master/arda.homelinux.net.zone";
        allow-transfer { key "europa-io"; };
        notify yes;
    };

    zone "10.168.192.in-addr.arpa" {
        type master;
        file "master/10.168.192.in-addr.arpa";
        allow-transfer { key "europa-io"; };
        //allow-update { key "europa-dhcp"; };
        update-policy { grant europa-dhcp subdomain 10.168.192.in-addr.arpa. PTR TXT; };
        notify yes;
    };

    zone "0.10.10.in-addr.arpa" {
        type master;
        file "master/0.10.10.in-addr.arpa";
        allow-transfer { key "europa-io"; };
        notify yes;
    };

    zone "localhost" {
        type master;
        file "master/localhost.zone";
    };

    zone "0.0.127.in-addr.arpa" {
        type master;
        file "master/localhost.rev";
    };

    zone "0.in-addr.arpa" {
        type master;
        file "master/named.network";
    };

    zone "255.in-addr.arpa" {
        type master;
        file "master/named.broadcast";
    };
};

view "ultimate-chaos" chaos {

    recursion no;

    zone "." {
        type hint;
        file "/dev/null";
    };

    zone "bind" {
        type master;
        file "master/named.bind";
    };
};

Some things to note concerning my named.conf file include the following points.

  • I use an include statement to inline my TSIG keys which are kept in a separate file, rndc.key. The reason for this is that the TSIG keys are only of value if nobody can gain access to them. The rndc.key file has more restrictive permissions than the named.conf file.
  • I have two access control lists (ACLs) defined; ‘internal-net’ and ‘colonies’. I use these ACLs to restrict who can query my name server. In my case, I allow queries only from machines on my home network. The ‘colonies’ ACL takes care of Thebe, which is connected to my home network through a VPN tunnel.
  • The controls clause determines from where rndc can be used to control BIND. I have BIND accepting rndc commands from the loopback address only.
  • I use a logging clause to define two log channels. One channel essentially replaces logging to syslog. I thought having BIND send logs to a separate file would make it more convenient for me to find important log messages. Defining a log channel explicitly also provides a lot of control over what gets logged. For example, setting the severity level to dynamic allows me to determine how much debugging information I want to log by sending trace and notrace commands to rndc. The second channel is for logging the queries BIND handles. Queries are logged only if you turn query logging on using rndc. My DNS server is not very busy so I can afford to leave query logging on all the time. On a heavily loaded DNS server, you probably want to turn query logging on only when troubleshooting a problem. A busy name server can produce piles of query logs in a very short timespan.
  • The arda.homelinux.net zone references a virtual domain used exclusively with my mail server; no real hosts are part of this domain. This entry is what allows me to route mail for the arda.homelinux.net domain. Every virtual domain used by my mail server needs to have a similar zone entry in the named.conf file.
  • The 0.10.10.in-addr.arpa zone is there to service reverse lookups of Thebe’s address. Forward lookups are handled by an entry in the arda.homeunix.net zone. It looks a little strange to have a 10.10.0.0 IP in the same zone with other machines belonging to 192.168.10.0 but it’s a simple solution that works with my particular VPN setup. A full explanation will have to wait until I get around to writing a document describing how VPN works on The Arda Network.
  • I have notify set to no in the options section. This setting is then overridden in the arda.homeunix.net, arda.homelinux.net, 10.168.192.in-addr.arpa, and 0.10.10.in-addr.arpa zones. I noticed that without these notify parameters, notify messages would be generated for all zones whenever BIND was restarted. Since the four zones listed are the only ones that will ever change, and thus be subject to zone transfers, I decided to eliminate the unnecessary notify messages. The root zone may change from time to time, but the notify option is not allowed in the root zone.
  • The allow-transfer option in the options section sets BIND’s default behaviour to refuse all zone transfers. Without setting this option, anyone can transfer any zone. This option is then overridden in the arda.homeunix.net, arda.homelinux.net, 10.168.192.in-addr.arpa,and 0.10.10.in-addr.arpa zones. The allow-transfer option in these zones tell BIND that zone transfers will only be allowed if the requester uses the specified TSIG key.
  • The forwarders option tells BIND to not use iterative queries itself for information it doesn’t already know about but to forward a recursive query to the name servers specified instead. In my case, I have my server pointing to my ISP’s name servers. This allows me to make use of the caches on these name servers, which are almost certainly more extensive than those on my own name servers. It should be noted that my setup will work perfectly fine without using the forwarders option. Whether you should use forwarders depends on many things including your network topology, the type of internet connection available, and the volume and types of queries you will be generating.
  • I’ve set up my BIND server to use views. One common use of views is to allow your name server to answer queries from your internal network differently than those from the internet at large. In my case, I’m using views to have more control over how version information is served by BIND through the named.bind zone.
  • The allow-update and update-policy options in the arda.homeunix and 10.168.192.in-addr.arpa zones indicate that they can be updated by DHCP. I was initially using the allow-update option until I succeeded in finding the proper syntax for the update-policy option. Both options can use a TSIG key to restrict who can perform updates but update-policy allows more control over what kinds of updates DHCP can perform on a zone.
  • The localhost zone is often incorporated into another zone; in my case this would be the arda.homeunix.net zone. RFC1912 recommends that the localhost zone be identified separately and I’ve adopted that scheme here. See the RFC for the reason behind this arrangement.
  • The 0.in-addr.arpa and 255.in-addr.arpa zones are generic zones that allow BIND to deal with erroneous reverse lookups of the addresses 0.0.0.0 and 255.255.255.255 so that these queries are not sent off to a root name server. These zones are also recommended in RFC1912.
  • The bind zone is different from the rest. It’s presence allows me to control the version information reported by BIND. The ‘version’ option will also do this but setting up this zone provides for hiding version information from some clients using access control lists. It also allows for logging of such requests, something that isn’t possible when using the version option. BIND complaines if there is no hint zone in this view but it still seems to work. You can retrieve the information in the bind zone with these queries:
        dig version.bind txt chaos
      dig authors.bind txt chaos

Here is my rndc.conf file.

/*
 * Copyright (C) 2000, 2001  Internet Software Consortium.
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
 * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

/* $Id: rndc.conf,v 1.7 2001/01/09 21:40:45 bwelling Exp $ */

options {
        default-server  localhost;
        default-key     "rndc-key";
};

server localhost {
        key     "rndc-key";
};

key "rndc-key" {
        algorithm       hmac-md5;
        secret
        "<rndc-key>";
};

And here is my rndc.key file.

key "rndc-key" {
        algorithm       hmac-md5;
        secret
        "<rndc-key>";
};

key "europa-dhcp" {
        algorithm       hmac-md5;
        secret
        "<europa-dhcp key>";
};

key "europa-io" {
        algorithm       hmac-md5;
        secret
        "<europa-io key>";
};

My /etc/resolv.conf file looks like this.

domain arda.homeunix.net
nameserver localhost
nameserver 192.168.10.5

Zone Files

The nine zone files are located in /etc/namedb/master. The section describing running BIND in a chroot jail shows a listing of the directory.

There are two *.jnl files in the /etc/namedb/master directory. They are produced when dhcpd updates my zone files.

Here are what my zone files look like.

Zone File Contents
arda.homeunix.net.zone
$ORIGIN .
$TTL 86400      ; 1 day
arda.homeunix.net       IN SOA  europa.arda.homeunix.net. postmaster.arda.homeunix.net. (
                                20060705   ; serial
                                21600      ; refresh (6 hours)
                                3600       ; retry (1 hour)
                                604800     ; expire (1 week)
                                21600      ; minimum (6 hours)
                                )
                        NS      io.arda.homeunix.net.
                        NS      europa.arda.homeunix.net.
                        MX      10 callisto.arda.homeunix.net.
$ORIGIN arda.homeunix.net.
metis                   A       192.168.10.1
thebe                   A       10.10.0.1
io                      A       192.168.10.5
europa                  A       192.168.10.9
callisto                A       192.168.10.6
$TTL 14400      ; 4 hours
ganymede                A       192.168.10.28
                        TXT     "311cc5d6b2b528cc61e23c831e840a6bf4"
$TTL 86400      ; 1 day
mail                    CNAME   callisto
www                     CNAME   io
arda.homelinux.net.zone
$ORIGIN .
$TTL 86400      ; 1 day
arda.homelinux.net      IN SOA  europa.arda.homeunix.net. postmaster.arda.homeunix.net. (
                                20070706   ; serial
                                21600      ; refresh (6 hours)
                                3600       ; retry (1 hour)
                                604800     ; expire (1 week)
                                86400      ; minimum (1 day)
                                )
                        NS      io.arda.homeunix.net.
                        NS      europa.arda.homeunix.net.
                        MX      10 callisto.arda.homeunix.net.
10.168.192.in-addr.arpa
$ORIGIN .
$TTL 86400      ; 1 day
10.168.192.in-addr.arpa IN SOA  europa.arda.homeunix.net. postmaster.arda.homeunix.net. (
                                20060705   ; serial
                                21600      ; refresh (6 hours)
                                3600       ; retry (1 hour)
                                604800     ; expire (1 week)
                                21600      ; minimum (6 hours)
                                )
                        NS      io.arda.homeunix.net.
                        NS      europa.arda.homeunix.net.
$ORIGIN 10.168.192.in-addr.arpa.
1                       PTR     metis.arda.homeunix.net.
$TTL 14400      ; 4 hours
28                      PTR     ganymede.arda.homeunix.net.
$TTL 86400      ; 1 day
5                       PTR     io.arda.homeunix.net.
6                       PTR     callisto.arda.homeunix.net.
9                       PTR     europa.arda.homeunix.net.
0.10.10.in-addr.arpa
$ORIGIN .
$TTL 86400      ; 1 day
0.10.10.in-addr.arpa    IN SOA  europa.arda.homeunix.net. postmaster.arda.homeunix.net. (
                                20070705   ; serial
                                21600      ; refresh (6 hours)
                                3600       ; retry (1 hour)
                                604800     ; expire (1 week)
                                86400      ; minimum (1 day)
                                )
                        NS      io.arda.homeunix.net.
                        NS      europa.arda.homeunix.net.
$ORIGIN 0.10.10.in-addr.arpa.
1                       PTR     thebe.arda.homeunix.net.
localhost.zone
$TTL 1w
@        IN SOA europa.arda.homeunix.net. postmaster.arda.homeunix.net. (
                                        1       ; Serial
                                        6h      ; Refresh after 6 hours
                                        1h      ; Retry after 1 hour
                                        1w      ; Expire after 1 week
                                        1d )    ; Negative caching TTL of 1 day

                        IN      NS      europa.arda.homeunix.net.
                        IN      NS      io.arda.homeunix.net.

localhost.              IN      A       127.0.0.1
localhost.rev
$TTL 1w
@        IN SOA europa.arda.homeunix.net. postmaster.arda.homeunix.net. (
                                        1       ; Serial
                                        6h      ; Refresh after 6 hours
                                        1h      ; Retry after 1 hour
                                        1w      ; Expire after 1 week
                                        1d )    ; Negative caching TTL of 1 day

                        IN      NS      europa.arda.homeunix.net.
                        IN      NS      io.arda.homeunix.net.

1                       IN      PTR     localhost.
named.broadcast
named.network
$TTL 1w
@       IN SOA europa.arda.homeunix.net. postmaster.arda.homeunix.net. (
                                        1       ; Serial
                                        6h      ; Refresh after 6 hours
                                        1h      ; Retry after 1 hour
                                        1w      ; Expire after 1 week
                                        1d )    ; Negative caching TTL of 1 day

                IN      NS      europa.arda.homeunix.net.
                IN      NS      io.arda.homeunix.net.
named.bind
$TTL 1d
$ORIGIN bind.
@       CHAOS SOA europa.arda.homeunix.net. postmaster.arda.homeunix.net. (
                                        1       ; Serial
                                        6h      ; Refresh after 6 hours
                                        1h      ; Retry after 1 hour
                                        1w      ; Expire after 1 week
                                        1d )    ; Negative caching TTL of 1 day

                CHAOS   NS      localhost.

version.bind.   CHAOS   TXT     "BIND 9.3.2"
authors.bind.   CHAOS   TXT     "Are at home at the ISC."
named.root
; <<>> DiG 9.3.2 <<>> @a.root-servers.net . ns
; (1 server found)
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63591
;; flags: qr aa rd; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 13

;; QUESTION SECTION:
;.                              IN      NS

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

;; ADDITIONAL SECTION:
C.ROOT-SERVERS.NET.     3600000 IN      A       192.33.4.12
G.ROOT-SERVERS.NET.     3600000 IN      A       192.112.36.4
F.ROOT-SERVERS.NET.     3600000 IN      A       192.5.5.241
B.ROOT-SERVERS.NET.     3600000 IN      A       192.228.79.201
J.ROOT-SERVERS.NET.     3600000 IN      A       192.58.128.30
K.ROOT-SERVERS.NET.     3600000 IN      A       193.0.14.129
L.ROOT-SERVERS.NET.     3600000 IN      A       198.32.64.12
M.ROOT-SERVERS.NET.     3600000 IN      A       202.12.27.33
I.ROOT-SERVERS.NET.     3600000 IN      A       192.36.148.17
E.ROOT-SERVERS.NET.     3600000 IN      A       192.203.230.10
D.ROOT-SERVERS.NET.     3600000 IN      A       128.8.10.90
A.ROOT-SERVERS.NET.     3600000 IN      A       198.41.0.4
H.ROOT-SERVERS.NET.     3600000 IN      A       128.63.2.53

;; Query time: 99 msec
;; SERVER: 198.41.0.4#53(198.41.0.4)
;; WHEN: Thu Jul  6 08:00:26 2006
;; MSG SIZE  rcvd: 436

In the arda.homeunix.net.zone and 10.168.192.in-addr.arpa files, resource records for the host Ganymede were inserted by DHCP. Otherwise these files plus all other zone files were created by hand with one exception.

The named.root file was not created by hand but is instead the output of this dig query.

    dig @a.root-servers.net . ns > named.root

This command can be re-run periodically to ensure the list of root name servers is up to date. Root name servers don’t change very often so updating this file more than twice a year is probably overkill. Frequent updates also put undo load on the root name servers; they have enough to do as it is.

The arda.homelinux.net.zone file contains no A records. Its sole purpose is to identify the mail server, via the MX record, that mail addressed to the arda.homelinux.net domain should be sent to.

Manually Updating Zone Files

There are times when I’ve needed to manually update a zone file. Since Europa is the master name server, I always make the change on this machine and allow the normal zone transfer process to propogate the change to Io. Of course, because I have a slave name server and because I’m doing dynamic updates with DHCP, the process of making a change takes a few steps.

  1. Use rndc to stop BIND.
  2. Remove any .jnl files from the zone file directory.
  3. Edit the zone files as necessary. Make sure to increment the serial number of any file edited.
  4. Start BIND using its startup script.

If you need to edit zone files that are not subject to dynamic updates, then you don’t need to stop BIND. Edit the zone files remembering to increment their serial number and issue a reload command from rndc, simple as that. So long as you make your changes on a master name server, the reload command will take care of initiating any zone transfers that need to happen.

Running BIND Chrooted

On Europa, not only do I run BIND with reduced privileges, but it also runs in a chroot jail. Here is how I did it.

  1. The first thing to do was to decide where to put everything. I decided to create the directory /etc/namedb which would become BIND’s root.
  2. I needed to add a number of directories and files to namedb. Here is what things looked like after I was done.
    drwxr-xr-x    6 root     root         4096 Jan 19 20:13 /etc/namedb/
    drwxr-xr-x    2 root     root         4096 Jan 19 20:21 /etc/namedb/dev/
    crw-rw-rw-    1 root     root       1,   3 Jan 19 20:00 /etc/namedb/dev/null
    crw-r--r--    1 root     root       1,   8 Jan 19 20:21 /etc/namedb/dev/random
    drwxr-xr-x    2 root     root         4096 Jan 19 19:59 /etc/namedb/etc/
    -rw-r--r--    1 root     root         1267 Jan 19 19:54 /etc/namedb/etc/localtime
    -rw-r--r--    1 root     root         1592 Jul  5 16:38 /etc/namedb/etc/named.conf
    -rw-r-----    1 root     named         344 Jan 19 19:55 /etc/namedb/etc/rndc.key
    drwxr-xr-x    2 named    named        4096 Jan 19 19:56 /etc/namedb/master/
    -rw-r--r--    1 root     root          412 Jul  5 17:00 /etc/namedb/master/0.10.10.in-addr.arpa
    -rw-r--r--    1 named    named         803 Jul  5 16:56 /etc/namedb/master/10.168.192.in-addr.arpa
    -rw-r--r--    1 named    named        1460 Jul  5 16:56 /etc/namedb/master/10.168.192.in-addr.arpa.jnl
    -rw-r--r--    1 root     root          781 Jul  5 17:35 /etc/namedb/master/arda.homelinux.net.zone
    -rw-r--r--    1 named    named         797 Jul  5 16:57 /etc/namedb/master/arda.homeunix.net.zone
    -rw-r--r--    1 named    named        1460 Jul  5 16:57 /etc/namedb/master/arda.homeunix.net.zone.jnl
    -rw-r--r--    1 root     root          620 Jul  5 16:46 /etc/namedb/master/localhost.rev
    -rw-r--r--    1 root     root          619 Jul  5 16:46 /etc/namedb/master/localhost.zone
    -rw-r--r--    1 root     root          592 Jul  5 16:47 /etc/namedb/master/named.bind
    -rw-r--r--    1 root     root          551 Jul  5 16:48 /etc/namedb/master/named.broadcast
    -rw-r--r--    1 root     root          551 Jul  5 16:48 /etc/namedb/master/named.network
    -rw-r--r--    1 root     root         1516 Jul  6 08:00 /etc/namedb/master/named.root
    drwxr-xr-x    3 root     root         4096 Jan 19 20:14 /etc/namedb/var/
    drwxr-xr-x    2 named    named        4096 Jan 19 20:24 /etc/namedb/var/run/

     

    • The var/run directory is where BIND’s pid file will go.
    • Create the dev/null special file using the command ‘mknod /etc/namedb/dev/null c 1 3′.
    • Create the dev/random special file using the command ‘mknod /etc/namedb/dev/random c 1 8′.
    • When creating the special files with mknod, it’s a good idea to check the corresponding files in the /dev directory to make sure the major and minor numbers are correct. You want to use whatever the files in the /dev directory use.
    • The etc/localtime file is copied from /etc. This file ensures BIND uses the correct timezone in its log messages.
    • The arda.homeunix.net.zone and 10.168.192.in-addr.arpa zone files must be writable by the user named because they are dynamically updated by dhcpd. The two *.jnl files are owned by named when they are created by dhcpd.

     

  3. Before I started using log channels in named.conf, I needed to give BIND a way to send messages to syslog from within the chroot jail. To accomplish this, I modified one line in the file /etc/sysconfig/syslog.
        SYSLOGD_OPTIONS=”-m 0″
            became
      SYSLOGD_OPTIONS=”-m 0 -a /etc/namedb/dev/log”

    Stopping and starting syslog will cause a new syslog socket to appear in the /etc/namedb/dev directory. Since I use log channels now, I don’t do this step anymore.

  4. The last thing to do is modify BIND’s startup parameters to tell it to run in the jail. I did this by adding the following line to the /etc/sysconfig/named file.
      ROOTDIR=”/etc/namedb”

Startup Scripts

I run BIND under the user and group ‘named’. Here is what my /etc/rc.d/init.d/named startup script looks like. I needed to modify it so that it would look for binaries in /usr/local/sbin instead of /usr/sbin and to look for rndc.conf in /etc and not in the chroot jail.

#!/bin/bash
#
# named           This shell script takes care of starting and stopping
#                 named (BIND DNS server).
#
# chkconfig: 345 55 45
# description: named (BIND) is a Domain Name Server (DNS) \
# that is used to resolve host names to IP addresses.
# probe: true

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ "${NETWORKING}" = "no" ] && exit 0

[ -f /etc/sysconfig/named ] && . /etc/sysconfig/named

[ -f /usr/local/sbin/named ] || exit 0

[ -f ${ROOTDIR}/etc/named.conf ] || exit 0

RETVAL=0
prog="named"

start() {
        # Start daemons.
        gprintf "Starting %s: " $prog
        if [ -n "${ROOTDIR}" -a "x${ROOTDIR}" != "x/" ]; then
                OPTIONS="${OPTIONS} -t ${ROOTDIR}"
        fi
        daemon /usr/local/sbin/named -u named ${OPTIONS}
        RETVAL=$?
        [ $RETVAL -eq 0 ] && touch /var/lock/subsys/named
        echo
        return $RETVAL
}
stop() {
        # Stop daemons.
        gprintf "Stopping %s: " $prog
        killproc named
        RETVAL=$?
        [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/named
        echo
        return $RETVAL
}
rhstatus() {
        #/usr/sbin/rndc -c ${ROOTDIR}/etc/rndc.conf status
        /usr/local/sbin/rndc -c /etc/rndc.conf status
        return $?
}
restart() {
        stop
        start
}
reload() {
        #/usr/sbin/rndc -c ${ROOTDIR}/etc/rndc.conf reload >/dev/null 2>&1 || /usr/bin/killall -HUP named
        /usr/local/sbin/rndc -c /etc/rndc.conf reload >/dev/null 2>&1 || /usr/bin/killall -HUP named
        return $?
}
probe() {
        # named knows how to reload intelligently; we don't want linuxconf
        # to offer to restart every time
        #/usr/sbin/rndc -c ${ROOTDIR}/etc/rndc.conf reload >/dev/null 2>&1 || echo start
        /usr/local/sbin/rndc -c /etc/rndc.conf reload >/dev/null 2>&1 || echo start
        return $?
}

# See how we were called.
case "$1" in
        start)
                start
                ;;
        stop)
                stop
                ;;
        status)
                rhstatus
                ;;
        restart)
                restart
                ;;
        condrestart)
                [ -f /var/lock/subsys/named ] && restart
                ;;
        reload)
                reload
                ;;
        probe)
                probe
                ;;
        *)
                gprintf "Usage: %s {start|stop|status|restart|condrestart|reload|probe}\n" $0
                exit 1
esac

exit $?

Slave DNS Server

DNS configuration on Io follows closely that for Europa. The biggest differences come from the fact that Io is a slave name server and BIND on Europa must accommodate dynamic updates while it doesn’t on Io.

Configuration Files

Here are the ownership and permissions of the various configuration files.

File Name Owner Permissions
/var/named/etc/namedb/named.conf root:wheel 644
/var/named/etc/namedb/rndc.key root:bind 640
/var/named/etc/namedb/rndc.conf root:wheel 600
/etc/resolv.conf root:wheel 644

Here is my named.conf file.

// Refer to the named.conf(5) and named(8) man pages for details.  If
// you are ever going to setup a primary server, make sure you've
// understood the hairy details of how DNS is working.  Even with
// simple mistakes, you can break connectivity for affected parties,
// or cause huge amount of useless Internet traffic.

include "/etc/namedb/rndc.key";

acl "internal-net" { 192.168.10/27; 127.0.0.1; };
acl "colonies" { 10.10.0.1; };

controls {
        inet 127.0.0.1 allow { any; } keys { "rndc-key"; };
};

//key to use for zone transfers
server 192.168.10.9 {
        keys { "europa-io"; };
};

logging {
    channel "named_log" {
        // send most BIND logs a dedicated log file
        file "/var/log/named.log" versions 10 size 500k;
        severity dynamic;
        print-category yes;
        print-severity yes;
        print-time yes;
    };

    channel "query_log" {
        // query logs go to a separate file
        file "/var/log/query.log" versions 10 size 500k;
        severity debug;
		print-severity yes;
        print-time yes;
    };

    category default { named_log; };
    category queries { query_log; };
};

options {
        directory "/etc/namedb";
		pid-file "/var/run/named/pid";
        statistics-file "/var/stats/named.stats";
        dump-file "/var/dump/named.dump";
        listen-on { "internal-net"; };
        allow-query { "internal-net"; "colonies"; };
        allow-transfer { none; };

// In addition to the "forwarders" clause, you can force your name
// server to never initiate queries of its own, but always ask its
// forwarders only, by enabling the following line:
//
//      forward only;

// 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 {
                <ISP DNS server 1>; <ISP DNS server 2>;
        };

        /*
         * 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;
};

// Setting up secondaries is way easier and the rough picture for this
// is explained below.
//
// If you enable a local name server, don't forget to enter 127.0.0.1
// into your /etc/resolv.conf so this server will be queried first.
// Also, make sure to enable it in /etc/rc.conf.

view "standard-in" in {

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

        zone "arda.homeunix.net" {
                type slave;
                file "slave/bak.arda.homeunix.net.zone";
                masters { 192.168.10.9; };
        };

        zone "arda.homelinux.net" {
                type slave;
                file "slave/bak.arda.homelinux.net.zone";
                masters { 192.168.10.9; };
        };

        zone "10.168.192.in-addr.arpa" {
                type slave;
                file "slave/bak.10.168.192.in-addr.arpa";
                masters { 192.168.10.9; };
        };

        zone "0.10.10.in-addr.arpa" {
                type slave;
                file "slave/bak.0.10.10.in-addr.arpa";
                masters { 192.168.10.9; };
        };

        zone "localhost" {
                type master;
                file "master/localhost.zone";
        };

        zone "0.0.127.in-addr.arpa" {
                type master;
                file "master/localhost.rev";
        };

        zone "0.in-addr.arpa" {
                type master;
                file "master/named.network";
        };

        zone "255.in-addr.arpa" {
                type master;
                file "master/named.broadcast";
        };
};

view "ultimate-chaos" chaos {

        recursion no;

        zone "." {
                type hint;
                file "/dev/null";
        };

        zone "bind" {
                type master;
                file "master/named.bind";
        };
};

This file looks a lot like my named.conf file on Europa but there are some differences.

  • The server clause tells BIND which TSIG key to use when doing zone transfers with Europa, my primary name server.
  • The allow-transfer option in the options section is not overridden in the arda.homeunix.net, arda.homelinux.net, 10.168.192.in-addr.arpa, and 0.10.10.in-addr.arpa zones. Zone transfers should only be done from a name server primary for the zones. Not setting allow-transer to none could also open up a back door if you don’t want to share your zone data.

Here is my rndc.conf file.

/*
 * Copyright (C) 2000, 2001  Internet Software Consortium.
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
 * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

/* $Id: rndc.conf,v 1.7 2001/01/09 21:40:45 bwelling Exp $ */

options {
        default-server  localhost;
        default-key     "rndc-key";
};

server 127.0.0.1 {
        key     "rndc-key";
};

key "rndc-key" {
        algorithm       hmac-md5;
        secret
        "<rndc-key>";
};

And here is my rndc.key file.

key "rndc-key" {
        algorithm       hmac-md5;
        secret
        "<rndc-key>";
};

key "europa-io" {
        algorithm       hmac-md5;
        secret
        "<europa-io key>";
};

My /etc/resolv.conf file looks like this.

domain  arda.homeunix.net
nameserver      127.0.0.1
nameserver      192.168.10.9

Zone Files

On Io, zone files live in the directories /etc/namedb/master and /etc/namedb/slave. The section that describes running BIND chrooted shows you what these directories look like.

Here are the nine zone files on Io.

Zone File Contents
bak.arda.homelinux.net.zone copied from Europa via automated zone transfer
bak.arda.homeunix.net.zone copied from Europa via automated zone transfer
bak.10.168.192.in-addr.arpa copied from Europa via automated zone transfer
bak.0.10.10.in-addr.arpa copied from Europa via automated zone transfer
localhost.zone
$TTL 1w
@        IN SOA europa.arda.homeunix.net. postmaster.arda.homeunix.net. (
                                        1       ; Serial
                                        6h      ; Refresh after 6 hours
                                        1h      ; Retry after 1 hour
                                        1w      ; Expire after 1 week
                                        1d )    ; Negative caching TTL of 1 day

                        IN      NS      europa.arda.homeunix.net.
                        IN      NS      io.arda.homeunix.net.

localhost.              IN      A       127.0.0.1
localhost.rev
$TTL 1w
@        IN SOA europa.arda.homeunix.net. postmaster.arda.homeunix.net. (
                                        1       ; Serial
                                        6h      ; Refresh after 6 hours
                                        1h      ; Retry after 1 hour
                                        1w      ; Expire after 1 week
                                        1d )    ; Negative caching TTL of 1 day

                        IN      NS      europa.arda.homeunix.net.
                        IN      NS      io.arda.homeunix.net.

1                       IN      PTR     localhost.
named.broadcast
named.network
$TTL 1w
@       IN SOA europa.arda.homeunix.net. postmaster.arda.homeunix.net. (
                                        1       ; Serial
                                        6h      ; Refresh after 6 hours
                                        1h      ; Retry after 1 hour
                                        1w      ; Expire after 1 week
                                        1d )    ; Negative caching TTL of 1 day

                        IN      NS      europa.arda.homeunix.net.
                        IN      NS      io.arda.homeunix.net.
named.bind
$TTL 1w
$ORIGIN bind.
@       CHAOS SOA europa.arda.homeunix.net. postmaster.arda.homeunix.net. (
                                        1       ; Serial
                                        6h      ; Refresh after 6 hours
                                        1h      ; Retry after 1 hour
                                        1w      ; Expire after 1 week
                                        1d )    ; Negative caching TTL of 1 day

                        CHAOS   NS      localhost.

version.bind.           CHAOS   TXT     "BIND 9.3.1"
authors.bind.           CHAOS   TXT     "Are at home at the ISC."
named.root
; <<>> DiG 9.3.1 <<>> @a.root-servers.net . ns
; (1 server found)
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41586
;; flags: qr aa rd; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 13

;; QUESTION SECTION:
;.                              IN      NS

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

;; ADDITIONAL SECTION:
F.ROOT-SERVERS.NET.     3600000 IN      A       192.5.5.241
B.ROOT-SERVERS.NET.     3600000 IN      A       192.228.79.201
J.ROOT-SERVERS.NET.     3600000 IN      A       192.58.128.30
K.ROOT-SERVERS.NET.     3600000 IN      A       193.0.14.129
L.ROOT-SERVERS.NET.     3600000 IN      A       198.32.64.12
M.ROOT-SERVERS.NET.     3600000 IN      A       202.12.27.33
I.ROOT-SERVERS.NET.     3600000 IN      A       192.36.148.17
E.ROOT-SERVERS.NET.     3600000 IN      A       192.203.230.10
D.ROOT-SERVERS.NET.     3600000 IN      A       128.8.10.90
A.ROOT-SERVERS.NET.     3600000 IN      A       198.41.0.4
H.ROOT-SERVERS.NET.     3600000 IN      A       128.63.2.53
C.ROOT-SERVERS.NET.     3600000 IN      A       192.33.4.12
G.ROOT-SERVERS.NET.     3600000 IN      A       192.112.36.4

;; Query time: 86 msec
;; SERVER: 198.41.0.4#53(198.41.0.4)
;; WHEN: Mon May 15 00:01:43 2006
;; MSG SIZE  rcvd: 436

The zone files arda.homelinux.net.zone, arda.homeunix.net.zone, 10.168.192.in-addr.arpa, and 0.10.10.in-addr.arpa on Europa are copied to their corresponding ‘bak.’ files on Io so I won’t list them again here.

The localhost.zone, named.broadcast, named.network, and named.bind files were simply copied from Europa without modification.

FreeBSD provides the make-localhost script for creating the reverse localhost zone file. I didn’t use this script as I copied the localhost.rev file from Europa along with everything else.

As with Europa, the named.root file is the output of a dig command listing all the root name servers.

Running BIND Chrooted

As on Europa, on Io I run BIND with reduced privileges and in a chroot jail. There’s really nothing to doing this on FreeBSD as the startup script supplied with the OS does everything for you the first time you start the named process. In my case, all I needed to do was edit the existing named.conf file, copy zone files from Europa, and create the rndc.key, rndc.conf files and that’s it. The directory FreeBSD uses for its jail is /var/named. Here is what it looked like after I was done adding files and after the first zone transfer from Europa.

drwxr-xr-x   5 root    wheel      512 Oct 10 00:28 /var/named
dr-xr-xr-x  4 root  wheel  512 Oct  9 15:46 /var/named/dev
crw-rw-rw-  1 root  wheel    2,   2 Oct 11 18:00 var/named/dev/null
crw-rw-rw-  1 root  wheel  246,   0 Oct  5 20:28 var/named/dev/random
drwxr-xr-x  3 root  wheel  512 Oct 10 00:28 /var/named/etc
-r--r--r--  1 root  wheel  1252 Sep 11 12:10 /var/named/etc/localtime
drwxr-xr-x  5 root  wheel   512 Oct 10 00:28 /var/named/etc/namedb
-rw-r--r--  1 root  wheel   423 May  8 03:05 /var/named/etc/namedb/PROTO.localhost-v6.rev
-rw-r--r--  1 root  wheel   423 May  8 03:05 /var/named/etc/namedb/PROTO.localhost.rev
drwxr-xr-x  2 bind  wheel   512 May  8 03:00 /var/named/etc/namedb/dynamic
-rw-r--r--  1 root  wheel  1093 May  8 03:05 /var/named/etc/namedb/make-localhost
drwxr-xr-x  2 root  wheel   512 Oct  9 15:01 /var/named/etc/namedb/master
-rw-r--r--  1 root  wheel   621 Oct  9 21:46 /var/named/etc/namedb/master/localhost.rev
-rw-r--r--  1 root  wheel   597 Oct  9 21:46 /var/named/etc/namedb/master/localhost.zone
-rw-r--r--  1 root  wheel   581 Oct  9 15:41 /var/named/etc/namedb/master/named.bind
-rw-r--r--  1 root  wheel   562 Oct  9 21:47 /var/named/etc/namedb/master/named.broadcast
-rw-r--r--  1 root  wheel   562 Oct  9 21:47 /var/named/etc/namedb/master/named.network
-rw-r--r--  1 root  wheel  1516 Oct  9 15:44 /var/named/etc/namedb/master/named.root
-rw-r--r--  1 root  wheel  4468 Jun 12 07:46 /var/named/etc/namedb/named.conf
-rw-------  1 root  wheel   299 Oct 10 00:28 /var/named/etc/namedb/rndc.conf
-rw-r-----  1 root  bind    314 Oct  9 15:37 /var/named/etc/namedb/rndc.key
drwxr-xr-x  2 bind  wheel   512 Oct  9 21:57 /var/named/etc/namedb/slave
-rw-r--r--  1 bind  wheel   412 Jul  5 21:40 /var/named/etc/namedb/slave/bak.0.42.10.in-addr.arpa
-rw-r--r--  1 bind  wheel   718 Jul  5 22:37 /var/named/etc/namedb/slave/bak.42.168.192.in-addr.arpa
-rw-r--r--  1 bind  wheel   503 Jul  5 22:20 /var/named/etc/namedb/slave/bak.arda.homelinux.net.zone
-rw-r--r--  1 bind  wheel   796 Jul  5 21:48 /var/named/etc/namedb/slave/bak.arda.homeunix.net.zone
drwxr-xr-x  6 root  wheel  512 May  8 03:00 /var/named/var
drwxr-xr-x  2 bind  wheel  512 May  8 03:00 /var/named/var/dump
drwxr-xr-x  2 bind  wheel  512 Oct 11 06:47 /var/named/var/log
-rw-r--r--  1 bind  wheel  300465 Oct 11 18:24 /var/named/var/log/named.log
-rw-r--r--  1 bind  wheel  240046 Oct 11 18:30 /var/named/var/log/query.log
drwxr-xr-x  3 bind  wheel  512 May  8 03:00 /var/named/var/run
drwxr-xr-x  2 bind  wheel  512 Oct  9 21:54 /var/named/var/run/named
-rw-r--r--  1 bind  wheel  6 Oct  9 21:54 /var/named/var/run/named/pid
drwxr-xr-x  2 bind  wheel  512 May  8 03:00 /var/named/var/stats

All the files and devices needed to run BIND in the jail automagically appear when named starts. Look at the section that describes running BIND in a chroot jail on Europa for an explanation of what these files and devices do.

Startup Scripts

To run BIND on system boot, put this line into /etc/rc.conf.

    named_enable=”YES”

If you really want BIND’s chroot jail to reside in a different directory, you can add this line to /etc/rc.conf as well.

    named_chrootdir=”/your/chosen/path”

If you decide to do this, remember to copy the directory structure found in /var/named to your preferred chroot otherwise all that wonderful automation I talked about won’t work.

Did I mention that FreeBSD also configures BIND to run with reduced privileges as the user bind? There is no need for you to create the required user or set extra arguments for named yourself. Not bad, huh?

DHCP

When I built the DHCP package on Europa, I used a tarball instead on an rpm because I wanted to apply a patch which allows DHCP to run with reduced privileges and to be chrooted. You’ll find a link to this patch in the Software Home Sites section at the end of this document. It is called ‘dhcp-3.0+paranoia.patch’. In order to use the features of this patch, you need to pass some options to configure when building DHCP so read the comments at the beginning of the file. Here are the options I used when building DHCP.

./configure --copts "-DPARANOIA"

Configuration Files

Here is my dhcpd.conf file.

# DHCP Daemon configuration file

authoritative;

max-lease-time 86400;
default-lease-time 14400;
ddns-update-style interim;
ddns-ttl 14400;

subnet 192.168.10.0 netmask 255.255.255.224 {
    range 192.168.10.24 192.168.10.30;

    # don't let clients modify their own A records
    ignore client-updates;

    # options
    option subnet-mask 255.255.255.224;
    option broadcast-address 192.168.10.31;

    option domain-name "arda.homeunix.net";
    option domain-name-servers 192.168.10.9, 192.168.10.5;
    option routers 192.168.10.1;

    option ntp-servers 192.168.10.1;

    option netbios-scope "";
    option netbios-node-type 8;
    option netbios-name-servers 192.168.10.9;
    option netbios-dd-server 192.168.10.9;

    # dynamic DNS updates
    ddns-updates on;
    ddns-domainname "arda.homeunix.net.";
    ddns-rev-domainname "in-addr.arpa.";

    key "europa-dhcp" {
        algorithm       hmac-md5;
        secret
        "<europa-dhcp key goes here>";
    };

    zone arda.homeunix.net {
        primary 192.168.10.9;
        key "europa-dhcp";
    }

    zone 10.168.192.in-addr.arpa {
        primary 192.168.10.9;
        key "europa-dhcp";
    }

}

The dhcpd.conf file supplies all the information that will be given to DHCP clients and also controls dynamic updates with DNS servers. There are several points to note with this file.

  • I’m using a CIDR network. This only seemed reasonable given the small number of machines I have running. The size of the network (32 IP addresses starting with 192.168.10.0) is stipulated by the subnet and netmask line. Make sure the subnet-mask and broadcast-address lines match otherwise your network is going to get very confused. You can calculate all the network parameters you need to set up a CIDR network from my IP Addressing for CIDR Networks page.
  • The ddns-* parameters control dynamic updates between DHCP and BIND. Make sure you use the correct value for ddns-update-style. The parameter accepts a few different values but not all work and which one does is very sensitive to the particular version of DHCP and BIND you are using. I used to use ‘ad-hoc’ for this value but when I upgraded to my current setup, I needed to change the value to ‘interim’.
  • The interim update style allows DHCP clients to update their own A records if they so choose. I want all updates to my DNS server to come from the DHCP server so I added the ignore client-updates parameter to my dhcpd.conf file.
  • The netbios-* options all provide information to Windows clients. These options allow my Windows clients to access the network and mount shares from my Samba server.
  • The europa-dhcp TSIG key referred to in the configuration file is the same key that appears in the rndc.key file on Europa.

Running DHCP Chrooted

Like BIND, I run DHCP with reduced privileges and in a chroot jail. The process to do this is similar to what I did for BIND but there are a few differences. Here is how I set up DHCP to run from the directory /etc/dhcpdb.

  1. The first thing to do was to create the user and group dhcpd would run as. Unlike BIND, I needed to do this manually. I chose the entirely predictable name ‘dhcpd’ for both user and group.
  2. I needed to add a number of directories and files to /etc/dhcpdb. Here is what things looked like after I was done.
    drwxr-xr-x    2 root     root         1024 Jul 17 10:12 /etc/dhcpdb/dev/
    crw-rw-rw-    1 root     root       1,   3 Jul 17 22:06 /etc/dhcpdb/dev/null
    crw-r--r--    1 root     root       1,   8 Jul 17 22:07 /etc/dhcpdb/dev/random
    drwxr-xr-x    2 root     root         1024 Jul 17 15:32 /etc/dhcpdb/etc/
    -rw-r--r--    1 root     root         1218 Jul 17 15:32 /etc/dhcpdb/etc/localtime
    drwxr-xr-x    4 root     root         1024 Jul 17 10:02 /etc/dhcpdb/var/
    drwxr-xr-x    2 dhcpd    dhcpd        1024 Jul 17 15:40 /etc/dhcpdb/var/run/
    drwxr-xr-x    3 root     root         1024 Jul 17 10:09 /etc/dhcpdb/var/state/
    drwxr-x---    2 dhcpd    dhcpd        1024 Jul 18 11:31 /etc/dhcpdb/var/state/dhcp/
    • The var/run directory is where DHCP’s pid file will go.
    • The var/state/dhcp directory is where the lease files will go.
    • Create the dev/null special file using the command ‘mknod /etc/dhcpdb/dev/null c 1 3′.
    • Create the dev/random special file using the command ‘mknod /etc/dhcpdb/dev/random c 1 8′.
    • As with BIND, the major and minor numbers for null and random are the same as the corresponding files found in /dev. I don’t know whether these files are actually necessary to run DHCP chrooted. dhcpd doesn’t complain when started without these special files present. I’ve put them in the jail more for insurance than anything else.
    • The etc/localtime file is copied from /etc. This file ensures DHCP uses the correct timezone when sending messages to syslog.
    • The var/run directory is owned by dhcpd:dhcpd. This is because the pid file is written after dhcpd has dropped privileges.

     

  3. I needed to give DHCP a way to send messages to syslog from within the chroot jail. To accomplish this, I modified one line in the file /etc/sysconfig/syslog.
        SYSLOGD_OPTIONS=”-m 0″
            became
      SYSLOGD_OPTIONS=”-m 0 -a /etc/dhcpdb/dev/log”

    Stopping and starting syslog will cause a new syslog socket to appear in the /etc/dhcpdb/dev directory.

  4. You’ll notice that dhcpd’s configuration file isn’t in the jail. It is located in /etc. Here is a listing of the file.
    -rw-------    1 root     root         1225 Jul 17 10:51 /etc/dhcpd.conf

    The dhcp-3.0+paranoia patch tells dhcpd to read dhcpd.conf before dropping privileges and invoking the chroot jail which is why the file is owned by root and is located outside the jail. I’ve set the permissions on this file to be restrictive because it contains the TSIG key used to dynamically update BIND. Having file permissions and ownership set up this particular way prevents the daemon from being able to modify the configuration file while still being able to read it at start up. Only a process with root privileges (presumably a sysadmin logged in as root) is able to modify the file.

Startup Scripts

Not only do I specify DHCP’s user, group, and chroot jail at startup, I also specify the particular interface DHCP listens on for requests. Here is my /etc/rc.d/init.d/dhcpd startup script. I modified this file, rather messily, to deal with DHCP running chrooted.

#!/bin/bash
#
# dhcpd           This shell script takes care of starting and stopping
#                 dhcpd (dynamic boot parameter server).
#
# chkconfig: 345 55 45
# description: dhcpd dynamically assigned network \
# parameters to clients at boot time.
# probe: true

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ "${NETWORKING}" = "no" ] && exit 0

#[ -f /etc/sysconfig/named ] && . /etc/sysconfig/named

[ -f /usr/sbin/dhcpd ] || exit 0

# set the chroot directory
chrootdir="/etc/dhcpdb"

[ -f /etc/dhcpd.conf ] || exit 0

RETVAL=0
prog="dhcpd"

start() {
        # Start daemons.
        gprintf "Starting %s: " $prog
        daemon $prog -q -user dhcpd -group dhcpd -chroot $chrootdir eth0
        RETVAL=$?
        [ $RETVAL -eq 0 ] && touch /var/lock/subsys/dhcpd
        echo
        return $RETVAL
}
stop() {
        # Stop daemons.
        gprintf "Stopping %s: " $prog
        pid=`pidofproc $prog`
        kill -TERM $pid
        RETVAL=$?
        [ $RETVAL -eq 0 ] && success "dhcpd shutdown" || failure "dhcpd shutdown"
        [ $RETVAL -eq 0 ] && rm -f $chrootdir/var/run/dhcpd.pid
        [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/dhcpd
        echo
        return $RETVAL
}
status() {
        status dhcpd
}
restart() {
        stop
        start
}
reload() {
        stop
        start
}

# See how we were called.
case "$1" in
        start)
                start
                ;;
        stop)
                stop
                ;;
        status)
                status
                ;;
        restart)
                restart
                ;;
        condrestart)
                [ -f /var/lock/subsys/dhcpd ] && restart
                ;;
        reload)
                reload
                ;;
        *)
                gprintf "Usage: %s {start|stop|status|restart|condrestart|reload}\n" $0
                exit 1
esac

exit $?

Software Home Sites

BIND
DHCP
http://www.isc.org/
dhcp-3.0+paranoia.patch http://www.episec.com/people/edelkind/patches/

Further Reading

Bind9.net – An excellent source of DNS and DHCP information http://www.bind9.net/
DNS Group Webstart Page – Lots of links to DNS information http://www.the-paynes.com/DNS/
DNS Setup and Troubleshooting – Covers BIND version 8 http://www.troubleshooters.com/linux/dns.htm
Building and Running BIND 9 http://www.unixwiz.net/techtips/bind9-chroot.html
Secure BIND Template http://www.cymru.com/Documents/secure-bind-template.html