Kea provides a REST API (JSON structures sent via http) and a control channel (JSON structures sent via Unix domain socket) that allows an external entity to send administrative commands to the server. This is a requirements document that describes what the implementation is expected to provide. Many of the commands listed here are already implemented. See below for color coding.
WARNING: This is a living document that is expected to evolve over multiple Kea releases. As a result, the requirements numbering may not be continuous, as obsolete requirements may be removed or new ones may be defined.
For easier understanding of what is and what is not supported, the commands are color coded. (We apologize for the inelegant color coding; if you can make it work correctly, we invite you to fix it.) The meaning is as follows:
#39e21fGreen is currently supported by either released or development version;
#1221ccBlue is implemented and is part of the add-ons ISC is offering. Getting access to those extensions involves money. See https://isc.org/kea for details;
#ea8920Orange is planned for upcoming versions;
#FF0000Red is currently not implemented and there are no specific milestones (please contact ISC if you're interested in those commands and we can talk about how we could fund that development effort).
Often there are many ways that certain things can be achieved. Where appropriate, the text below explains the rationale that led to specific design choices.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [https://tools.ietf.org/html/rfc2119 RFC2119].
Each requirement has an X.Y designation, which can be used for reference.
The key words can also be used to roughly estimate priority for a given feature: MUST is P1 priority (i.e. it's a mandatory part and the feature is considered dysfunctional without it), SHOULD being P2 (less important than MUST, but still much desired), and MAY being P3 (this is really an optional thing; assuming infinite time we would implement all MAYs, but the reality makes it somewhat unlikely).
1. Administrative actions
A.1. Kea MUST support the #39e21fshutdown command. (supported since 0.9.2)
It must be possible to terminate Kea programmatically. Since Kea is the process that handles the command channel, it will not be possible to restart it without additional administrative action.
A.2. Control channel MUST support incoming commands and sending responses of any size (larger than 64K bytes).
Supporting large command parameters and responses is required for a number of scenarios: getting all leases from a subnet, getting statistics for multiple subnets when # of subnets is large, etc.
Since some existing and prospective deployments talk about having over 10k subnets and 2M devices, it seems natural that some of the commands (e.g. subnetX-list) will generate large responses. Also, config-set and config-get commands will operate on the whole configuration, which can clearly be larger than 1500 bytes. With Kea 1.1 and 1.2 we tried to limit the maximum size to 64K, but that restriction is going to be removed in Kea 1.3.
A.3. Kea MUST support #39e21fconfig-reload to reload configuration from a file. (supported since 1.2.0)
Kea 1.2.0 already supports config-reload. It remembers the path to the JSON config file used during start and can reload it if needed. This is sufficient in use cases where a local configuration file was edited.
A.3.1. Kea SHOULD support #FF0000filename parameter in config-reload to reload configuration from a different file than when it initially started.
However, there are other scenarios that it does not address. In particular, there is no way to specify that the file location has changed. There are customers who built IPAM systems around ISC DHCP and they generate temporary config files, then restart ISC dhcpd. Once dhcpd is restarted, that temporary file is removed. It seems logical to presume that a similar model will be used with Kea. As of Kea 1.2.0, the current code allows reloading of the same file, without providing an ability to change its location. Changing location is especially important for cases when Kea is integrated into an IPAM or similar system.
A.4. Kea MUST support the #39e21fconfig-get command (Kea sends back its current configuration in the response). (supported since 1.2.0)
With the advance of Control API and the ability to modify its configuration during run-time, a new problem will emerge: how to ensure persistence of the configuration changes. It was suggested that perhaps Kea could try to overwrite its configuration file. This approach has several issues. First, we would have to ensure that whatever rewrite Kea does would not overwrite any existing information, including comments. The current Kea parser simply ignores comments; Kea code would have to remember comments and then insert them back into the written file. This is more complex than it sounds as there are many commenting styles. People write their comments immediately before the clause, they may put sections in their config, add some comments for specific entries, etc. Understanding which comment applies to which JSON entry is a difficult task. Had we chosen to retain comments and write the whole configuration, there would be cases of oddly misplaced comments.
The second argument against the approach of Kea rewriting its own configuration file is limiting use cases. There are deployments where the config file is stored on a read-only filesystem (e.g. OpenWRT or systems where only /tmp and /var are writeable). It would also make IPAM-like systems built around Kea difficult. We know of several systems developed around ISC DHCP; one of them keeps the configuration internally in XML. When the configuration changes, this XML is processed to generate and write ISC dhcpd's config to a temporary file, then the server is restarted and the temporary file removed. Rewriting this long deleted file would be useless.
Last but not least, the argument is about desired persistence of the changes. Users could experiment with their configuration and not necessarily keep the changes if they don't like the outcome. Therefore the "rewrite your own config" approach would require adding "bool persist" parameters to all configuration modification commands and then keeping them internally in the configuration manager. Furthermore, the configuration could possibly be internally inconsistent, e.g. sane with non-persistent elements, but insane without them. This would be an ever-growing complexity without a good solution in sight.
Therefore the proposal is to provide a config-get method that would return the current running configuration. It is up to the caller to do something with the response, e.g. store it externally, review it, or write it to the configuration file, possibly overwriting the existing config if the user so desires. Also, it gives the best flexibility in the sense of discarding changes that are deemed not desired. The user would simply not issue the config-get command, restart, and Kea would revert to its previous configuration.
A.5. Kea MUST support the #39e21fconfig-set command (sysadmin specifies new configuration as parameter). (supported since 1.2.0)
A.5.1 removed (write parameter for config-set will not be implemented, please use the config-write command instead)
A.5.2. Kea MAY support the #39e21fconfig-write command (sysadmin specifies file where current configuration should be written). (supported since 1.2.0)
Currently we assume that Kea loads its configuration file from the local file system. This will certainly remain the default behavior, but with simple modification we could add optional, additional sources of configuration. The JSON configuration would be sent over the command channel. One specific envisaged use case for this is the ability to boot many DHCP servers in data centers or large networks. There would be a VM image with just bare-bones configuration covering logging destination and pointers to the database. Then, once the VM is booted the actual configuration is deployed using the config-set command.
Another envisaged use case for this command is the ability to push configuration. For example, in large networks a new configuration could be pushed to multiple servers at the same time, without restarting any servers.
The config-set command will replace the existing configuration in memory. Kea will lose it after restart. The config-get command can be used to retrieve the existing configuration and store it externally.
The config-set command may also optionally provide updated logging configuration.
The config-write command allows writing of the current configuration to a file. The file location MUST be somehow limited; otherwise, a compromising DHCP server would allow escalation to write to an arbitrary place on disk.
A.6. Kea MUST support the #39e21fleases-reclaim command to trigger expiration of expired leases. (supported since 1.1.0)
Kea keeps leases for all clients it currently serves. Those leases have lease expiration timers associated. Kea does not take actions immediately when such a timer expires, but rather does the clean-up periodically. This command tells Kea to initiate such a clean-up command immediately. Details are described in Section 15.3.1 of the Kea User's Guide. This command is already supported in Kea 1.0.
A.7. Kea MUST support the #39e21flist-commands command that lists all supported commands. (supported since 1.2.0)
This simple command returns all commands that are currently supported by Kea. This is useful for refreshing one's memory regarding spelling of the commands. It can also be used to determine whether a given Kea instance supports a given command or not. This command is already supported in Kea 1.0.
A.8. Authentication MUST be supported on the command channel.
Currently (in Kea 1.0) the security of the channel is fragile. It is based on the UNIX socket and the fact that the UNIX socket is created with root privileges, so only privileged processes can write to it. This solution was chosen as a compromise made due to time constraints. For any possible future non-local command channel implementation, we will need an authentication mechanism. It is too early to discuss details, but to frame future discussions, here are two ground rules:
A.8.1. The solution provided MUST be able to defend against replay, spoof, and man-in-the-middle attacks.
A.8.2. The solution MUST be optional.
This second requirement should be regarded as an ability to disable authentication. The reason is that in some trusted environments, an admin may want to simply update the configuration with ease and not be bothered with keys, or signatures that expire. One possible mechanism considered here would be something similar to TSIG: client and server share a private key. The client signs each command with this key with the addition of a timestamp. The server then verifies that the signature is valid and not expired. This is only one of several possible solutions. Details of such solutions will be discussed during the design phase.
A.9 The commands and responses sent over the command channel MUST be logged.
Since the command channel is a powerful feature and can be used (intentionally or not) to severely degrade or even render the service unusable, we need a way to log all commands, where they came from, and what the server sent back in response. This will likely be implemented as a separate logger, but those are implementation details that will be sorted out during the design phase.
A.10 Kea MUST support the #39e21fconfig-test command to dry run the server configuration. (supported since 1.2.0)
Kea should allow testing of a new configuration without actually applying it. It is understood that certain aspects can't be really validated or the validation is temporary. For example, database connection or opening sockets is something that could work during verification, but could fail during the actual configuration commit.
2. Configuration management
2.1 Identifier types
There are several commands proposed below that refer to identifier-type and identifier, especially in leases and host reservations contexts. In a very simplified approach, the DHCPv4 client can be identified by its hardware/MAC address and the DHCPv6 client can be identified by its client-id (which is a DUID). However, modern networks are often more complicated and so are the ways clients are identified. DHCPv4 clients may send client-id options, ISPs may not know the MAC addresses but know the ports over which the clients will be connecting, etc. The number of such identifiers that are used to identify a client is growing over time. Therefore Kea is currently being refactored to allow easy addition of extra identifiers in the future.
Kea 1.0 allowed the following identifier types: hardware/MAC addresses for DHCPv4 and DUID for DHCPv6.
Kea 1.1 is expected to allow the following identifier types: hardware/MAC addresses, client-id (client-id option in DHCPv4), DUID (client-id option formatted according to RFC4361 in DHCPv4, client-id option in DHCPv6), remote-id (remote-id suboption inserted in option 82 by a DHCPv4 relay agent or remote-id option (37) inserted by a DHCPv6 relay agent), or circuit-id (circuit-id suboption inserted in option 82 by a DHCPv4 relay agent).
Additional identifier types are likely to be implemented in the future.
2.2 Leases management
After the DHCP server assigns an address (or address or prefix in case of DHCPv6), it records the fact of the address being assigned to a given client as a lease. This is the most important run-time piece of information for every DHCP server. The lease information tends to be updated frequently as most communications with any client cause the lease state to change. Therefore this is the most dynamic data in the DHCP world.
The API must allow management of the leases. It should allow full CRUD methodology (Create, Retrieve, Update, Delete). Those changes MUST be applicable during run-time and MUST NOT require Kea to be restarted.
L.1. Kea MUST support the #39e21flease4-add command.
L.2. Kea MUST support the #39e21flease6-add command.
Kea is able to store leases in memfile (which is an in-memory database that writes changes to a CSV file), MySQL, and PostgreSQL. There's work in progress to also store leases in a Cassandra nosql database. While it is possible to insert leases into the databases in some backends (MySQL and Postgres), this direct insertion approach has several flaws. In particular, it does not offer any sanity checks. The very basic checks (that the address is unique) are enforced by the database schema, but the more subtle are not. Three specific examples of such checks would be adding a lease for host A when the address is reserved for host B, adding a lease with invalid subnet ID, and adding a lease for subnet X with an address Y where address Y does not belong to the subnet X. Another reason why using an API is better is that it behaves in the same way for every backend, so any solutions built around Kea could be migrated to a different backend if such a need arises.
L.3. Kea MUST support the #39e21flease4-get command that takes IPv4 address as a parameter.
L.4. Kea MUST support the #39e21flease4-get command that takes (identifier-type, identifier, subnet-id) as parameters.
L.5. Kea MUST support the #39e21flease6-get command that takes IPv6 address as a parameter.
L.6. Kea MUST support the #39e21flease6-get command that takes (identifier-type, identifier, subnet-id) as parameters.
identifier-type is one of hwaddr (hardware/MAC address of the client), client-id (content of the client-identifier option in DHCPv4), DUID (content of the client-identifier option in DHCPv6), remote-id (content of the remote-id sub-option inserted in option 82 by a relay agent), or circuit-id (content of the circuit-id sub-option inserted in option 82 by a relay agent). More identifier types may be defined in the future.
These two commands will be used to retrieve IPv4 or IPv6 lease information. For each command one of two available sets of parameters may be specified: either IP address or a tuple of (identifier-type, identifier, subnet-id). The first command type is pretty obvious; we know an IP address and want to check whether there's a lease for it. The second command type is somewhat more complex. Kea 1.0 supports MAC addresses in IPv4 leases and DUIDs in IPv6 leases. Kea 1.1 will support several identifier types; in particular we're working on adding support for client-id, remote-id, and circuit-id options. It is envisaged that more identifier types may be added in the future. Therefore we chose the identifier-type + identifier approach, rather than provide specific commands for lease-get-by-hwaddr, lease-get-by-client-id, etc., as the number of such commands would grow over time.
Additional parameter sets for the leaseX-get command may be added at a later time.
L.7. Kea MAY support the #FF0000lease4-update command.
L.8. Kea MAY support the #FF0000lease6-update command.
Those two commands allow updating all parameters of a v4 or v6 lease. It is assumed that all parameters can change, except the IP address. The code processing this command MUST ensure that the data is consistent, e.g. verify that the subnet-id is sane, that the IP address range matches the subnet it belongs to, that the hostname has a valid format, etc. For the command to succeed, the lease for the specified IP address must exist. This call allows updating all or some of the fields. For example, if address and lifetime are specified, then only the lifetime will be updated and all other lease parameters will remain unchanged. This is useful for sysadmins so they do not need to know details like subnet-id if they only want to update e.g. lease-lifetime.
L.9. Kea MUST support the #39e21flease4-delete command.
L.10. Kea MUST support the #39e21flease6-delete command.
These two commands attempt to remove IPv4 and IPv6 leases. There will be only one mandatory parameter specified: the IP address of the lease to be removed. There will be one optional parameter called mode. It will accept one of two values: remove (which simply removes the lease from the database), or release (treat it as if a release packet was received. In particular, this would trigger additional steps, like cleaning up DNS entries if necessary). The default would be 'remove'.
Those two commands will be overloaded, i.e. they will accept one of two parameter sets: (address) or (identifier-type, identifier, subnet-id).
L.11. Kea MUST support the #39e21flease4-wipe command.
L.12. Kea MUST support the #39e21flease6-wipe command.
These two commands will remove all leases from a given subnet. Similar to the previous commands, these two commands will also have a parameter called mode that will accept values: remove (simply remove the lease from the database) or release (treat it as if a release packet was received). The default will be 'remove'.
Note: There are currently no plans to implement commands that retrieve multiple leases, e.g. all leases in a subnet. The reason why such an API was not designed is the stress on the API code. With subnets having potentially millions of leases, a command requesting all of them formatted as JSON structures would be a significant burden (potentially exploitable as a denial-of-service attack) to the server. We may revisit this if people come up with actual use cases for this.
Note: As an alternative, it was proposed that we could implement a row limit with some reasonable number, and maybe a flag or parameter for overriding that limit. We are not pursuing this alternative for now.
L.13 Kea MAY support the #FF0000lease4-get command that takes the (subnet-id) parameter and returns all leases in an IPv4 subnet.
L.14 Kea MAY support the #FF0000lease6-get command that takes the (subnet-id) parameter and returns all leases in an IPv6 subnet.
These two commands would return all leases for a given IPv4 or IPv6 subnet. Since the number of leases may be significant (a million or more), this will require some form of response limiting. One possible way would be to specify the maximum number of leases requested and then have a follow-up command to retrieve the next part of the information in batches. Another would be to have a dedicated thread that would retrieve that information in one go. This would become possible after the response size limitation is removed in upcoming Kea 1.3.
L.15 Kea MAY support the #FF0000lease4-get command that takes the (identifier-type, identifier) parameter.
L.16 Kea MAY support the #FF0000lease6-get command that takes the (identifier-type, identifier) parameter.
These two commands would return information about leases for a given device, regardless of the subnet it is connected to. This call could potentially return multiple leases for a mobile device that visited multiple subnets.
2.3 Host Reservations (HR) management
Kea allows host reservations. HR is a mechanism that allows reserving a specific IPv4 address, IPv6 address, IPv6 prefix, specific hostname, or set of options to a given client. Depending on the deployment, there may be no host reservations at all (all leases assigned dynamically), there may be some reservations (mixed model, where most clients are assigned dynamically, but there is a subset of clients that have reserved parameters), or there may be a fully static model (dynamic allocation is effectively disabled, all clients are known and have static reservations).
Currently (Kea 1.0), Kea allows storing host reservations in the configuration file and there's work in progress to allow storing HR in MySQL and PostgreSQL. Ultimately, the plan is to store this information in backends (for most backends except memfile). When the number of reservations is small and they are not updated frequently, it makes sense to store them in the configuration file. However, with the number of HR getting large or being updated more frequently, it is increasingly compelling to store them in the database. The following commands provide the ability to manipulate the HR information.
Note: for backends that provide the ability to store HR (currently MySQL only, but this capability for PostgreSQL is planned for 1.1. There are also discussions about developing such capability for Cassandra in the upcoming releases, but no firm decisions have been made yet), the change will be reflected in-memory only. If you're using a backend that can't store reservations, Kea would keep the reservations in-memory. Those would be lost after shutdown, unless retrieved with config-get and stored.
H.1. Kea MUST support the #1221ccreservation-add command that adds a reservation. (since 1.2.0, premium feature)
H.2. The #1221ccreservation-add command MUST allow reserving an IPv4 address. (since 1.2.0, premium feature)
H.3. The #1221ccreservation-add command MUST allow reserving zero, one, or more IPv6 addresses. (since 1.2.0, premium feature)
H.4. The #1221ccreservation-add command MUST allow reserving zero, one, or more IPv6 prefix. (since 1.2.0, premium feature)
H.5. The #1221ccreservation-add command MUST allow specifying a hostname. (since 1.2.0, premium feature)
H.6. The #1221ccreservation-add command MUST allow specifying IPv4 options that will be sent for that host. (since 1.2.0, premium feature)
H.7. The #1221ccreservation-add command MUST allow specifying IPv6 options that will be sent for that host. (since 1.2.0, premium feature)
H.8. The #1221ccreservation-add command MUST allow reservations by hardware (MAC) address. (since 1.2.0, premium feature)
H.9. The #1221ccreservation-add command MUST allow reservations by DUID. (since 1.2.0, premium feature)
H.10. The #1221ccreservation-add command SHOULD allow reservations by client-id. (since 1.2.0, premium feature)
H.11. The #1221ccreservation-add command MAY allow reservations by circuit-id. (since 1.2.0, premium feature)
H.12. The #1221ccreservation-add command MAY allow reservations by remote-id. (since 1.2.0, premium feature)
H.12.1 The #1221ccreservation-add command MAY allow adding boot-file-name, server-hostname and next-server for IPv4 reservations. (since 1.2.0, premium feature)
This command will add a new reservation for a host. It will be possible to specify an IPv4 address, IPv6 addresses (typically one, but it will be possible to specify more), IPv6 prefixes (typically one, but it will be possible to specify more), a hostname, per host specific options, a subnet-id (separate for IPv4 and IPv6 subnets), and an identifier. The identifier will be specified as (identifier-type, identifier) pair. The details are TBD, but it seems very likely that the initial implementation will allow specifying the following identifier types: hwaddr (hardware/MAC address), client-id (client-identifier option in DHCPv4), DUID (client-id option in DHCPv6), remote-id (remote-id sub-option in option 82), or circuit-id (circuit-id sub-option in option 82). Additional identifier types are likely to be defined in the future.
The reservation-add command will ensure the integrity of the data. In particular, it will refuse any data that fails sanity checks: the IP address is already reserved to a different host, this identifier already has a different reservation in this subnet, or the IP address does not belong to the subnet represented by the subnet-id parameter.
For backends that do not support storing reservations, this will create a memory entry in Host Manager. This will be lost upon shutdown or restart. To avoid loss of this information use the config-get command before shutdown.
H.13. Kea MUST support #1221ccreservation-get by (IPv4 address, subnet-id) command. (since 1.2.0, premium feature)
H.14. Kea MUST support #1221ccreservation-get by (IPv6 address subnet-id) command. (since 1.2.0, premium feature)
H.15. Kea MUST support #1221ccreservation-get by IPv6 prefix command. (since 1.2.0, premium feature)
H.16. Kea MUST support #1221ccreservation-get by (identifier-type, identifier, subnet-id). (since 1.2.0, premium feature)
An ability to retrieve existing reservations is useful for two broad ranges of scenarios. The first is to check whether there is a reservation for a given address or client, and the second is to check the details of said reservation. Kea stores IPv4 and IPv6 reservations together in the same table to allow a centralized point of authority for dual-stack devices. It also makes keeping the configuration consistent between IPv4 and IPv6 stacks easier.
There will be two ways to use the reservation-get command. The first one is to specify an IP address. The second one is to specify an identifier-type, identifier, and a subnet in which the search should be conducted. See the "Identifier types" section above for details about identifier-type and identifier tuple.
H.16.1 Kea MAY support #FF0000reservation-get by (IPv4 address) command.
H.16.2 Kea MAY support #FF0000reservation-get by (IPv6 address) command.
This type of query will retrieve a reservation for a specific IPv4 or IPv6 address, if it exists. It will do so regardless of the subnet the reservation is in.
H.16.3 Kea MAY support #FF0000reservation-get by (identifier-type, identifier) command.
This command will return all reservations for a given device. There may be multiple reservations returned for multiple subnets.
H.17. Kea MAY support the #FF0000reservation-update command that modifies an existing reservation.
This command will update an existing host reservation. This command will have two groups of parameters. The first group will be used to select the reservation. It will have identifier-type, identifier, and subnet-id parameters specified (there will be a way to specify if the subnet-id is v4 or v6). Once the appropriate reservation is selected, it will be updated. The parameters for this are to be specified in the second group of parameters. This will include all parameters allowed in the reservation-add command.
The implementation of this command will internally be split into two logical phases. The first is an attempt to retrieve the host, which is functionally equivalent to the reservation-get(identifier-type, identifier, subnet-id) command. The second step is to update specified parameters. This means that the user doesn't have to provide all parameters, only those that are being changed.
The operations would be atomic.
For backends that do not support storing reservations, this will create a memory entry in Host Manager. This will be lost upon shutdown or restart. To avoid loss of this information use the config-get or config-write commands before shutdown.
H.17.1 #FF0000reservation-update MUST be able to update IPv6 reservations.
H.17.2 #FF0000reservation-update MUST be able to update DHCPv4 and DHCPv6 options.
A specific reservation will be indicated by providing a (identifier-type, identifier, subnet-id) tuple. Since this is a relation one-to-many (one host can have multiple IPv6 reservations, multiple DHCPv4 options, and multiple DHCPv6 options), and there is no easy way to reference reservations or options, those commands will assume that IPv6 reservations or DHCPv4 or DHCPv6 options are specified, and they overwrite whatever was specified for the host. In particular, it will be possible to specify an empty list to remove any existing IPv6 reservations or options.
H.18. Kea MUST support #1221ccreservation-del by IPv4 address command. (since 1.2.0, premium feature)
H.19. Kea MUST support #1221ccreservation-del by IPv6 address command. (since 1.2.0, premium feature)
H.20. Kea MUST support #1221ccreservation-del by (identifier-type, identifier, subnet-id). (since 1.2.0, premium feature)
These three commands will attempt to remove a reservation. A specific reservation will be indicated by providing one of the following parameter sets: (identifier-type, identifier, subnet-id) tuple, (IPv4 address), or (IPv6 address). It is recommended to understand how Kea works before deleting a reservation for an active host. Once a request comes from a client that has matching HR, Kea will create a lease entry (or even multiple leases if the host has IPv4+IPv6 or multiple IPv6 addresses reserved). Removing the host reservation will not remove the leases, unless the delete-leases parameter is specified.
In such cases it is not advisable to remove the lease, as it could have adverse consequences. In particular, after removing a lease for an active client, the client will not immediately know that its lease was revoked and will continue using it until the next renewal, which may be days away. The server, however, would consider the address unused and available for allocation and could assign it to a different client. This would cause two clients to attempt to use the same address, which would cause Decline procedures.
Note that IPv4 or IPv6 addresses are used to identify the reservation. If found, the reservation will be deleted, even if there are other parameters (e.g. an address for the other protocol family).
For backends that do not support storing reservations, this will create a memory entry in Host Manager. This will be lost upon shutdown or restart. To avoid loss of this information use the config-get command before shutdown and make sure it is stored somewhere before shutting down the server.
2.4 Subnets management
Dedicated page: SubnetCommands.
Existing (Kea 1.0) and upcoming (Kea 1.1) versions support storing subnet information in the configuration file only. However, it was reported by several large-scale existing and prospective users that their deployments use thousands of subnets. At this scale, it makes sense to consider allowing storage of subnet information in the database. Subnet information is considered to be less frequently changing than host reservations and much less often than lease information.
It should be noted that the capability to store subnets in the DB will always be in addition to the config file. The ability to provide the configuration in a configuration file without running a database will remain supported.
Since IPv4 and IPv6 topologies may be different and the per-subnet parameters are different in those protocols, Kea stores IPv4 and IPv6 subnets separately. Therefore, there will be separate commands for IPv4 and IPv6 subnets.
S.1. Kea MUST support the #ea8920subnet4-list command (planned for 1.3.0).
S.2. Kea MUST support the #ea8920subnet6-list command (planned for 1.3.0).
Kea uses the subnet-id parameter (an integer) to identify subnets. The only requirement for those identifiers is that they must be unique for each family. In particular, they don't have to be consecutive, start from 1 or have increasing values. There is a very good reason for that. Imagine a case where there are 3 subnets with subnet-ids 1, 2, and 3. Now the topology has changed and subnet 2 was removed. The subnet ids are 1 and 3. That removed subnet is then replaced by two subnets with ids 2 and 10, which are added to the configuration. The subnet ids for the configured subnets are now 1, 3, 2, 10. This simple example shows that we can't make any assumptions about the subnet-id. In particular, the assumption that the biggest subnet-id equals the number of subnets is false. Also, the assumption that we can get all subnets by querying subnet-ids in increasing (1,2,3,4,5,6...) order is false.
subnetX-list will return a list of all subnets. Each subnet will be represented as a single subnet-id value and no other value. This terse notation is useful when you have many subnets and returning detailed information about all of them could easily slow down the server. If you are interested in a particular subnet, please use the subnetX-get(subnet-id) call.
If the user knows the subnet-id values, this command can be skipped altogether.
S.3. Kea MUST support the #ea8920subnet4-get (by subnet-id) command (planned for 1.3.0).
S.3.1 Kea MUST support the #ea8920subnet4-get (by prefix/prefix-len) command (planned for 1.3.0).
S.4. Kea MUST support #ea8920subnet6-get (by subnet-id) command (planned for 1.3.0).
S.4.1 Kea MUST support #ea8920subnet6-get (by prefix/prefix-len) command (planned for 1.3.0).
The subnetX-get commands return subnet information, including subnet range and prefix (e.g. 192.0.2.0/24) and subnet-id. Additional parameters (e.g. configured relay information, configured host reservation mode, configured T1, T2, preferred lifetime, valid lifetime, allowed client classes, and subnet specific options) may also be returned. The exact scope of information returned will be decided during the design phase. This command will return all pools configured in the subnet.
S.7. Kea MAY support the #FF0000subnet4-update command.
S.8. Kea MAY support the #FF0000subnet6-update command.
Those two commands allow making changes to an existing subnet: changing prefix, prefix length, T1, T2, preferred lifetime, valid lifetime timers, allowed client classes, subnet specific options, and subnet-id values. It also allows modifying pools.
Sanity checks will be conducted to verify that the specified input parameters are sane.
Note: for backends that do not support storing subnet information (as of upcoming Kea 1.1, none of the backends will be able to store this information. There is a debate whether database storage for subnet information will be available in Kea 1.2), the update will only modify in-memory representation of the database. This will be lost upon shutdown or restart. To avoid loss of this information use the config-get command before shutdown and store its response.
Note: Care should be taken when modifying a subnet or its pools to not abandon any leases. If the updated subnet or pool definition has a smaller range than before modification, it's possible to have leases that are outside of the current subnet definitions.
We need to handle subnet modification. There are several options:
We could forcibly remove leases that are not in the subnet anymore. This has the advantage of having lease information consistent with the configuration. However, it means that after subnet reconfiguration there will be clients believing they have a lease, but the server would think the address is not used. This should be ok in most cases, as those addresses would be out of subnet now, so the server wouldn't assign them to anyone else. However, in rare cases where an existing subnet is split into two smaller ones, this logic could fail and then the same address could be assigned twice.
We could keep the leases and implement a check in the allocation engine. Every time an address is sent to the client we could check that it belongs to a subnet it's claimed to be in (match by subnet-id) and that the address belongs in the current definition of pools. This would mostly work, except in the cases of host reservations that use out-of-pool reservations. Also, adding extra checks in the assignment/renewal case would have some small performance implications.
We could keep the leases as they are and do nothing. It would mean that after shrinking the subnet or pool, clients would remain using the address they got. It's the safest approach from the safety perspective, but it would mean a long tail of addresses being still in use after the configuration has changed.
As all of them may be useful, we will likely provide a parameter which will select the behavior of !#1 (closed), !#2 (closed), or !#3 (closed). It was suggested that !#2 (closed) would be somewhat awkward to implement. For the time being we keep it here as an alternative.
S.9. Kea MUST support the #ea8920subnet4-add command (planned for 1.3.0).
S.10. Kea MUST support the #ea8920subnet6-add command (planned for 1.3.0).
These two commands add new subnets. They will allow specifying all the subnet parameters as if the subnet definition were in a config file. Sanity checks will be conducted to verify that the specified input parameters are sane.
Note: for backends that do not support storing subnet information (as of upcoming Kea 1.1 none of the backends will be able to store this information. There is a debate whether database storage for subnet information will be available in Kea 1.2), the update will only modify in-memory representation of the database. This will be lost upon shutdown or restart. To avoid loss of this information use the config-get command before shutdown and store its response.
S.11. Kea MUST support the #ea8920subnet4-del command.
S.12. Kea MUST support the #ea8920subnet6-del command.
Those two commands attempt to delete existing subnet definition. Removing an existing subnet should be taken with care. If there are active devices in the subnet being removed from configuration, unexpected behaviors may be observed.
The issue here is similar to update-subnet. There are several possible strategies:
Do gradual subnet retirement. The first step would be to mark the subnet for removal. This means that no new address would be assigned and existing leases would not be extended. Once all leases are released or expired, we could remove the subnet. This seems to be the cleanest way to remove a subnet. However, it takes time and in some cases it would be annoying to wait.
Simply delete the subnet structure. The leases will be there, but during renewal the server will not be able to pick them up because of subnet selection failing, and a new lease will be assigned. After valid-lifetime all leases will be expired. This could potentially get messed up if a subnet is deleted and then a new subnet with the same subnet-id is added.
Delete leases instantly. This makes sense if the devices are going away together with the subnet, e.g. an old network segment is shutdown.
Initiate the reconfigure process and delete the leases/subnet afterwards. This would make Kea initiate the reconfigure procedure for all clients. This is ideal behavior in theory, but has two problems. First, Kea does not support reconfigure yet. Second, reconfigure support in clients is optional, so there are many implementations that do not support it.
We will likely implement a parameter that will cause Kea to proceed using one of the strategies above.
2.5 Options management
Kea allows specifying options in several scopes: global (all clients will get them), subnet (all clients connected to a given subnet will get them), class (only clients belonging to specific class will get them), and host (only a given host will get them). Kea allows option definitions on a global level. See Sections 7.2.9 of the Kea User's Guide for examples of option definitions and option data.
Option definitions allow defining standard options, custom options, vendor space options, and nested options. See Sections 7.2.8, 7.2.9, 7.2.10, and 7.2.11 of the Kea User's Guide.
O.1. Kea MUST support the #FF0000option4-def-add command that adds DHCPv4 option definition.
O.2. Kea MUST support the #FF0000option6-def-add command that adds DHCPv6 option definition.
O.3. Kea MUST support the #FF0000option4-defs-set-all command that sets all DHCPv4 option definitions.
O.4. Kea MUST support the #FF0000option6-defs-set-all command that sets all DHCPv6 option definitions.
O.5. Kea MUST support the #FF0000option4-defs-get-all command that returns all DHCPv4 option definitions.
O.6. Kea MUST support the #FF0000option6-defs-get-all command that returns all DHCPv6 option definitions.
O.7. Kea MUST support the #FF0000option4-def-del command that deletes a DHCPv4 option definition.
O.8. Kea MUST support the #FF0000option6-def-del command that deletes a DHCPv6 option definition.
add-optionX-def commands add one or more new option definitions. New options will be added to existing ones. A sanity check is done on input data. In particular, it is checked whether the option is internally consistent and does not conflict with existing standard or custom options (e.g. by attempting to define an option that is already defined).
set-multiple-optionX-defs commands set all option definitions. New options will replace whatever old definitions may have been there. A sanity check is done on input data. It is checked whether the new options are internally consistent (i.e. there are no options with duplicate names or duplicate codes). Also, since subnets may contain definitions of options, all existing subnets are checked to see whether they are covered by new option definitions.
get-multiple-optionX-defs commands return a set of all option definitions.
delete-optionX-def commands have 3 parameters: option-name, option-code, and option-space. Only one of option-name or option-code is required, so the option being deleted can be referred to either by name or by code. If option-space is not specified, it is assumed to be "dhcp4" for delete-option4-def and "dhcp6" for delete-option6-def.
O.9. Kea MUST support the #FF0000option4-add command that adds value of a single DHCPv4 option.
O.10. Kea MUST support the #FF0000option6-add command that adds value of a single DHCPv6 option.
O.11. Kea MUST support the #FF0000options4-set command that sets all DHCPv4 options values.
O.12. Kea MUST support the #FF0000options6-set command that sets all DHCPv6 options values.
O.13. Kea MUST support the #FF0000options4-get command that returns all DHCPv4 option values.
O.14. Kea MUST support the #FF0000options6-get command that returns all DHCPv6 option values.
O.15. Kea MUST support the #FF0000option4-del command that deletes a DHCPv4 option values.
O.16. Kea MUST support the #FF0000option6-del command that deletes a DHCPv6 option values.
O.17. Kea MAY support the #FF0000option4-get command that returns a single DHCPv4 option value.
O.18. Kea MAY support the #FF0000option6-get command that returns a single DHCPv6 option value.
Kea allow option specification on a global and per-subnet level. Both can be manipulated using the same command. There will be an optional parameter, subnet-id. If it's not specified, the code applies to the global level. If there is a subnet-id specified, the change applies to the specific subnet. The same rule applies to all commands related to options.
add-option4 and add-option6 add new DHCPv4 or DHCPv6 option values. It is expected that only options that have definitions can be specified. This requires either the option to be standard or to have a custom definition. See [https://git.kea.isc.org/~tester/kea/guide/kea-guide.html#dhcp4-std-options Table 7.1] in Section 7.2.8 and [https://git.kea.isc.org/~tester/kea/guide/kea-guide.html#dhcp6-std-options Table 8.1] in Section 8.2.8 of the Kea User's Guide for a list of currently defined standard options. This command would generally expect parameters as specified in Section 8.2.8, i.e. one of option-name or option-code being mandatory, option-space being optional with the default option space being "dhcp4" or "dhcp6" depending on which command was called, csv-format to be true. Option-data is mandatory for options that have any fields (most options have, except empty and container options).
set-options4 and set-options6 set all option values for a given scope. If the subnet-id is not specified, the options are set globally. If there is a subnet-id specified, the option values will be set only for a given subnet. Input parameters are sanity-checked the same way as described for add-optionX with the additional check against subnet-id having proper values.
The get-options4 and get-options6 commands return all option values defined for a given scope. They have one optional parameter: subnet-id. If it's not defined, all global options are returned. If it's defined, only options for a given scope are returned.
delete-option4 and delete-option6 delete the configuration value of an option. They require either option-name or option-code to be specified and optionally subnet-id. If subnet-id is not specified, it is interpreted as a command to delete the global option with the specified code or name. If subnet-id is specified, the option value in that subnet is deleted.
2.6 Interfaces management
In DHCP it is essential to control how the server receives and transmits packets to and from clients. The important distinction should be kept in mind here: an interface or interfaces refer to network interfaces present in the system. These are typically physical hardware network interfaces, but may also be logical interfaces that represent a VLAN, a tunnel, or another type of connection. They are something that the OS reports are a possible communication channel. Kea servers can only read that information from the system, but can't change anything about them. On top of that there is a list of interfaces that Kea is configured to listen on and handle traffic from. This is a part of Kea configuration. This list can be updated, i.e. entries can be added and removed from that list at any time. Currently (Kea 1.2.0), an attempt to configure an interface that is reported by the OS as available will result in a Kea configuration error.
The following API commands are envisaged:
I.1. Kea MAY support the #FF0000interfaces-config-get command that returns details of the network interfaces Kea listens on.
I.2. Kea MAY support the #FF0000interfaces-config-set command that sets network interfaces Kea listens on.
I.3. Kea MAY support the #FF0000interfaces-get command that returns the current list of detected interfaces.
I.4. Kea MAY support the #FF0000interfaces-redetect command that re-runs network interfaces detection.
I.5. Kea MAY support the #FF0000interface-config-add command that adds a new network interface to the list on which Kea listens.
I.6. Kea MAY support the #FF0000interface-config-del command that removes a new network interface from the list on which Kea listens.
The get-interfaces-config returns a list of network interfaces the server is told to listen on. This is thoroughly described in Sections 7.2.4 and 8.2.3 of the Kea User's Guide. This would usually be a list of interface names, but could also be information on specific unicast addresses the server is told to listen on. Also, it may contain an asterisk to denote that Kea was told to listen on all interfaces.
The set-interfaces-config command is used to specify interfaces to listen on and possibly IP addresses to bind to. This follows the data structures laid out in Sections 7.2.4 and 8.2.3 of the Kea User's Guide.
The get-interfaces command is a convenience method that returns all network interfaces detected in the system. This is different than get-interfaces-config. For example, imagine a server that has 3 interfaces: eth0, eth1, and lo. It is configured to listen on eth1 only, so incoming DHCP traffic on eth0 is ignored. get-interfaces-config would return eth1 only, while get-interfaces would return eth0, eth1, and lo.
It should be noted that Kea detects interfaces reported by the OS during startup and assumes that they have not changed. This may not always be true, e.g. new USB or PPP interfaces may have been added, a PPP link may have gone down, etc. The redetect-interfaces command tells Kea to redo the interface procedure.
2.7 Classification management
Kea supports client classification. It is a set of expressions that are evaluated for each incoming packet. Depending on the result of such evaluation, the packet may be assigned to zero or more classes. This mechanism is explained in Section 12 of the Kea User's Guide.
Q3: Do we need API commands to manage client classification? The answer is likely yes, but it's a bit premature to define an API for this as the client classification is being worked on right now (Kea 1.1).
2.8 Hooks management
At this time we do not plan separate commands for hook management, but we may design them once hooks usage becomes more popular.
2.9 Run-time operations
Kea is able to gather many run-time parameters called statistics. The following commands are currently supported in Kea 1.0:
R.1. - Kea MUST support the #39e21fstatistic-get command that returns a single statistic. (since 1.0)
R.2. - Kea MUST support the #39e21fstatistic-reset command that resets a statistic to its neutral value (zero, 0.0, empty string or similar) (since 1.0)
R.3. - Kea MUST support the #39e21fstatistic-remove command that removes a given statistic. (since 1.0)
R.4. - Kea MUST support the #39e21fstatistic-get-all command that returns all statistics. (since 1.0)
R.5. - Kea MUST support the #39e21fstatistic-reset-all command that resets all statistics to their neutral values (zero, 0.0, empty string or similar) (since 1.0)
R.6. - Kea MUST support the #39e21fstatistic-remove-all command that removes all statistics. (since 1.0)
Calls R.1 - R.6 are already implemented in Kea 1.0 and are documented in Chapter 15 of the Kea User's Guide.
2.10 Shared Networks Management
Main page: SharedNetworkCommands.
The #1221ccnetwork4-list command lists all currently configured shared IPv4 networks.
The #1221ccnetwork6-list command lists all currently configured shared IPv6 networks.
The #1221ccnetwork4-get command retrieves all configuration details for one specified shared IPv4 network.
The #1221ccnetwork6-get command retrieves all configuration details for one specified shared IPv6 network.
The #1221ccnetwork4-add command adds a new shared IPv4 network.
The #1221ccnetwork6-add command adds a new shared IPv6 network.
The #1221ccnetwork4-del command deletes an existing shared IPv4 network and downgrades any subnets in it into stand-alone subnets.
The #1221ccnetwork6-del command deletes an existing shared IPv6 network and downgrades any subnets in it into stand-alone subnets.
The #1221ccnetwork4-subnet-add command adds an existing IPv4 subnet into an existing shared IPv4 network.
The #1221ccnetwork6-subnet-add command adds an existing IPv6 subnet into an existing shared IPv6 network.
The #1221ccnetwork4-subnet-del command removes an existing IPv4 subnet that was part of an existing shared IPv4 network from that network.
The #1221ccnetwork4-subnet-del command removes an existing IPv6 subnet that was part of an existing shared IPv4 network from that network.
3. Future enhancements and ideas
This section lists ideas and potential features that are currently out of scope. We keep them to solicit feedback and comments.
Shawn suggested: In Bind’s RNDC there is the concept of freezing the server such that the configuration can be updated while it is still “running” but not “serving”. This is useful if the admin wants to make a number of changes that should be somewhat atomic as seen from the outside. Response: We handle atomic changes by using config-get/config-set. The freeze state doesn't seem that useful, especially since Kea tries to be more responsive and do as many configuration changes as possible on the fly.
We could implement a timestamp that would report when the configuration has been updated. Shawn writes: I’m thinking of the case of an admin trying to synchronize the configuration with an external source and being able to confirm that the version or time stamp is the same as when the external source last updated the configuration could avoid having to retrieve and compare the entire configuration. That's a good idea. Created #5299 for that.
We could implement version numbering, so each configuration update would bump up the number. This would be mainly useful if you have many DHCP servers and you deploy configuration on all of them. Created #5300 for it.
Tomek writes: We could implement a sort of a digest of the whole configuration. If the configuration changes the digest would change. This would have 2 benefits. First, you can check if the configuration is matching what is expected, but without retrieving the whole configuration. Second, you could detect any changes, for example an attacker updating your router configuration as a stage for MITM attack. #5301 has been created for it.
Shawn writes: We may also want to consider the idea of before and after from ISC DHCP. With these options one can specify that a given subnet is only to be used until a certain date or after a certain date. Such a feature would require changes in the allocation code as well but it would make adding, removing, or updating subnet information more convenient. An example of how this could work is that an IPv6 subnet is being renumbered and the old prefix should stop at midnight tonight while the new prefix can be used after midnight. The server would hand out shorter and shorter leases up till midnight, such that all the leases would expire at midnight when the old prefix is no longer used. Exact details of how to implement this would need to be discussed and again this is likely to be deferred till later.
Shawn writes: can we update the logging information while running? It would be useful to modify the severity and debug level at least. Tomek's comment: logging can be set with config-set. We may consider separate call set-logging if there's a need for it.
Normen mentioned: there should be more server configuration parameters, like interface names, logging, and database configuration.
Thomas: At some point we had requirements to address an audit trail/log of commands received/executed. Not sure when they fell out but we should add them.