5. Kea Configuration

Kea uses JSON structures to represent server configurations. The following sections describe how the configuration structures are organized.

5.1. JSON Configuration

JSON is the notation used throughout the Kea project. The most obvious usage is for the configuration file, but JSON is also used for sending commands over the Management API (see Management API) and for communicating between DHCP servers and the DDNS update daemon.

Typical usage assumes that the servers are started from the command line, either directly or using a script, e.g. keactrl. The configuration file is specified upon startup using the -c parameter.

5.1.1. JSON Syntax

Configuration files for the DHCPv4, DHCPv6, DDNS, Control Agent, and NETCONF modules are defined in an extended JSON format. Basic JSON is defined in RFC 7159 and ECMA 404. In particular, the only boolean values allowed are true or false (all lowercase). The capitalized versions (True or False) are not accepted.

Even if the JSON standard (ECMA 404) does not require JSON objects (i.e. name/value maps) to have unique entries Kea implements them using a C++ STL map with unique entries so:

  • if there are multiple values for the same name in an object/map the last value overwrites previous values
  • configuration file parsers since Kea 1.9.0 version raise a syntax error in such cases

Kea components use an extended JSON with additional features allowed:

  • shell comments: any text after the hash (#) character is ignored.
  • C comments: any text after the double slashes (//) character is ignored.
  • Multiline comments: any text between /* and */ is ignored. This commenting can span multiple lines.
  • File inclusion: JSON files can include other JSON files by using a statement of the form <?include “file.json”?>.

The configuration file consists of a single object (often colloquially called a map) started with a curly bracket. It comprises only one of the “Dhcp4”, “Dhcp6”, “DhcpDdns”, “Control-agent”, or “Netconf” objects. It is possible to define additional elements but they will be ignored.

A very simple configuration for DHCPv4 could look like this:

# The whole configuration starts here.
{
    # DHCPv4 specific configuration starts here.
    "Dhcp4": {
        "interfaces-config": {
            "interfaces": [ "eth0" ],
            "dhcp-socket-type": "raw"
        },
        "valid-lifetime": 4000,
        "renew-timer": 1000,
        "rebind-timer": 2000,
        "subnet4": [{
           "pools": [ { "pool": "192.0.2.1-192.0.2.200" } ],
           "subnet": "192.0.2.0/24"
        }],

       # Now loggers are inside the DHCPv4 object.
       "loggers": [{
            "name": "*",
            "severity": "DEBUG"
        }]
    }

# The whole configuration structure ends here.
}

More examples are available in the installed share/doc/kea/examples directory.

Note

The “Logging” element is removed in Kea 1.6.0 and its contents (the “loggers” object) moved inside the configuration objects (maps) for the respective Kea modules. For example: the “Dhcp4” map contains the “loggers” object specifying logging configuration for the DHCPv4 server. Backward compatibility is maintained until Kea 1.7.10 release; it will be possible to specify the “Logging” object at the top configuration level and “loggers” objects at the module configuration level. Finally, support for the top-level “Logging” object was removed in Kea 1.7.10.

The specification for supporting several elements (e.g. “Dhcp4”, “Dhcp6”) in one file has been removed in Kea 1.7.10, so that each component requires one separate configuration file.

To avoid repetition of mostly similar structures, examples in the rest of this guide will showcase only the subset of parameters appropriate for a given context. For example, when discussing the IPv6 subnets configuration in DHCPv6, only subnet6 parameters will be mentioned. It is implied that the remaining elements (the global map that holds Dhcp6) are present, but they are omitted for clarity. Usually, locations where extra parameters may appear are denoted by an ellipsis (…).

5.1.2. Comments and User Context

You can specify shell, C or C++ style comments in the JSON configuration file if you use the file locally. This is convenient and works in simple cases where your configuration is kept statically using local file. However, since comments are not part of JSON syntax, most JSON tools will detect them as errors. Another problem with them is once Kea loads its configuration, the shell, C and C++ style comments are ignored. If you use commands such as config-get or config-write, those comments will be lost. An example of such comments has been presented in the previous section.

Historically, to address the problem Kea code allowed to put comment strings as valid JSON entities. This had the benefit of being retained through various operations (such as config-get) or allowed processing by JSON tools. An example JSON comment looks like this:

"Dhcp4": {
    "subnet4": [{
        "subnet": "192.0.2.0/24",
        "pools": [{ "pool": "192.0.2.10 - 192.0.2.20" }],
        "comment": "second floor"
    }]
}

However, users complained that the comment is only a single line and it’s not possible to add any other information in more structured form. One specific example was a request to add floor levels and building numbers to subnets. This was one of the reasons why the concept of user context has been introduced. It allows adding arbitrary JSON structure to most Kea configuration structures. It has a number of benefits compared to earlier approaches. First, it is fully compatible with JSON tools and Kea commands. Second, it allows storing simple comment strings if you want to, but it can store much more complex data, such as multiple lines (as string array), extra typed data (such as floor numbers being actual numbers) and more. Third, the data is exposed to hooks, so it’s possible to develop third party hooks that take advantage of that extra information. An example user context would look like this:

"Dhcp4": {
    "subnet4": [{
        "subnet": "192.0.2.0/24",
        "pools": [{ "pool": "192.0.2.10 - 192.0.2.20" }],
        "user-context": {
            "comment": "second floor",
            "floor": 2
        }
    }]
}

User contexts can store an arbitrary data file as long as it has valid JSON syntax and its top-level element is a map (i.e. the data must be enclosed in curly brackets). However, some hook libraries may expect specific formatting; please consult the specific hook library documentation for details.

In a sense the user context mechanism has superseeded the JSON comment capabilities. ISC would like to encourage people to use user-context in favor of the older mechanisms and we hope to deprecate JSON comments one day in the future. To promote this way of storing comments, Kea code is able to understand JSON comments, but converts them to user context on the fly. The comments entries in user-context were converted back to JSON comments to keep backward compatibility, but that conversion went away in version 1.7.9.

The is one side effect, however. If your configuration uses the old JSON comment, the config-get command will return a slightly modified configuration. Don’t be surprised if you call config-set followed by a config-get and receive a slightly different structure. If this bothers you, the best way to avoid this problem is simply abandon JSON comments and start using user-context.

For a discussion about user context used in hooks, see User Contexts in Hooks.

5.1.3. Simplified Notation

It is sometimes convenient to refer to a specific element in the configuration hierarchy. Each hierarchy level is separated by a slash. If there is an array, a specific instance within that array is referenced by a number in square brackets (with numbering starting at zero). For example, in the above configuration the valid-lifetime in the Dhcp4 component can be referred to as Dhcp4/valid-lifetime and the pool in the first subnet defined in the DHCPv4 configuration as Dhcp4/subnet4[0]/pool.

5.2. Kea Configuration Backend

5.2.1. Applicability

Kea Configuration Backend (abbreviated as CB) is a feature first introduced in the 1.6.0 release, which provides Kea servers with the ability to manage and fetch their configuration from one or more databases. In the documentation, the term “Configuration Backend” may also refer to the particular Kea module providing support to manage and fetch the configuration information from the particular database type. For example: MySQL Configuration Backend is the logic implemented within the “mysql_cb” hooks library which provides a complete set of functions to manage and fetch the configuration information from the MySQL database.

In small deployments, e.g. those comprising a single DHCP server instance with limited and infrequently changing number of subnets, it may be impractical to use the CB as a configuration repository because it requires additional third-party software to be installed and configured - in particular the MySQL server and MySQL client. Once the number of DHCP servers and/or the number of managed subnets in the network grows, the usefulness of the CB becomes obvious.

A good example of a use case for the CB is a pair of Kea DHCP servers which can be configured to support High Availability as described in ha: High Availability. The configurations of both servers (including the value of the server-tag parameter) are almost exactly the same. They may differ by the server identifier and designation of the server as a primary or standby (or secondary). They may also differ by the interfaces configuration. Typically, the subnets, shared networks, option definitions, global parameters are the same for both servers and can be sourced from a single database instance to both Kea servers.

Using the database as a single source of configuration for subnets and/or other configuration information supported by the CB has the advantage that any modifications to the configuration in the database are automatically applied to both servers.

Another case when the centralized configuration repository is desired is in deployments including a large number of DHCP servers, possibly using a common lease database to provide redundancy. New servers can be added to the pool frequently to fulfill growing scalability requirements. Adding a new server does not require replicating the entire configuration to the new server when a common database is used.

Using the database as a configuration repository for Kea servers also brings other benefits, such as:

  • the ability to use database specific tools to access the configuration information,
  • the ability to create customized statistics based on the information stored in the database, and
  • the ability to backup the configuration information using the database’s built-in replication mechanisms.

5.2.2. CB Capabilities and Limitations

Kea CB, introduced in the 1.6.0 release, comes with a number of limitations as a result of the overall complexity of this feature and the development time constraints. This feature will evolve over time and the new capabilities will be added in subsequent releases. In this section we present the capabilities and limitations of the CB in the Kea 1.6.0 release:

  • Kea CB is supported for the MySQL database only.
  • Kea CB is only supported for DHCPv4 and DHCPv6 servers. Neither the Control Agent nor the D2 daemon can be configured via the database.
  • Potential configurations to be stored for the DHCP servers include: global parameters, option definitions, global options, shared networks, and subnets. Other configuration parameters are not stored in the database and must be configured via the JSON configuration file.

Note

Kea CB stores data in a MySQL schema that is public. It’s possible to insert configuration data into the MySQL tables manually, or automatically using SQL scripts, but this requires a reasonably good knowledge of SQL and the schema. The supported method for managing the data is through our cb-cmds hook library which provides management commands for config backends. It simplifies many typical operations, such as listing, adding, retrieving, and deleting of global parameters, shared networks, subnets, pools, options, and option definitions. In addition, it provides essential business logic that ensures logical integrity of the data. For a complete list, see commands starting with “remote-” in Appendix A of the Kea Administrator Reference Manual. The cb_cmds hooks library is available to subscribers only. If you are not a subscriber and would like to subscribe, please contact info@isc.org and our sales team will assist you.

The schema creation script can be found here dhcpdb_create.mysql and we have some related design documents in gitlab CB Design.

Note

We strongly recommend against duplication of the configuration information in the file and the database. For example, when specifying subnets for the DHCP server, please store them in either the configuration backend or in the configuration file, not both. Storing some subnets in the database and others in the file may put you at risk of potential configuration conflicts. Note that the configuration instructions from the database take precedence over instructions from the file, so it is possible that parts of the configuration specified in the file may be overridden if contradicted by information in the database.

Note

It is recommended that the subnet_cmds hooks library not be used to manage the subnets when the configuration backend is used as a source of information about the subnets. The subnet_cmds hooks library modifies the local subnets configuration in the server’s memory, not in the database. Use the cb_cmds hooks library to manage the subnets information in the database instead.

5.2.3. CB Components

In order to use the Kea CB feature, the Kea 1.6.0 version or later is required. The mysql_cb open source hooks library implementing the Configuration Backend for MySQL must be compiled and loaded by the DHCP servers. This hooks library is compiled when the --with-mysql configuration switch is used during the Kea build. The MySQL C client libraries must be installed, as explained in DHCP Database Installation and Configuration.

Note

Any existing MySQL schema must be upgraded to the latest schema required by the particular Kea version using the kea-admin tool, as described in The kea-admin Tool.

The cb_cmds premium hooks library, which is available to ISC’s paid support customers, provides a complete set of commands to manage the servers’ configuration information within the database. This library can be attached to both DHCPv4 and DHCPv6 server instances. It is still possible to manage the configuration information without the cb_cmds hooks library with commonly available tools, such as MySQL Workbench or the command-line MySQL client, by directly working with the database.

Refer to cb_cmds: Configuration Backend Commands for the details regarding the cb_cmds hooks library.

The DHCPv4 and DHCPv6 server-specific configurations of the CB, as well as the list of supported configuration parameters, can be found in Configuration Backend in DHCPv4 and Configuration Backend in DHCPv6 respectively.

5.2.4. Configuration Sharing and Server Tags

The configuration database is designed to store the configuration information for multiple Kea servers. Depending on the use case, the entire configuration may be shared by all servers, parts of the configuration may be shared by multiple servers and the rest of the configuration may be different for these servers or, finally, each server may have its own non-shared configuration.

The configuration elements in the database are associated with the servers by “server tags”. The server tag is an arbitrary string holding the name of the Kea server instance. The tags of the DHCPv4 and DHCPv6 servers are independent in the database, i.e. the same server tag can be created for the DHCPv4 and the DHCPv6 server respectively. The value is configured using server-tag parameter in the Dhcp4 or Dhcp6 scope. The current server-tag can be checked with the server-tag-get command.

The server definition, which consists of the server tag and the server description, must be stored in the configuration database prior to creating the dedicated configuration for that server. In cases when all servers use the same configuration, e.g. a pair of servers running as the High Availability peers, there is no need to configure the server tags for these servers in the database. The database by default includes the logical server all, which is used as a keyword to indicate that the particular piece of configuration must be shared between all servers connecting to the database. The all server can’t be deleted or modified. It is not even returned among other servers as a result of the remote-server[46]-get-all commands. Also, slightly different rules may apply to “all” keyword than to any user defined server when running the commands provided by the cb_cmds hooks library cb_cmds: Configuration Backend Commands.

In the simplest case there are no server tags defined in the configuration database and all connecting servers will get the same configuration regardless of the server tag they are using. The server tag that the particular Kea instance presents to the database to fetch its configuration is specified in the Kea configuration file, using the config-control map (please refer to the Enabling Configuration Backend and Enabling Configuration Backend for details).

All Kea instances presenting the same server tag to the configuration database are given the same configuration. It is the administrator’s choice whether multiple Kea instances use the same server tag or each Kea instance is using a different sever tag. Also, there is no requirement that the instances running on the same physical or virtual machine use the same server tag. It is even possible to configure the Kea server without assigning it a server tag. In such case the server will be given the configuration specified for “all” servers.

In order to differentiate the configurations between the Kea servers, a collection of the server tags used by the servers must be stored in the database. For the DHCPv4 and DHCPv6 servers, it can be done using the commands described in remote-server4-set, remote-server6-set commands and remote-server4-set, remote-server6-set commands. Next, the server tags can be used to associate the configuration information with the servers. However, it is important to note that some DHCP configuration elements may be associated with multiple server tags and other configuration elements may be associated with exactly one server tag. The former configuration elements are referred to as shareable configuration elements and the latter are referred to as non-shareable configuration elements. The Configuration Backend in DHCPv4 and Configuration Backend in DHCPv6 list the DHCP specific shareable and non-shareable configuration elements. However, in this section we want to briefly explain the difference between them.

The shareable configuration element is the one having some unique property identifying it and which instance may appear only once in the database. An example of the shareable DHCP element is a subnet instance. The subnet is a part of the network topology and we assume that the particular subnet may have only one definition within this network. The subnet has two unique identifiers: subnet id and the subnet prefix. The subnet identifier is used in Kea to uniquely identify the subnet and to connect it with other configuration elements, e.g. in host reservations. The subnet identifier uniquely identifies the subnet within the network. Some commands provided by the cb_cmds hooks library allow for accessing the subnet information by subnet identifier (or prefix) and explicitly prohibit using the server tag to access the subnet. This is because, in a general case, the subnet definition is associated with multiple servers rather than single server. In fact, it may even be associated with no servers (unassigned). Still, the unassigned subnet has an identifier and prefix which can be used to access the subnet.

A shareable configuration element may be associated with multiple servers, one server or no servers. Deletion of the server which is associated with the shareable element does not cause the deletion of the shareable element. It merely deletes the association of the deleted server with the element.

Unlike the shareable element, the non-shareable element must not be explicitly associated with more than one server and must not exist after the server is deleted (must not remain unassigned). The non-shareable element only exists within the context of the server. An example of the non-shareable element in DHCP is a global parameter, e.g. renew-timer. The renew timer is the value to be used by the particular server and only this server. Other servers may have their respective renew timers set to the same or different value. The renew timer is the parameter which has no unique identifier by which it could be accessed, modified or otherwise used. The global parameters like the renew timer can be accessed by the parameter name and the tag of the server for which they are configured. For example: the commands described in The remote-global-parameter4-get, remote-global-parameter6-get Commands allow for fetching the value of the global parameter by the parameter name and the server name. Getting the global parameter only by its name (without specifying the server tag) is not possible because there may be many global parameters with the given name in the database.

When the server associated with a non-shareable configuration element is deleted, the configuration element is automatically deleted from the database along with the server because the non-shareable element must be always assigned to some server (or the logical server “all”).

The terms “shareable” and “non-shareable” only apply to the associations with user defined servers. All configuration elements associated with the logical server “all” are by definition shareable. For example: the renew-timer associated with “all” servers is used by all servers connecting to the database which don’t have their specific renew timers defined. In the special case, when none of the configuration elements are associated with user defined servers, the entire configuration in the database is shareable because all its pieces belong to “all” servers.

Note

Be very careful when associating the configuration elements with different server tags. The configuration backend doesn’t protect you against some possible misconfigurations that may arise from the wrong server tags’ assignments. For example: if you assign a shared network to one server and the subnets belonging to this shared network to another server, the servers will fail upon trying to fetch and use this configuration. The server fetching the subnets will be aware that the subnets are associated with the shared network but the shared network will not be found by this server as it doesn’t belong to it. In such case, both the shared network and the subnets should be assigned to the same set of servers.