Technology

Install ISC DHCP on macOS Catalina

In late-2018, Apple stopped bundling a host of open-source software into macOS Server. Since then, I’ve seen a spike in hits on a post from 2011, Install ISC DHCP on Mac OS X Server. That post should still be relevant up to at least Mac OS X El Capitan (10.11), which is where the Mac mini hardware I have running ISC DHCP has remained, dutifully handing out IP addresses across our network.

While those Mac minis have been rock solid, they are aging. So when a pair of fairly new Mac minis decommissioned and no longer needed for their original purpose, I took the opportunity to install macOS Catalina on them, and revisit installing ISC DHCP. I have documented that process here, which hasn’t changed much.

Requirements

A Mac running macOS Catalina, with Xcode (and the Xcode Command Line Tools) installed.

Note: I see no reason this should not work for macOS Sierra 10.12- Mojave 10.14, but I did all my testing on a clean install of the latest release of macOS Catalina 10.15.3. So if you’re using a version other than that, you’re on your own.

Download & Install ISC DHCP Software

With macOS Catalina and Xcode are installed, download the ISC DHCP software. There are various ways to do this, personally I find it easiest to just visit the ISC DHCP webpage, download the latest version of software, then double-click to extract it. Or, if you’re a command line nerd like me, you can also use cURL.

In this case, I just downloaded ISC DHCP 4.4.2 from their website, because I did not want to take the time to track down the URL to download the latest version using cURL. Once downloaded, I moved the dhcp-4.4.2.tar file to my desktop (just to make life easier), and double-clicked on it to expand the tar archive.

With the tar archive unpacked, navigate into the extracted folder on your desktop…

  cd ~/Desktop/dhcp-4.4.2/

Once inside the uncompressed folder, run the following three commands, one at a time, to build and install the ISC DHCP software…

  ./configure

  make

  sudo make install
 

Each of those will output lot of information, just be patient and look for major errors. Once they complete successfully, that’s it…the ISC DHCP software has been successfully installed. You can find the dhcpd daemon is installed in /usr/local/sbin/.

Configure ISC DHCP

Now the fun of configuring dhcpd can begin. First, you will need to configure an /etc/dhcpd.conf file. With ISC DHCP 4.4.2, you will find a sample configuration file at /usr/local/etc/dhcpd.conf.example. Either copy that file to, or create a new one in /etc/.

To copy the example configuration file, run the following command in Terminal…

  sudo cp /usr/local/etc/dhcpd.conf.example /etc/dhcpd.conf

Or, to create a new, empty dhcpd.conf file, run the following command…

  sudo touch /etc/dhcpd.conf

Below is a commented example of a dhcpd.conf file. There are many, many, many settings to choose from, so I cannot possibly cover them all here. I would highly recommend reading through the dhcpd man pages, but these are the basics…

# EXAMPLE DHCPD.CONF FILE FOR ISC DHCP
# /etc/dhcpd.conf
#
# NECESSARY TO BE A DHCP SERVER
     authoritative;
     ddns-update-style none;
# DHCP CONFIGURATION INFORMATION
     default-lease-time 43200;
     max-lease-time 86400;
     server-name "dhcpserver.domain.com";
# DNS SERVERS DHCP WILL PUSH TO CLIENTS
     option domain-name-servers 10.0.1.1, 10.0.1.2;
# SEARCH DOMAINS DHCP WILL PUSH TO CLIENTS
     option domain-name "domain.com";
# DHCP STATIC IP ASSIGNMENTS FILE
     include "/etc/dhcpd/master.conf";
#
################## [ IP SUBNETS ] ##################
# SUBNET01 - IP ADDRESSES MANUALLY/STATICALLY ASSIGNED ONLY
subnet 10.0.1.0 netmask 255.255.255.0 {
     option broadcast-address 10.0.1.255;
     option subnet-mask 255.255.255.0;
     option routers 10.0.1.254;
}
# SUBNET02 - IP ADDRESSES DYNAMICALLY/STATICALLY ASSIGNED
subnet 10.0.2.0 netmask 255.255.254.0 {
     option broadcast-address 10.0.3.255;
     option subnet-mask 255.255.254.0;
     option routers 10.0.3.254;
     pool { range 10.0.2.1 10.0.3.254; }
}

The subnet of your DHCP server’s IP address MUST be included in the dhcpd.conf file, otherwise dhcpd will be very unhappy, and will not start.

Note the following lines in the dhcpd.conf file…

# DHCP Static Assignments configuration file
     include "/etc/dhcpd/master.conf";

This allows you to keep your static IP assignments in a file separate from the primary configuration file. This is quite nice as you are not editing the primary configuration file every time you want to add/change/remove a static IP assignment. So there is less chance you accidentally edit something you didn’t mean to, and break DHCP. Here is a brief sample of the master.conf file for static IP assignments…

# EXAMPLE STATIC IP CONFIG FILE FOR DHCP
# CONTAINS ALL STATIC IP ASSIGNMENTS
# /etc/dhcpd/master.conf
#
# STATIC IP ASSIGNMENTS
############################################
## SUBNET01 - 10.0.1.0/24
############################################
host device1 { hardware ethernet 12:34:56:ab:cd:ef; fixed-address 10.0.1.1; }
host device2 { hardware ethernet 12:23:34:ab:bc:cd; fixed-address 10.0.1.2; }
#
############################################
## SUBNET02 - 10.0.2.0/23
############################################
host device3 { hardware ethernet 13:57:91:ab:cd:ef; fixed-address 10.0.2.1; }
host device4 { hardware ethernet 02:46:80:ab:cd:ef; fixed-address 10.0.2.25; }
host device5 { hardware ethernet 13:24:35:46:57:68; fixed-address 10.0.3.100; }

Once you have your dhcpd.conf and master.conf file setup, you will need to create the leases file, otherwise dhcpd will not run. In Terminal, run the following command…

  sudo touch /var/db/dhcpd.leases

Start dhcpd & Test

You can now start up dhcpd and begin testing your configuration. In Terminal, type the following command…

  sudo /usr/local/sbin/dhcpd -q -f

Some time ago, Apple moved to a unified logging system for macOS. For the purposes of this how-to, it means you will not find dhcpd logs in /var/log/system.log as you would have in the past. Instead, logs are in a unified, binary log system Apple has developed (and I haven’t investigated too deeply). So you have two options for checking log files that may indicate problems…

Option 1: Open the Console application, and in the search bar type “dhcpd”…this will show you the relevant logs being generated.

Option 2: In the Terminal application, and type the following command…

  sudo log stream --info --debug --predicate "process == 'dhcpd'"

…this will stream the relevant logs, similar to how a sudo tail -f /var/log/system.log would have in the past.

The log files ISC DHCP generates are typically verbose enough you can quite easily figure out what is going wrong (if something is going wrong). If everything is looking good, dhcpd is running, and no errors are being generated by the log files, you can now grab a client machine (macOS, iOS, Windows, whatever) and test to make sure you are getting an IP address from your newly configured DHCP server.

On a macOS machine, check System Preferences > Network to verify that you are in fact getting an IP address. Then, you can run the following command in Terminal to verify what DHCP server that IP address is coming…

  ipconfig getpacket en0

Note: en0 is typically the onboard ethernet interface, however, on macOS computers without onboard ethernet, en0 is the WiFi interface. If you’re using an ethernet adapter, you can go to About This Mac > System Report > Network to find the interface identifier.

In the output, you should see an sname field that will tell you the DNS name of the DHCP server your IP address is originating from. Additionally, the server_identifier (ip) field will tell you the IP address of the DHCP server. If those show the name and IP address of your newly configured DHCP server, you are golden…dhcpd is properly configured. Yay! Note, the command will also give you other relevant information that your DHCP server may be handing out, like DNS servers, default domain name, NetBIOS servers, etc.

Keep dhcpd Running with launchd

Now that we know things are running successfully, we can uselaunchd to automatically start dhcpd after rebooting your server, after a power outage, etc. It’s quite simple to implement. Below is the launchd configuration file for ISC DHCP I am using.

<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
<plist version=\"1.0\">
<dict>
     <key>Label</key>
          <string>org.isc.dhcpd</string>
     <key>OnDemand</key>
          <false/>
     <key>ProgramArguments</key>
          <array>
          <string>/usr/local/sbin/dhcpd</string>
          <string>-q</string>
          <string>-f</string>
          </array>
     <key>RunAtLoad</key>
          <true/>
     <key>ServiceDescription</key>
          <string>ISC DHCP Server</string>
</dict>
</plist>

Copy this into a file named org.isc.dhcpd.plist inside /Library/LaunchDaemons/, and then load it into launchd using launchctl. In Terminal, issue the following commands…

  sudo launchctl load /Library/LaunchDaemons/org.isc.dhcpd.plist

Test to see if the configuration file loaded into launchd…

  sudo launchctl list org.isc.dhcpd

…and/or test to see if dhcpd is running…

  ps -ax | grep dhcpd

Again, assuming no configuration errors, dhcpd should be running.

So there you have it, an ISC DHCP server is now installed and running on macOS Catalina. In the nearly 10-years I have been running this software on Mac OS X/macOS, the only time it has ever stopped working is because I fat-fingered something in the configuration. To say it’s rock-solid is an understatement, and for something as important as DHCP, that’s as good as it gets.

Now that I do have ISC DHCP running on macOS Catalina, I have also documented configuring ISC DHCP failover…for those occasions when you fat-finger something in the configuration, and your primary DHCP server stops responding. I will post a follow-up how-to on that in the coming days.