Linux · December 8, 2006 6

How To: Setup a DHCP Server on Linux

This is one of the first of a series of tutorials I wrote on taming the Linux daemons. It was first published at Astahost Forums on February 5th, 2005.I’m sure all of you must have come across the term DHCP – anyone who’s connects to the internet has to come across it every now and then. You see the term even on the small setup instructions leaflets that accompany the dial-up internet packages from most of the ISPs. DHCP is what allots you a unique IP address every time you dial out to your ISP. Here’s a short description of what DHCP is and what it can do straight from the Redhat Manuals.

Chapter 18. Dynamic Host Configuration Protocol (DHCP)

Dynamic Host Configuration Protocol (DHCP) is network protocol for automatically assigning TCP/IP information to client machines. Each DHCP client connects to the centrally-located DHCP server which returns that client’s network configuration including IP address, gateway, and DNS servers.

18.1. Why Use DHCP?

DHCP is useful for fast delivery of client network configuration. When configuring the client system, the administrator can choose DHCP and not have to enter an IP address, netmask, gateway, or DNS servers. The client retrieves this information from the DHCP server. DHCP is also useful if an administrator wants to change the IP addresses of a large number of systems. Instead of reconfiguring all the systems, he can just edit one DHCP configuration file on the server for the new set of IP address. If the DNS servers for an organization changes, the changes are made on the DHCP server, not on the DHCP clients. Once the network is restarted on the clients (or the clients are rebooted), the changes will take effect.

Furthermore, if a laptop or any type of mobile computer is configured for DHCP, it can be moved from office to office without being reconfigured as long as each office has a DHCP server that allows it to connect to the network.

Assumptions:

  1. You have a Linux Server up and running with DHCP pre-installed on it. This will be referred to as your DHCP Server from now on.
  2. You have another Windows 2000/XP workstation running and connected to the Linux Server. This is required to test if the DHCP is being able to allot the IP addresses properly. This will be referred to as your DHCP Client from now on.
  3. You have only ONE network card (NIC) attached to the Linux Server and it’s name according to Linux Device List is eth0.

If you are unsure about what your NIC is referred to as, type the following in a linux console: shell> ifconfig

The output you get should look similar to this:

eth0   Link encap:Ethernet  HWaddr 00:0D:88:39:D2:69
inet addr:10.19.168.5  Bcast:10.19.168.255  Mask:255.255.255.0
inet6 addr: fe80::20d:88ff:fe39:d269/64 Scope:Link
UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
RX packets:14450 errors:0 dropped:0 overruns:0 frame:0
TX packets:15310 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1539185 (1.4 Mb)  TX bytes:1763316 (1.6 Mb)
Interrupt:225 Base address:0xb800

This tells you that indeed your NIC is present and set to handle Linux networking. See if you can spot the important parameters like the Server’s NIC Hardware Address (MAC address), the Server’s alloted IP, Subnet Mask etc. They’re all grouped up in the first 2-3 lines of the output.

My server’s IP is set to 10.19.168.5 and that’s what you see on first half of the second line, along with the Broadcast Address (10.19.168.255) and Subnet Mask (255.255.255.0).

Step 1 – Editing the /etc/dhcpd.conf file

Most likely the file dhcpd.conf would not exist beforehand in you /etc directory. We’ll start with a blank file. If you want to save up on some typing, you can load up the sample configuration file that comes with linux and modify the parameters. If you have the most recent version of DHCP you’ll find the sample configuration file at /usr/share/doc/dhcp-3.0.1rc12/dhcpd.conf.sample. The location of the sample file might vary from distribution to distribution – so if you can’t find it in this directory try using the locate command to find the location of the file. A quick example of how to spot a file with locate…

shell> locate dhcpd.conf

Personally I prefer starting off with the blank file and inserting the configuration data according to my needs. So lets get on with it. Type in the following four lines at the beginning of the file…

default-lease-time 86400;
max-lease-time 86400;
ddns-update-style interim;
ignore client-updates;

A short explanation:

  • default-lease-time 86400 – This tells the DHCP server that the minimum amount of time that an IP is alloted to a client a.k.a lease, shouldn’t be less than ONE DAY (86400 seconds). One day is a good figure to keep for your default lease time. This will lease an IP address for 86400 seconds if the client host doesn’t ask for a lease over a specific time frame.
  • max-lease-time 86400 – This again, is the maximum duration for which one particular client host will have the IP alloted to it. When this period is over, the client has to re-apply for a new IP lease – and depending on the range of free IP addresses, it might be given the same IP as it had before or a new one. Be aware that once you have the server running – this process takes place with absolute transparency without any human intervention. Feel free to modify the numbers to suit your need. Normally you wouldn’t need values larger than 86400 – unless you intend to have any of your client hosts to be up and running for more than a day. Say you want it running for 2 days – change the figure to 2 x 86400 = 172800 and so. Whatever number of days you want the lease to stay, just multiply 86400 by that and put the result in. Even if the client host requests a lease time frame which is more than this – the request would be rejected and the client will receive this figure as the maximum lease time.
  • ddns-update-style interim & ignore client-updates – These two lines are required too – but we won’t delve much deeper into these parameters – except that they involve a far advanced concept involving the inner operations of the DNS Server and are REQUIRED here. So just blindly put them in.

Below this part put a few blank lines and type in the following lines…

option subnet-mask 255.255.255.0;
option broadcast-address 10.19.168.255;
option routers 10.19.168.5;
## The IP address of the name server
##
option domain-name-servers 10.19.168.5;
option domain-name "mydomain.com";

These are the global option clauses that take the form:

option <optionname> <optionvalue>

The options should be fairly self evident. The first line sets a global subnet mask for your network. The second line fixes the Broadcast address for your subnet – the DHCP Server will advertise it’s services from either this IP (10.19.168.255) or use the universal broadcast IP (255.255.255.255). The third line sets the address of your router – which in turn shows up as the Default Gateway under windows. If you don’t have one, you can comment out this line. Fourth and fifth line as you can see specifies your DNS Servers IP and your Domain Name. If you have multiple DNS Servers, say 10.19.168.5 and 10.19.168.6 – you should specify them in order of search, i.e. the statement will take this form:

option domain-name-servers  10.19.168.5  10.19.168.6;

We key in all these parameters here, because certain network services/hosts cannot be allowed to have dynamic IPs. They require fixed addresses to perform properly i.e., any hosts on the network should always be able find these services at fixed addresses.

Next we come to the Subnet Configuration part of the config file. Go ahead and type in the following…

subnet 10.19.168.0 netmask 255.255.255.0 {
	range 10.19.168.31 10.19.168.250;
}

As you can see – the first line specifies the subnet of your network and your netmask. Replace my subnet IP with that of yours. The netmask usually always is 255.255.255.0 – which means your network logically wouldn’t have more than 253 client hosts and 254 including your server. My experimental network has just one subnet. You might have many more. In case you do, you have to make another similar block on entry below this one replacing the IPs with those of your second subnet.

Next comes the clause that takes the form of…

range <startrange> <endrange>

– which specifies the IP Block or IP Pool from which addresses will be handed out to the client hosts. As you can see, I was experimenting with it, and set the start range to 10.19.168.31 and end range to 10.19.168.250 – so range of IPs alloted to my clients will start only at .31 and upto a maximum of .250.

You can repeat the option statements that we used earlier inside this subnet {} block too – in case, you want this subnet to have a different set of dns/router/domain etc. The “options” specified earlier in the file are global and will affect any subnet which doesn’t have it’s own set of option clauses.

This brings us to the last part of the configuration file. Whatever we’ve put in so far is enough to get your DHCP Server up and running – but in some special cases, you need to tell the server to allot a fixed IP to a certain system. This is possible by setting up a matching list of IPs and Hardware MAC Addresses of those systems. Say I have my own development WorkStation and a friend’s system called Tony who joins my network regularly. So the config options to be entered are…

# Assign fixed address to certain hosts based
# on NIC Address

# My Development Workstation
host workstation {
	hardware ethernet
	00:11:2F:47:54:F2;
	fixed-address 10.19.168.50;
}

# Tony's Computer
host tony {
	hardware ethernet
	00:0A:5E:24:24:0E;
	fixed-address 10.19.168.60;
}

# Networked Laser Printer
host laser-printer {
	hardware ethernet 08:00:2b:4c:59:23;
	fixed-address 10.19.168.100;
}

Once again this part should be self evident:

  • host <hostname>clause specifies the host for which I’m going to fix a specific IP address.
  • hardware ethernet and 00:11:2F:47:54:F2 together specify the MAC address of the client hosts.
  • fixed-address 10.19.168.50; tells the DHCP Server to allot only this IP against that particular MAC address.

I’ve defined two systems here – but you are allowed to add in as many systems as you want. I’ve also got a networked laser printer which you can see defined in the third block.

Be aware though – with every fixed MAC Address/IP combination you specify here, you IP Pool or IP Range that you specified for your subnet will get shorter by one free IP. In effect, if you’d specified around 250 hosts here manually – the whole IP Pool will be exhausted. In case some new system connects to your network – it wouldn’t be able to receive any free IPs. Besides if any of the client hosts has a malfunctioning NIC which has to be replaced – you’ll have to come back here and change the respective entry for its MAC address here and set it to the new one.

Be very careful about the Opening and Closing Braces {} – if you miss out on any one of them the DHCP server will fail to start. If possible, use a GUI based editor with brace-matching, which helps to a considerable degree here.

There’s something I forgot to mention though. Since these fixed IP specifications are for clients who are part of your subnet, this whole section should be enclosed within the subnet 10.19.168.0 netmask 255.255.255.0 {} declaration right after the line where you specify the IP Pool range (range 10.19.168.31 10.19.168.250;). If you are still unsure where to include this – see the attached sample config file and you’ll know right away.

Save the file and quit 🙂

Step 2 – Editing the /etc/rc.d/init.d/dhcpd file

This is the file that actually starts up the DHCP Daemon during boot time, which in turn reads the configuration options from the dhcpd.conf in the /etc folder. This file is almost fully configured beforehand and we have to make only a few minor modifications. Scroll down till you come upon something that looks like a subroutine named start(). It should look like this:

start() {
	# Start daemons.
	echo -n $"Starting $prog: "

Below the second line with the “echo” add the following two lines…

start() {
	# Start daemons.
	echo -n $"Starting $prog: "
	/sbin/route add -host 255.255.255.255 dev eth0 2> /dev/null
	daemon /usr/sbin/dhcpd eth0
	#daemon /usr/sbin/dhcpd ${DHCPDARGS}
	...
	...
}

The /sbin/route add -host 255.255.255.255 dev eth0 2> /dev/null sets up the DHCP Broadcast address to the global broadcast address of 255.255.255.255 and binds it to your primary NIC [b]eth0[/b]. Your system now knows that DHCP will broadcast its presence using this IP through your primary NIC.

The second line daemon /usr/sbin/dhcpd eth0 is the actual command that starts your DHCP Server and tells it to listen on eth0 – which again, is your primary NIC. When you edit this file, you’ll probably see the third commented out line already present. You can either comment it out and insert the second line manually – or modify the same line and remove the ${DHCPDARGS} variable and put in eth0 there instead.

Next scroll a little further down till you get to another similar sub routine titled stop(). Once again add the following line as shown…

stop() {
	# Stop daemons.
	echo -n $"Shutting down $prog: "
	/sbin/route del -host 255.255.255.255 dev eth0 2> /dev/null
	...
	...
}

You have to add only the /sbin/route del -host 255.255.255.255 dev eth0 2> /dev/null line here which tells you system to stop broadcasting DHCP upon shutdown of the service and unhooks it from the global broadcast address.

That’s it. Save the file and quit.

We are now ready to start the DHCP server and put it to test. But before you do that there’s one last step that you got to perform. The DHCP Server stores all its lease information in a file called /var/lib/dhcp/dhcpd.leases by default. This file wouldn’t exist when you start the server – and on some systems, depending on the version of DHCP you are using it might spit out some error and cause DHCP to halt. Creating a blank file with that name solves the problem. We’ll just go ahead and do it anyway whether the file exists or not. So enter the following command…

shell> touch /var/lib/dhcp/dhcpd.leases

…and we are done.

Step 3 – Starting the DHCP Server

The DHCP Server can be started up in several ways. Do any of the following:

shell> /etc/rc.d/init.d/dhcpd start

OR

shell> service dhcpd start

Either way, you should get a message saying…

Starting dhcpd:       [  OK  ]

…which means all has gone well and your server is working fine.

Step 4 – Starting your Windows System to check if DHCP is working properly

Boot up your windows system and go to the Network and Dial-up Connections Panel. Right-click Local Area Connection and click on Properties. Then double-click on Internet Protocol (TCP/IP) and in the panel that comes up, make sure that the radio buttons next to Obtain an IP address automatically and Obtain DNS Server address automatically are both checked. If they are NOT, select them and click OK. Next Restart your system.

Upon next boot – open a command line console type ipconfig /all. This should print out detailed information about your Network Card (NIC) and your present IP address. In my case, I booted up my development workstation – which if you recall from dhcpd.conf was set to have an IP address of 10.19.168.50 based on my hardware MAC address. That’s what I found my workstation to have. And if you didn’t allot fixed IP to any system, you’d find you Windows machine to have taken up the first free IP in your IP Pool, once again, the range of which was specified in the dhcpd.conf.

One last cross-check that you can do – is to get back to your Linux Server and open the /var/lib/dhcp/dhcpd.leases file and view its content. It was blank when you created it – but now it should contain an entry corresponding to your Windows system(s) and should look like this…

lease 10.19.168.50 {
	starts 2 2005/02/01 20:03:10;
	ends 3 2005/02/02 08:03:10;
	hardware ethernet 00:11:2F:47:54:F2;
	uid 01:00:00:e8:4c:5d:31;
	client-hostname "WorkStation";
}

That’s about it. Good luck and have fun. If you’ve any questions about any of the steps shown here, feel free to leave a comment 🙂