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.
- Use rndc to stop BIND.
- Remove any .jnl files from the zone file directory.
- Edit the zone files as necessary. Make sure to increment the serial number of any file edited.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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 |