The DSL router/modem (an Alcatel Speedtouch 510) that brokers Internet connectivity for hydrus.org.uk locks up every couple of months. The usual symptoms are that the DHCP server and DNS stop working (these are the 'added value' facilities it offers that I make use of in my local area network). The last time this happened, I decided I would transfer the DHCP and DNS capabilities to the FreeBSD box, crimson. Maybe this would take some load of the Alcatel router, leading to less frequent reboots. The following is a recipe for defining DNS and DHCP server services for a small network.
Since the build process on crimson had been changed to stop compiling bind, it had to be rebuilt manually. This is fairly easy, by issuing the following commands (as root):
# cd /usr/src/lib/bind # make obj && make depend && make && make install # cd /usr/src/usr.sbin/named # make obj && make depend && make && make install
Now that bind was working (don't forget to add
named_enable="YES"
in /etc/rc.conf
), I could
create the configuration files. After poking about on the web, and
reading the O'Reilly "DNS and BIND" book, I came up with the
following configuration files:
// Standard FreeBSD settings options { directory "/etc/namedb"; pid-file "/var/run/named/pid"; dump-file "/var/dump/named_dump.db"; statistics-file "/var/stats/named.stats"; // 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. // Note: real IP's removed. forwarders { xx.xx.xx.xx; yy.yy.yy.yy; }; /* * 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 versions 8 and later * use a pseudo-random unprivileged UDP port by default. */ query-source address * port 53; }; zone "." { type hint; file "named.root"; }; zone "0.0.127.IN-ADDR.ARPA" { type master; file "dynamic/db.127.0.0"; }; zone "hydrus.org.uk" in { type master; file "dynamic/db.hydrus.org.uk"; allow-update { 192.168.0.15; }; }; zone "0.168.192.in-addr.arpa" in { type master; file "dynamic/db.192.168.0"; allow-update { 192.168.0.15; }; };
Note that the allow-update
line ensures that a DHCP server
is able to dynamically update DNS. Note further that the
configuration files for bind (shown below), live in the
dynamic
subdirectory; this is because only the
dynamic
and slave
subdirectories in the
/etc/namedb
directory are owned by bind. Dynamic DNS
requires the ability to create and modify files in the directory
where its configuration files live (a .jnl
file for one).
The other configuration files are are shown below. There are the three key files that must be defined. Note the the files shown below are as I originally defined them; dynamic DNS will cause them to change when in operation.
This file defines the forward lookups, that is from name to IP address.
$TTL 3h @ IN SOA crimson.hydrus.org.uk. root.crimson.hydrus.org.uk. ( 1 ; Serial 3h ; Refresh after 3 hours 1h ; Retry after 1 hour 1w ; Expire after 1 week 1h ) ; Negative caching TTL of 1 hour ; Name server IN NS crimson.hydrus.org.uk. ; Static addresses localhost IN A 127.0.0.1 crimson IN A 192.168.0.15 speedtouch IN A 192.168.0.1 ; Aliases www IN CNAME crimson
This file defines the reverse lookups, i.e. from IP address to name.
$TTL 3h @ IN SOA crimson.hydrus.org.uk. root.crimson.hydrus.org.uk. ( 1 ; Serial 3h ; Refresh after 3 hours 1h ; Retry after 1 hour 1w ; Expire after 1 week 1h ) ; Negative caching TTL of 1 hour ; Name server IN NS crimson.hydrus.org.uk. ; Addresses point to canonical name 15 IN PTR crimson.hydrus.org.uk. 1 IN PTR speedtouch.hydrus.org.uk.
You also need definitions for the local loopback address reverse lookup.
$TTL 3h @ IN SOA crimson.hydrus.org.uk. root.crimson.hydrus.org.uk. ( 1 ; Serial 3h ; Refresh after 3 hours 1h ; Retry after 1 hour 1w ; Expire after 1 week 1h ) ; Negative caching TTL of 1 hour ; Name server IN NS crimson.hydrus.org.uk. ; Addresses point to canonical name 1 IN PTR localhost.
I started named
via the /etc/rc.d/named
script,
and tested it with nslookup. Once it seemed to be working, for both
internal and external names, I changed /etc/resolv.conf to use the
localhost (127.0.0.1) as the first nameserver.
The ports contain the ISC DHCP server, isc-dhcp3-server:
isc-dhcp3-server-3.0.3 The ISC Dynamic Host Configuration Protocol server
Downloading and installing the package was the work of a few moments with portupgrade:
portupgrade -NPP isc-dhcp3-server
The configuration, via /usr/local/etc/dhcpd.conf
was not
too difficult, but it did take a while to figure out how to assign a
fixed IP address to chrome. At first, I tried the host
directive but, while that certainly gave out the right IP address,
the host name was never entered into the DNS. Dynamic DNS updates
did work for addresses assigned via the subnet
directive;
so it seemed I was misusing the host
directive.
Eventually, I figured out the scheme shown below. This sets up a
class to which only chrome can possibly belong (by virtue of its MAC
address). The class is granted access to a pool with one address,
and denied access to the general pool.
However, this whole scheme was a waste of time, since I realised that chrome could not be dependent on crimson for IP address, as a disaster backup machine cannot rely on crimson for anything.
Anyway, here's the dhcpd.conf
file I arrived at.
# dhcpd.conf # # crimson configuration file for ISC dhcpd # # mpw 12th March, 2006 # option definitions common to all supported networks... option domain-name "hydrus.org.uk"; option domain-name-servers crimson.hydrus.org.uk, xx.xx.xx.xx, yy.yy.yy.yy; option routers 192.168.0.1; default-lease-time 7200; max-lease-time 7200; # If this DHCP server is the official DHCP server for the local # network, the authoritative directive should be uncommented. authoritative; # ad-hoc DNS update scheme - set to "none" to disable dynamic DNS updates. ddns-update-style interim; # Use this to send dhcp log messages to a different log file (you also # have to hack syslog.conf to complete the redirection). log-facility local7; # define chrome class for static address of chrome class "chrome" { match if substring ( hardware,1,6) = 00:41:15:a1:75:59; } subnet 192.168.0.0 netmask 255.255.255.0 { pool { allow members of "chrome"; range 192.168.0.30; } pool { deny members of "chrome"; range 192.168.0.35 192.168.0.45; } }
The final DNS configuration has chrome defined as a fixed IP address. I mirrored the DNS configuration files to chrome, so that it had its own named running. In case of disaster, all I'd need to do would be to start dhcpd running.
In fact, I wrote a local rc script to start the dhcpd daemon automatically if crimson was down:
#!/bin/sh # # If crimson is down, start dhcpd # DHCPD='dhcpd_enable="YES"' case "$1" in start) ping -c 1 -o -t 1 crimson >/dev/null 2>amp;1 if [ $? -ne 0 ]; then echo "$0: crimson down. Starting dhcpd..." echo ${DHCPD} >>/etc/rc.conf sh /usr/local/etc/rc.d/isc-dhcpd start fi ;; stop) if grep -q ${DHCPD} /etc/rc.conf; then sh /usr/local/etc/rc.d/isc-dhcpd stop cat /etc/rc.conf | sed -e "/${DHCPD}/d" >/tmp/$$ cp /tmp/$$ /etc/rc.conf;rm /tmp/$$ fi ;; esac