05.04.2019 linux dhcp

DHCP on Linux using isc-dhcp

In this tutorial I show you how to build a DHCP server on your RasPi, to get the caching/forwarding DNS from my previous tutorial working automatically.

Devices

In my private network at home, I have essentially 5 devices right now:

  • 1 Router
  • 1 NAS
  • 1 Raspberry Pi
  • 1 Computer
  • 1 Phone

Pretty standard setup I’d say, for a single into networking and IT and standard in terms of amount of devices. I am not using anything smart home.

I am using the 10.10.10.0 /24 subnet. You don’t have to, 192.168.0.0 /24 works for most people, but I find the other subnet easier to type. That is really the only reason I am using it. After shits and giggles, which is actually a very valid reason. With that being said, let’s plan our network:

DEVICETYPE
Computerdynamic
NASstatic
Phonedynamic
Routerstatic
Tabletdynamic

So, in my network, I have only 2 devices that need a static IP and only can actually receive one via DHCP. The router only accepts direct input, but not DHCP, since it comes with it’s own DHCP server. So does my NAS, btw. So, theoretically, I have already 2 DHCP servers in my network. However, the router DHCP is very limited and does not even allow DNS to be set by myself and the Synology NAS can’t do IPV6 DHCP, if only for the DHCP options.

Understanding DHCP

There are a couple of things you need to understand about DHCP:

1.) How a DHCP request works

When a computer has no IP, it has another address, the so called MAC address. That is a 48 bit long unique identifier that is in the chip of your network card. One can change it, but not on the hardware, only in software, but in general, you should consider it being unchangeable.

So, now we know that a network interface without an IP still has an address. The first thing any networking capable device will do, is to just send a request into the network to ALL clients. Literally everyone. It can do that by sending a request to the MAC address FF:FF:FF:FF:FF:FF. That is the so called broadcast address. The message will contain a request for the DHCP server to identify itself. And it will do so by responding with a packet that contains it’s MAC address. I could go into great details, because it generates quite some traffic, but they talk a while until they have settled on an IP the client can use. Then the client network driver (OSI layer 7) will take that IP and set it for the interface. And voilĂ , your computer has an IP address. Like magic ;).

2.) DHCP only works in the same subnet

Well, you actually can use one DHCP server for a lot of different subnets in another subnet, but then each subnet needs a DHCP relay server, which relays the request to the other subnet. Why? Because DHCP runs on OSI layer 2 (with the answer being in Layer 7) and there are no IP on OSI layer 2, only MAC-addresses. Therefore, the request ends at the router at the latest. But, since this post is mostly targeted at SOHO and home networking, you are probably only using 1 subnet anyway.

3.) DHCP has options that aren’t mandatory

One of those options is the DNS servers that I want to give to my devices, to utilize my Raspberry as DNS. There are plenty of others and the good folks over at IANA have done a fine job compiling them. What I am trying to say is, only use those that you actually need and understand, because some of them can really screw up your network.

Installing isc-dhcp-server

One of the DHCP servers available on Linux is isc-dhcp-server. You can install easily by typing sudo apt install isc-dhcp-server. This will install the software and we can get configuring.

Static IP

Since the device running that server cannot set an IP for itself, because it is the DHCP server, we need a static IP. If you followed my last tutorial , you already know how to do that. You can set it by editing /etc/dhcpcd.conf with nano or vim and entering the following:

interface eth0

static ip_address=192.168.1.252/24
static routers=192.168.1.254
static domain_name_servers=192.168.1.252

You need to adjust the IP addresses and network interfaces to your own of course and I have omitted the IPV6 addresses this time, for the sake of this tutorial. You can get the interface identifier by typing ip a on a RasPi and entering it into the first line. static ip_address is the address you want your Pi to have and static routers is called gateway in Windows and is what it says: Your router.

Config file

This is going to be a big one, so let’s get cracking:

# lease time
default-lease-time 600;
max-lease-time 7200;

# My Network
subnet 10.10.10.0 netmask 255.255.255.0{

        range 10.10.10.10 10.10.10.200;

        option routers 10.10.10.254;
        option domain-name-servers 10.10.10.252;
        option ntp-servers 10.10.10.252;

        host nas{
                hardware ethernet 00:00:00:00:00:00;
                fixed-address 10.10.10.253;
        }

} # End Network

Let’s examine it step-by-step, shall we?

Lease time

# lease time
default-lease-time 600;
max-lease-time 7200;

The lease time tells the server in seconds how long the IP address is reserved, after a device is finished using it. Finished means, it is turned off or outside the subnet. It will never expire if a device is still online, because at half the time, the device will send a request to extend the lease. So, if you set this really low, you may generate a lot of unnecessary traffic on your network, depending on the number of devices. So be careful about it and set reasonable times.

Subnet declaration

subnet 10.10.10.0 netmask 255.255.255.0{
}

This line declares the subnet we are using. You may notice the .0 at the end of the IP. For those not familiar with it, that is the ID of the network. It is the first IP in a subnet. Since we have a subnet of /24, meaning the whole last octet is available for hosts or in simpler words, devices, the first IP is 0 and that is our ID. It cannot be used for devices and most will reject if you try to set it. The last address in a subnet, .255 is reserved for broadcasts on the IP layer. It is the same as the broadcast I was explaining above, just on a different OSI layer. All things written inside the brackets will only affect this subnet.

The range

range 10.10.10.10 10.10.10.200;

This tells the DHCP in what range of our subnet he is allowed to choose IP addresses from. The first device that connects, will get an address within that range, however, it is no guaranteed that the first device will actually get .10. It may end up with .20, just because the server feels like using that. The exact algorithm is unknown to me and of no consequence to us. I have decided that all static IP go between one and ten and DHCP between .10 and .200. Everything over .200 is a network service in my network.

DHCP options

option routers 10.10.10.254;
option domain-name-servers 10.10.10.252;
option ntp-servers 10.10.10.252;

Those are the mysterious DHCP options I have been talking about. The first line is the address of my router. In the second, I set my RasPi as a DNS server. Only do this if you have been following the Raspberry caching/forwarding DNS Tutorial ! The third option sets my RasPi as the NTP server. NTP is a time protocol and sets the time in devices. Yes, you can actually do this in Windows and Windows will follow the DHCP entry. Quite neat actually :).

Static entries

host nas{
        hardware ethernet 00:00:00:00:00:00;
        fixed-address 10.10.10.253;
}

Sometimes you want devices to have a static IP, like my NAS. This is how you do it. The name after host, in my case nas, can be set freely. Then you need to put in the MAC address as shown here. Windows displays the MAC when calling ipconfig /all with dashes, but the isc-dhcp-server expects double colons. Unfortunately, there is no standard how MAC’s shall be displayed, so if you copy it from Windows, don’t forget editing it. The second line simply tells the server that the device with that MAC is to be given exactly that IP. You can extend that list at your leisure, you may even only allow known clients by setting deny unknown-clients; inside the brackets of the subnet. Then it will only give clients listed here an address.

Restarting the service

The last thing you need to do, is to restart the service, so the server accepts the new configuration. You can that sudo service isc-dhcp-server restart on your terminal. After that, the config should be good to go and your devices will now receive DHCP addresses from our newly configured DHCP server.

Conclusion

Today you have learned how to set up a DHCP server for IPV4 all by yourself, without flashy interfaces, by just editing text files. You should be proud of yourself! Understanding this essential service is a good step towards more freedom and how you address your network, if you do anything beyond just plugging it in. Have fun and keep a lookout for more tutorials. Send any comments or errata to contact@tuxstash.de. Thanks for reading.

Link to the author's twitter Link to the authors ko-fi page

comments

Characters: 0/1000

gravatar portrait

 Pinned by contact@tuxstash.de

Come join the discussion and write something nice. You will have to confirm your comment by mail, so make sure it is legit and not a throwaway. Only the name part of it will be displayed, so don't worry about spam. If it does not show up after confirming it, it may be considered spam, but I curate them manually, so don't worry. Please read the privacy statement for more.