Friday, April 4, 2008

DHCP, DNS and dynamic updates

Today I updated my router, a Soekris net4801 (I think), to OpenBSD 4.2. I know it's dumb to upgrade to OpenBSD 4.2 about three weeks before OpenBSD 4.3 is officially released, but today I actually had time and the box was in desperate need of an update. Also, I have recently moved and the network changed. I used to have a designated server running FreeBSD that also handled DNS and DHCP. When I moved, I shut the server down, and so for the last few weeks I had only very basic DHCP services running and no local DNS at all. Anyways, to make the long story short, I needed a DNS server that would resolve local names as well as a DHCP server that does dynamic DNS upates.

First, I installed OpenBSD 4.2 by netbooting the Soekris box from another OpenBSD "box" running inside Parallels. The instructions for that can be found in the OpenBSD FAQ. There is one thing to remember, though: The Soekris doesn't have a VGA console but only serial, so the PXE-booted kernel needs to be told that it should only use the serial console for output. So the boot.conf file the FAQ mentions needs to look like this:
set tty com0
set stty 9600
boot bsd.rd
Now on to the DHCP and DNS installation. The DHCP server included with OpenBSD will not do dynamic DNS updates, so the ISC DHCP Server is needed. It can be installed by running (as root):
# ftp ftp://ftp.de.openbsd.org/pub/OpenBSD/4.2/packages/i386/isc-dhcp-server-3.0.4p0.tgz
# pkg_add -v isc-dhcp-server-3.0.4p0.tgz
The dhcpd binary will be installed in /usr/local/sbin. Be aware that the base dhcpd included in OpenBSD lives in /usr/sbin, so simply typing "dhcpd" at the command line will most certainly start the OpenBSD DHCP Server! In order to automatically start the DHCP server on boot, these lines need to be added to /etc/rc.local:
if [ -x /usr/local/sbin/dhcpd ] ; then
        echo -n ' dhcpd' ; /usr/local/sbin/dhcpd
fi
Next, before the Server can be fully configured, a key that will be shared between DHCP and DNS server needs to be created:
$ dnssec-keygen -a HMAC-MD5 -b 128 -n USER <name>
This command generates to files in the current working directory. The file with the extension *.private will include the key required later. Wherever the configuration files include a "secret" statement, that value needs to be inserted. The parameter <name> determines the name of the key. This will be used later, but I don't know if the name actually has to be reused. For the rest of this posting, we'll use key_name to represent the generated key's name.

So now on to the DHCP Server configuration. My /etc/dhcpd.conf now looks like this:
option  domain-name "local.deadc0.de";

ddns-update-style ad-hoc;

key key_name {
        algorithm       hmac-md5;
        secret          "...";
}

zone local.deadc0.de. {
        primary 127.0.0.1;
        key key_name;
}

zone 1.168.192.in-addr.arpa. {
        primary 127.0.0.1;
        key key_name;
}

zone 2.168.192.in-addr.arpa. {
        primary 127.0.0.1;
        key key_name;
}

subnet 192.168.1.0 netmask 255.255.255.0 {
        range 192.168.1.1 192.168.1.127;
        
        option domain-name-servers 192.168.1.254;
        option routers 192.168.1.254;
}
        
subnet 192.168.2.0 netmask 255.255.255.0 {
        range 192.168.2.1 192.168.2.127;

        option domain-name-servers 192.168.2.254;
        option routers 192.168.2.254;
}
Now that the DHCP server is configured, the DNS server needs configuration. In OpenBSD, the DNS Server is BIND, but it's started in a chroot environment, so its configuration files live under /var/named. The server configuration file is /var/named/etc/named.conf and looks like this on my system:
include "etc/rndc.key";

controls {
        inet 127.0.0.1 allow {
                localhost;
        } keys {
                key_name;
        };
};

acl clients {
        localnets;
        ::1;
};

options {
        listen-on    { any; };
        listen-on-v6 { any; };

        allow-recursion { clients; };
};

// Standard zones ommited.

zone "local.deadc0.de" {
        type master;
        file "master/local.deadc0.de";
        
        allow-update {
                key     "key_name";
        };
};

zone "1.168.192.in-addr.arpa" {
        type master;
        file "master/1.168.192.in-addr.arpa";

        allow-update {
                key     "key_name";
        };
};

zone "2.168.192.in-addr.arpa" {
        type master;
        file "master/2.168.192.in-addr.arpa";

        allow-update {
                key     "key_name";
        };
};
The actual zone files will not be posted, they are just standard zone declarations, nothing special. However, notice the include statement at top of the file. It includes the key declaration file /var/named/etc/rndc.key that looks like this:
key key_name {
        algorithm hmac-md5;
        secret "...";
};
In order to supress some warning when the DNS server starts, the file /var/named/etc/rndc.conf needs to be created. It should look like this:
options {
        default-server  localhost;
        default-key     "key_name";
};

server localhost {
        key     "key_name";
};

include "rndc.key";
Finally, everything under /var/named/etc and /var/named/master needs to be owned by the user "named", so as root run this:
# chown -R named:named /var/named/etc
# chown -R named:named /var/named/master
Now make sure that the DNS server is enabled by including this line in /etc/rc.conf.local:
named_flags=""
Then reboot the box and that should be it.

No comments: