
Modern implementation of DHCP with Kea
Address Jockey
Dynamic IP address assignment by the Dynamic Host Configuration Protocol (DHCP) usually performs its service reliably. However, some implementations lack modern interfaces to connect them to existing management systems and databases. Some outdated solutions also lack functions for IPv6. The Kea project, launched in 2014, modernizes the DHCP server.
Kea was designed as a successor to the Internet Systems Consortium's open source DHCP server (ISC DHCP), which has been widely used on enterprise networks since 1999. Version 1.8.1 [1] of the DHCP server was recently released and is available for the Linux, Unix, and macOS operating systems. The service has a modular structure with, for example, separate daemons for DHCPv4 and DHCPv6, as well as for dynamic DNS registration.
The Kea server configuration relies on a JSON-based data structure. Configuration changes do not require a service restart, with the exception of an interface change, and was one of the key criteria for one of the early adopters of the project: Facebook. According to its own statements, the social media company used the predecessor, ISC DHCP, for provisioning the operating systems of bare metal servers and out-of-band management systems.
However, automated mechanisms were complex to implement with static configuration files and required frequent restarts of services to apply the changes. Additionally, extended availability requirements, as well as the dynamic connection to the internal inventory system as a "single point of truth," were additional arguments for establishing Kea as the replacement.
Highly Available and Expandable
Some optional functions can be reloaded with dynamically loaded "hook modules." Hooks written in C++ extend the range of functions, which makes it possible to keep the core of the service small, yet not limit the possible range of functions.
Moreover, the ISC provides a web-based monitoring GUI named Stork [2] that requires agents on the monitored Kea servers. Connecting Kea to SQL databases for DHCP lease data, DHCP reservations, and some configuration data also appears interesting and supports, for example, unified access from clustered DHCP servers to a lease dataset. A RESTful API offers the ability to connect to your own management systems. High availability (HA) is also feasible. In contrast to the ancient ISC DHCP, Kea also offers HA for IPv4 and IPv6. Redundancy for IPv6 is implemented according to RFC8156. In addition to two active servers, you can set up classic 1:1 redundancy and run multiple backup servers.
In the classic ISC DHCP, dividing address pools was a very flexible process. Kea can only do this in a 50/50 distribution.
Added to all these functions, Kea offers integration with RADIUS servers. For example, if a MAC address is known, the RADIUS server can suggest a specific IPv4 or IPv6 address and thus offer a quasi-RADIUS-based DHCP reservation. Alternatively, the RADIUS server can also name a specific address pool, which can be useful if dedicated sets of rules depend on certain IP addresses at other points, such as firewalls.
Installation with Dependencies
Before you install, you need to answer two crucial questions that need to be considered later in the build process: (1) Is redundancy intended? (2) Do you want to use a comma-separated values (CSV) file for the lease data or a database?
After downloading Kea, you need to compile it yourself. However, pre-built packages can be downloaded from the Cloudsmith website [3]. Some Linux distributions offer such packages through their package managers, but the versions usually are not up to date. Starting in Kea 1.6.0, you can generate a build with a Python 3 script called Hammer.py
, which is included in the Git repository.
In the example here, you will first install some dependencies, including a MySQL server that uses memfile (the simplest and fastest database back end, which uses an in-memory database and stores DHCP lease data on disk in a CSV file). MySQL, PostgreSQL, and Cassandra are supported as alternative back ends. Afterward, you will be cloning the current GitLab repository and executing the build process (Listing 1). The binaries are then stored under /usr/local/sbin
.
Listing 1: Build Process
sudo apt-get -y install liblog4cplus-dev libboost-all-dev make build-essential autoconf libtool libssl-dev mysql-server libmysqlclient-dev cd /opt/ sudo git clone https://gitlab.isc.org/isc-projects/kea.git cd kea sudo autoreconf -install sudo ./configure --with-mysql sudo make sudo make install
Preparing Logging and the Database
To define globally which modules need to be loaded by Kea and which paths will be used to access the configuration files, edit the keactrl.conf
configuration file, where you can disable the dynamic DNS service (e.g., if you do not need dynamic DNS updating on the network).
You can start and stop the service and query the current status with:
keactrl start keactrl stop keactrl status
In the respective module configuration, you can define a logging target. For DHCPv4 this would be kea-dhcp4.conf
if you do not use a different configuration file as an argument.
Now you need to initialize the MySQL database before using it the first time. The kea-admin
binary provides the db-init
argument for this purpose. I will not go into detail on the steps for granting the MySQL user permissions here. Listing 2 initializes the MySQL database and shows the created table structure.
Listing 2: MySQL Table Structure
pfister@dhcp:~# kea-admin db-init mysql -u dhcpsvc -p t0ps3cr3t -n dhcp mysql> show tables; +--------------------------------------------+ | Tables_in_dhcp | +--------------------------------------------+ | dhcp4_audit | | dhcp4_audit_revision | | dhcp4_global_parameter | | dhcp4_global_parameter_server | | dhcp4_option_def | | dhcp4_option_def_server | | dhcp4_options | | dhcp4_options_server | | dhcp4_pool | | dhcp4_server | | dhcp4_shared_network | | dhcp4_shared_network_server | | dhcp4_subnet | | dhcp4_subnet_server | | dhcp6_audit | | dhcp6_audit_revision | | dhcp6_global_parameter | | dhcp6_global_parameter_server | | dhcp6_option_def | | dhcp6_option_def_server | | dhcp6_options | | dhcp6_options_server | | dhcp6_pd_pool | | dhcp6_pool | | dhcp6_server | | dhcp6_shared_network | | dhcp6_shared_network_server | | dhcp6_subnet | | dhcp6_subnet_server | | dhcp_option_scope | | host_identifier_type | | hosts | | ipv6_reservations | | lease4 | | lease4_stat | | lease6 | | lease6_stat | | lease6_types | | lease_hwaddr_source | |lease_state | | logs | | modification | | parameter_data_type | | schema_version | +--------------------------------------------+
Creating the Initial Configuration
Among other things, the /usr/local/etc/kea
directory contains the configuration files of the modules for DHCPv4 and DHCPv6, the dynamic DNS registry, and the parameterization of the keactrl
script.
To customize the configuration, use either the configuration files or the RESTful API. The associated daemon is named Kea Control Agent, which also lets you connect to your own management systems. However, it does not provide encrypted access natively. You would have to connect a reverse proxy such as Apache or Nginx to enable encrypted management access – which is of course recommended.
After the initial configuration, start the DHCPv4 service with
keactrl start -s dhcp4
and verify the status by typing keactrl status
.
Static Config vs. Database
To begin, start with the static DHCPv4 configuration in a configuration file (Listing 3). Note that these sample configurations are not intended for production and partly include IP addresses from reserved address ranges specifically for documenting the process.
Listing 3: DHCPv4 Config File for Memfile
{ "Dhcp4": { "renew-timer": 900, "rebind-timer": 1800, "valid-lifetime": 3600, "interfaces-config": { "interfaces": ["ens33"], "dhcp-socket-type": "raw" }, "lease-database": { "type": "memfile", "persist": true, "lfc-interval": 3600 }, "option-data": [ { "name": "domain-name-servers", "data": "192.0.2.1" }, { "code": 15, "data": "lab.pfisterit.de" }, { "name": "domain-search", "data": "lab.pfisterit.de" } ], "subnet4": [ { "subnet": "192.0.2.0/24", "pools": [ { "pool": "192.0.2.20 -- 192.0.2.199" } ], "option-data":[ { "name": "routers", "data": "192.0.2.1" }], "reservations": [ { "hw-address": "1a:1b:1c:1d:1e:1f", "ip-address": "192.0.2.201" } ] } ], "loggers": [ { "name": "kea-dhcp4", "output_options": [ { "output": "/tmp/kea-dhcp4.log" } ], "severity": "WARNINGS", "debuglevel": 0 } ] } }
A DHCPv4 configuration file initially starts and ends with the outer element "Dhcp4": { }
. The individual parameters must be comma-separated cleanly to create a valid JSON file. This example first defines some timers, including timers for the maximum validity of a DHCP lease and for the extension of a lease with the previous DHCP server or with other DHCP servers. After that, it defines the interface on which a service binding will be made and determines that it accepts raw requests with dhcp-socket-type
.
Alternatively, to accept DHCP requests by a DHCP relay on the DHCP server, you could parameterize the socket type as udp
. Next, the file configures the leases database to be a memfile
type and stores it persistently in the /var/lib/kea/dhcp4.leases
directory. Next are the global DHCP options. The example defines the DNS server of the organization, the domain name, and the search domain.
Additionally, it creates a DHCP scope with the option to assign the default gateway; that is, it has set up a DHCP reservation for the MAC address 1a:1b:1c:1d:1e:1f and the IP address 192.0.2.201. The path /usr/local/var/log/kea-dhcp4.log
is used as the logging destination. The corresponding log level is set to WARNINGS
.
Figure 1 shows a DHCPv4 process in Wireshark as an example. The global DHCP option for the lab.pfisterit.de DNS domain was passed to the client in the offer from the DHCP server residing on the IPv4 address 192.168.178.194.

In contrast to the example in Listing 3, with a memfile lease database, the next example connects to a MySQL database by storing the corresponding connection parameters such as the TCP port, database name, and corresponding credentials in the configuration snippet (Listing 4).
Listing 4: IPv4 Config File for MySQL
{ "Dhcp4": { "renew-timer": 900, "rebind-timer": 1800, "valid-lifetime": 3600, "interfaces-config": { "interfaces": ["ens33"], "dhcp-socket-type": "raw" }, "lease-database": { "type": "mysql", "name": "dhcp", "host": "", "connect-timeout" : 5, "max-reconnect-tries": 5, "reconnect-wait-time": 3000, "user": "dhcpsvc", "password": "t0ps3cr3t", "port": 3306, "persist": true, "lfc-interval": 3600 }, "option-data": [ { "name": "domain-name-servers", "data": "192.0.2.1" }, { "code": 15, "data": "lab.pfisterit.de" }, { "name": "domain-search", "data": "lab.pfisterit.de" } ] , "subnet4": [ { "subnet": "192.168.178.0/24", "pools": [ { "pool": "192.168.178.20 -- 192.168.178.199" } ], "option-data":[ { "name": "routers", "data": "192.168.178.1" }], "reservations": [ { "hw-address": "1a:1b:1c:1d:1e:1f", "ip-address": "192.168.178.201" } ] } ], "loggers": [ { "name": "kea-dhcp4", "output_options": [ { "output": "/tmp/kea-dhcp4.log" } ], "severity": "WARNINGS", "debuglevel": 0 } ] } }
DHCPv6 and Data Models
The example in Listing 5 uses a dedicated configuration file for IPv6. The matching timers and interface bindings are already known from the IPv4 configuration. The central differences are recognizable in this very simple JSON example in the form of specifications for Dhcp6
instead of Dhcp4
, as well as subnet6
instead of subnet4
for the corresponding scopes.
Listing 5: IPv6 Sample Config
{ "Dhcp6": { "renew-timer": 900, "rebind-timer": 1800, "valid-lifetime": 3600, "interfaces-config": { "interfaces": ["ens33"], }, "lease-database": { "type": "memfile", "persist": true, "name": "/var/lib/kea/dhcp6.leases" }, "subnet6": [ { "subnet": "2001:db8:1::/64", "pools": [ { "pool": "2001:db8:1::5 - 2001:db8:1::ffff" } ] } ] } }
As the level of automation in the network environment increases, the YANG (Yet Another Next Generation) data model has become increasingly popular. A unified data model is particularly recommended on heterogeneous networks. Kea also offers YANG support based on the open source Sysrepo engine. To work with this data model, the NETOPEER2 NETCONF server, which is under BSD license, offers an interface for configuration adjustments.
Migration Path from ISC DHCP
Anyone who uses an existing ISC DHCP server and finds the new features interesting will now be asking themselves how they can migrate their existing configuration to Kea. A migration wizard known as KeaMA [4] is available for this purpose.
The wizard uses an existing ISC configuration file and translates it into a Kea-compatible configuration file. You need to run the process twice: once for IPv4 and once for IPv6 if you use both protocols. If you encounter any errors during the conversion, the migration wizard will offer appropriate tips. However, the tool is still considered experimental according to the GitLab page.
Conclusions
Kea offers interesting approaches and functions. However, switching from an existing ISC DHCP server to Kea needs to be well thought out and planned. If functions such as high availability for IPv6 are not used on your network and you do not need APIs for management systems, it is questionable whether a switch to Kea will offer any advantages. One argument, of course, is that switching removes the need to restart for scope changes. For data centers with a large number of configuration changes within short time intervals, Kea could be interesting. The documentation is also very useful.