DNS DHCP server
From OptionC
| Table of contents |
Introduction
The purpose of this document is to list how to make a DNS and DHCP server. These can be combined in a single machine or split. As with the other documents there is little or no reference to Xen, emphasising that the Xen virtual machine is, effectively, simply another Linux machine.
Base Installation
Start with a small base system, such as the one detailed here. For both the DNS and the DHCP server you should probably not use DHCP to get your network configuration (IP address, nameserver, etc), but assign them statically.
DNS
The type of DNS configuration depends upon the needs of the network. I wanted to set up a small LAN DNS, serving a small office. I needed to have a non-official TLD with a couple of internal mail servers and a web server. The following are the steps I took.
Install BIND (will also install dependencies):
# apt-get install bind9 dnsutils
Configuration:
We want to create our own domain. In order to not upset anyone out in the "real world", we'll use a completely made-up domain name: ournet.blah (as of now, Internet Corporation for Assigned Names and Numbers (ICANN) has not yet approved ".blah" as top level domain, although, considering the amount of pretentious nonsense available on the Interet, I'm sure it's only a matter of time).
First, if your machine is configured via DHCP then it will have the wrong nameserver defined -- since you're attempting to define the local machine as a nameserver, anything else that's defined is, by definition, wrong. If your machine has not been configured via DHCP (better for a DNS server), you'll still need to perform the following steps to ensure that searching for the "ournet.blah" machines occurs in the right place.
Edit /etc/resolv.conf:
search ournet.blah nameserver 127.0.0.1
To prevent resolv.conf from being reset by DHCP, type the following command:
# chattr +i /etc/resolv.conf
(If you choose, at a later time you can remove this attribute by using -i instead of +i)
In /etc/bind/named.conf.local, add the following:
zone "ournet.blah" {
type master;
notify no;
file "/etc/bind/ournet.blah";
};
Create the /etc/bind/ournet.blah zone file, similar to the following:
;
; Zone file for ournet.blah
;
; The full zone file
;
$TTL 3D
@ IN SOA ns.ournet.blah. hostmaster.ournet.blah. (
200506241 ; serial # (date + #)
8H ; refresh time
2H ; retry time
4W ; expires in...
1D ) ; minimum
;
NS ns ; Address of name server
MX 10 mail.ournet.blah. ; Primary Mail Exchanger
MX 20 mail2.ournet.blah. ; Secondary Mail Exchanger
;
localhost A 127.0.0.1
gw A 192.168.64.1
TXT "The gateway to the world"
ns A 192.168.64.2
MX 10 mail
MX 20 mail2
mail A 192.168.64.10
mail2 A 192.168.64.11
www A 192.168.64.20
ftp CNAME www
This data defines the following:
- SOA (Start Of Authority) record
- NS (Nameserver) record, giving the address of the name server
- MX (Mail eXchange) records, for a primary and secondary mail server
Finally, some specific A (address) records are set up. Note that ftp.ournet.blah is an alias to www.ournet.blah, using a CNAME (Canonical NAME) record.
To test what we've got so far, we need to reload the nameserver daemon.
# rndc reload
We use dig to test:
# dig ournet.blah axfr ; <<>> DiG 9.2.4 <<>> ournet.blah axfr ;; global options: printcmd ournet.blah. 259200 IN SOA ns.ournet.blah. hostmaster.ournet.blah. 200506241 28800 7200 2419200 86400 ournet.blah. 259200 IN NS ns.ournet.blah. ournet.blah. 259200 IN MX 10 mail.ournet.blah. ournet.blah. 259200 IN MX 20 mail2.ournet.blah. ftp.ournet.blah. 259200 IN CNAME www.ournet.blah. gw.ournet.blah. 259200 IN A 192.168.64.1 gw.ournet.blah. 259200 IN TXT "The gateway to the world" localhost.ournet.blah. 259200 IN A 127.0.0.1 mail.ournet.blah. 259200 IN A 192.168.64.10 mail2.ournet.blah. 259200 IN A 192.168.64.11 ns.ournet.blah. 259200 IN A 192.168.64.2 ns.ournet.blah. 259200 IN MX 10 mail.ournet.blah. ns.ournet.blah. 259200 IN MX 20 mail2.ournet.blah. www.ournet.blah. 259200 IN A 192.168.64.20 ournet.blah. 259200 IN SOA ns.ournet.blah. hostmaster.ournet.blah. 200506241 28800 7200 2419200 86400 ;; Query time: 1 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) ;; WHEN: Fri Jun 24 15:45:23 2005 ;; XFR size: 15 records
Now we need the reverse zone so that programs can convert addresses to DNS names. Many services use reverse DNS to decide if you should have access.
Add the following to /etc/bind/named.conf.local:
zone "64.168.192.in-addr.arpa" {
type master;
notify no;
file "/etc/bind/192.168.64";
};
Create the /etc/bind/192.168.64 file:
;
; Reverse Zone file for ournet.blah
;
$TTL 3D
@ IN SOA ns.ournet.blah. hostmaster.ournet.blah. (
200506241 ; serial # (date + #)
8H ; refresh, seconds
2H ; retry, seconds
4W ; expire, seconds
1D ) ; minimum, seconds
;
NS ns.ournet.blah.
;
1 PTR gw.ournet.blah.
2 PTR ns.ournet.blah.
10 PTR mail.ournet.blah.
11 PTR mail2.ournet.blah.
20 PTR www.ournet.blah.
Restart the name daemon, named, and use dig to check the results:
# rndc reload # dig -x 192.168.64.20 ; <<>> DiG 9.2.4 <<>> -x 192.168.64.20 ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15849 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1 ;; QUESTION SECTION: ;20.64.168.192.in-addr.arpa. IN PTR ;; ANSWER SECTION: 20.64.168.192.in-addr.arpa. 259200 IN PTR www.ournet.blah.64.168.192.in-addr.arpa. ;; AUTHORITY SECTION: 64.168.192.in-addr.arpa. 259200 IN NS ns.ournet.blah. ;; ADDITIONAL SECTION: ns.ournet.blah. 259200 IN A 192.168.64.2 ;; Query time: 0 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) ;; WHEN: Fri Jun 24 15:55:09 2005 ;; MSG SIZE rcvd: 119
If you have a small network with fixed IP addresses then you now have a useful DNS system. Simply update the two files -- /etc/bind/ournet.blah and /etc/bind/192.168.64 -- with your machine names and IP addresses.
DHCP Server
The DNS server as it stands works well. Not being willing to leave well enough alone, I decided to make it into a DHCP server as well.
First, install the daemon, dhcpd:
# apt-get install dhcpd
If you're installing DHCP for the first time then you'll probably get some warning messages about needing to create/edit the configuration. If you simply want to assign IP addresses at random, then use something like the following:
# option definitions common to all supported networks...
option domain-name "ournet.blah";
option domain-name-servers ns.ournet.blah;
option subnet-mask 255.255.255.0;
default-lease-time 3600;
max-lease-time 7200;
subnet 192.168.64.0 netmask 255.255.255.0 {
range 192.168.64.150 192.168.64.200;
}
To restart the daemon,
# /etc/init.d/dhcp restart
If you want to assign static IP addresses to specific machines (for example, servers) then you need to use slightly more complicated configuration file:
option domain-name "ournet.blah";
option domain-name-servers ns.ournet.blah;
option subnet-mask 255.255.255.0;
default-lease-time 3600;
max-lease-time 7200;
subnet 192.168.64.0 netmask 255.255.255.0 {
range 192.168.64.150 192.168.64.200;
host ns.ournet.blah { hardware ethernet 00:0C:D1:99:BB:01; fixed-address 192.168.64.2; }
host mail.ournet.blah { hardware ethernet 00:0C:D1:99:BB:DD; fixed-address 192.168.64.10; }
host mail2.ournet.blah { hardware ethernet 00:0C:D1:99:BB:EE; fixed-address 192.168.64.11; }
host www.ournet.blah { hardware ethernet 00:0C:D1:99:BB:CC; fixed-address 192.168.64.20; }
}
DNS + DHCP
Having a DHCP server that doesn't actually talk to the DNS server can be annoying. It's much more efficient to have the DHCP addresses auto register themselves in DNS. Plus it gives a chance to write more on this HOWTO.
I've chosen to use the Debian autodns-dhcp package, a lightweight solution for automatically registering DHCP addresses in the DNS database.
Installation:
# apt-get install autodns-dhcp
Configuration: First you'll need to reconfigure DHCP. The autodns-dhcp scripts need to have a single IP per line. For example, above we had the range set in /etc/dhcpd.conf as
subnet 192.168.64.0 netmask 255.255.255.0 {
range 192.168.64.150 192.168.64.200;
}
The scripts want the ranges as follows (sorted sequentially). Note: every single IP address in the range needs to be listed. There is a one-liner perl script for that, which comes with the package's documentations. Here's a quick one: perl -le 'for ( my $i = 150; $i <= 200; ++$i ) { print " range 192.168.64.$i;\n" }' Change it so it will suite your needs.
subnet 192.168.64.0 netmask 255.255.255.0 {
range 192.168.64.150;
range 192.168.64.151;
range 192.168.64.152;
range 192.168.64.153;
range 192.168.64.154;
...
range 192.168.64.196;
range 192.168.64.197;
range 192.168.64.198;
range 192.168.64.199;
range 192.168.64.200;
}
Restart DHCP:
# /etc/init.d/dhcp restart
Next you'll need to reconfigure BIND (/etc/bind/named.conf.local). You must set BIND up to allow dynamic DNS. Again, better use a script for that: perl -le 'for ( my $i = 150; $i <= 200; ++$i ) { print " 192.168.64.$i;\n" }'
acl "okay_hosts" {
192.168.64.150;
192.168.64.151;
192.168.64.152;
192.168.64.153;
...
192.168.64.198;
192.168.64.199;
192.168.64.200;
};
zone "ournet.blah" {
type master;
notify no;
file "/etc/bind/ournet.blah";
allow-update { "okay_hosts"; };
};
zone "1.168.192.in-addr.arpa" {
type master;
notify no;
file "/etc/bind/192.168.64";
allow-update { "okay_hosts"; };
};
Edit your /etc/bind/ournet.blah (you can use the above configuration with slight changes) and /etc/bind/192.168.64. You can use the program "named-checkconf" and "named-checkzone" to make sure you wrote a valid syntax. Don't forget to increment the serial number in every edit, and don't forget that full domain names (such as domain.com, domain.co.uk, etc...) ends with a DOT (".") in BIND (domain.com., domain.co.uk., etc...).
Reload DNS configurations:
# rndc reload
Finally, you'll need to edit the /etc/autodns-dhcp.conf file. It should look like the following:
$DDNSHOME="/var/lib/autodns-dhcp"; $DHCPD="/var/lib/dhcp/dhcpd.leases"; $DOMAIN="ournet.blah"; $NSUPDATE="/usr/bin/nsupdate";
Additional:
There may be issues with the different versions of the software available. The autodns-dhcp package was created to run with BIND8; BIND9 is installed if the instructions have been followed. As such, you may need to make some modifications to the autodns-dhcp scripts which are to be found in:
- /usr/sbin/ddns.cron.pl
- /usr/sbin/ndc.cron.pl
Extra Stuff
It was suggested that I also install a tftp server. I didn't, but it would seem to be a trivial thing (in other words, it's not been tested). The following installs the HPA tftpd which has been derived from OpenBSD tftp with some extras if you wish to use the PXE protocol.
# apt-get install tftpd-hpa
Recommended Reading
The following references were useful in creating this document:
- How To Set Up A Linux Network (http://www.aboutdebian.com/network.htm)
- How To Set Up Linux DNS Services (http://www.aboutdebian.com/dns.htm)
- http://www.linux.org/docs/ldp/howto/DNS-HOWTO.html (http://www.linux.org/docs/ldp/howto/DNS-HOWTO-5.html)
- DHCP mini-HOWTO (http://www.linux.org/docs/ldp/howto/DHCP/index.html)

