8. The DHCPv4 Server

8.1. Starting and Stopping the DHCPv4 Server

It is recommended that the Kea DHCPv4 server be started and stopped using keactrl (described in Managing Kea with keactrl); however, it is also possible to run the server directly. It accepts the following command-line switches:

  • -c file - specifies the configuration file. This is the only mandatory switch.
  • -d - specifies whether the server logging should be switched to debug/verbose mode. In verbose mode, the logging severity and debuglevel specified in the configuration file are ignored; “debug” severity and the maximum debuglevel (99) are assumed. The flag is convenient for temporarily switching the server into maximum verbosity, e.g. when debugging.
  • -p server-port - specifies the local UDP port on which the server will listen. This is only useful during testing, as a DHCPv4 server listening on ports other than the standard ones will not be able to handle regular DHCPv4 queries.
  • -P client-port - specifies the remote UDP port to which the server will send all responses. This is only useful during testing, as a DHCPv4 server sending responses to ports other than the standard ones will not be able to handle regular DHCPv4 queries.
  • -t file - specifies a configuration file to be tested. Kea-dhcp4 will load it, check it, and exit. During the test, log messages are printed to standard output and error messages to standard error. The result of the test is reported through the exit code (0 = configuration looks ok, 1 = error encountered). The check is not comprehensive; certain checks are possible only when running the server.
  • -v - displays the Kea version and exits.
  • -V - displays the Kea extended version with additional parameters and exits. The listing includes the versions of the libraries dynamically linked to Kea.
  • -W - displays the Kea configuration report and exits. The report is a copy of the config.report file produced by ./configure; it is embedded in the executable binary.

On startup, the server will detect available network interfaces and will attempt to open UDP sockets on all interfaces mentioned in the configuration file. Since the DHCPv4 server opens privileged ports, it requires root access. This daemon must be run as root.

During startup, the server will attempt to create a PID file of the form: [runstatedir]/kea/[conf name].kea-dhcp4.pid where:

  • runstatedir: The value as passed into the build configure script; it defaults to “/usr/local/var/run”. Note that this value may be overridden at runtime by setting the environment variable KEA_PIDFILE_DIR, although this is intended primarily for testing purposes.
  • conf name: The configuration file name used to start the server, minus all preceding paths and the file extension. For example, given a pathname of “/usr/local/etc/kea/myconf.txt”, the portion used would be “myconf”.

If the file already exists and contains the PID of a live process, the server will issue a DHCP4_ALREADY_RUNNING log message and exit. It is possible, though unlikely, that the file is a remnant of a system crash and the process to which the PID belongs is unrelated to Kea. In such a case it would be necessary to manually delete the PID file.

The server can be stopped using the kill command. When running in a console, the server can also be shut down by pressing ctrl-c. It detects the key combination and shuts down gracefully.

8.2. DHCPv4 Server Configuration

8.2.1. Introduction

This section explains how to configure the DHCPv4 server using a configuration file. Before DHCPv4 is started, its configuration file must be created. The basic configuration is as follows:

{
# DHCPv4 configuration starts on the next line
"Dhcp4": {

# First we set up global values
    "valid-lifetime": 4000,
    "renew-timer": 1000,
    "rebind-timer": 2000,

# Next we set up the interfaces to be used by the server.
    "interfaces-config": {
        "interfaces": [ "eth0" ]
    },

# And we specify the type of lease database
    "lease-database": {
        "type": "memfile",
        "persist": true,
        "name": "/var/lib/kea/dhcp4.leases"
    },

# Finally, we list the subnets from which we will be leasing addresses.
    "subnet4": [
        {
            "subnet": "192.0.2.0/24",
            "pools": [
                {
                     "pool": "192.0.2.1 - 192.0.2.200"
                }
            ]
        }
    ]
# DHCPv4 configuration ends with the next line
}

}

The following paragraphs provide a brief overview of the parameters in the above example, along with their format. Subsequent sections of this chapter go into much greater detail for these and other parameters.

The lines starting with a hash (#) are comments and are ignored by the server; they do not impact its operation in any way.

The configuration starts in the first line with the initial opening curly bracket (or brace). Each configuration must contain an object specifying the configuration of the Kea module using it. In the example above this object is called Dhcp4.

Note

In the current Kea release it is possible to specify configurations of multiple modules within a single configuration file, but this is not recommended and support for it will be removed in a future release. The only object, besides the one specifying module configuration, which can be (and usually was) included in the same file is Logging. However, we don’t include this object in the example above for clarity; its content, the list of loggers, should now be inside the Dhcp4 object instead of the deprecated object.

The Dhcp4 configuration starts with the "Dhcp4": { line and ends with the corresponding closing brace (in the above example, the brace after the last comment). Everything defined between those lines is considered to be the Dhcp4 configuration.

In general, the order in which those parameters appear does not matter, but there are two caveats. The first one is to remember that the configuration file must be well-formed JSON. That means that the parameters for any given scope must be separated by a comma, and there must not be a comma after the last parameter. When reordering a configuration file, keep in mind that moving a parameter to or from the last position in a given scope may also require moving the comma. The second caveat is that it is uncommon — although legal JSON — to repeat the same parameter multiple times. If that happens, the last occurrence of a given parameter in a given scope is used, while all previous instances are ignored. This is unlikely to cause any confusion as there are no real-life reasons to keep multiple copies of the same parameter in the configuration file.

The first few DHCPv4 configuration elements define some global parameters. valid-lifetime defines how long the addresses (leases) given out by the server are valid. If nothing changes, a client that got an address is allowed to use it for 4000 seconds. (Note that integer numbers are specified as is, without any quotes around them.) renew-timer and rebind-timer are values (also in seconds) that define T1 and T2 timers that govern when the client will begin the renewal and rebind procedures.

Note

Beginning with Kea 1.6.0 the lease valid lifetime is extended from a single value to a triplet with minimum, default and maximum values using min-valid-lifetime, valid-lifetime and max-valid-lifetime. When the client does not specify a lifetime the default value is used, when it specifies using a DHCP option code 51 this value is used if it is not less than the minimum (in this case the minimum is returned) or greater than the maximum (in this case the maximum is used).

Note

Both renew-timer and rebind-timer are optional. The server will only send rebind-timer to the client, via DHCPv4 option code 59, if it is less than valid-lifetime; and it will only send renew-timer, via DHCPv4 option code 58, if it is less than rebind-timer (or valid-lifetime if rebind-timer was not specified). In their absence, the client should select values for T1 and T2 timers according to RFC 2131. See section Sending T1 (Option 58) and T2 (Option 59) for more details on generating T1 and T2.

The interfaces-config map specifies the server configuration concerning the network interfaces on which the server should listen to the DHCP messages. The interfaces parameter specifies a list of network interfaces on which the server should listen. Lists are opened and closed with square brackets, with elements separated by commas. To listen on two interfaces, the interfaces-config command should look like this:

"interfaces-config": {
    "interfaces": [ "eth0", "eth1" ]
},

The next couple of lines define the lease database, the place where the server stores its lease information. This particular example tells the server to use memfile, which is the simplest (and fastest) database backend. It uses an in-memory database and stores leases on disk in a CSV (comma-separated values) file. This is a very simple configuration; usually the lease database configuration is more extensive and contains additional parameters. Note that lease-database is an object and opens up a new scope, using an opening brace. Its parameters (just one in this example: type) follow. If there were more than one, they would be separated by commas. This scope is closed with a closing brace. As more parameters for the Dhcp4 definition follow, a trailing comma is present.

Finally, we need to define a list of IPv4 subnets. This is the most important DHCPv4 configuration structure, as the server uses that information to process clients’ requests. It defines all subnets from which the server is expected to receive DHCP requests. The subnets are specified with the subnet4 parameter. It is a list, so it starts and ends with square brackets. Each subnet definition in the list has several attributes associated with it, so it is a structure and is opened and closed with braces. At a minimum, a subnet definition has to have at least two parameters: subnet (which defines the whole subnet) and pools (which is a list of dynamically allocated pools that are governed by the DHCP server).

The example contains a single subnet. If more than one were defined, additional elements in the subnet4 parameter would be specified and separated by commas. For example, to define three subnets, the following syntax would be used:

"subnet4": [
    {
        "pools": [ { "pool":  "192.0.2.1 - 192.0.2.200" } ],
        "subnet": "192.0.2.0/24"
    },
    {
        "pools": [ { "pool": "192.0.3.100 - 192.0.3.200" } ],
        "subnet": "192.0.3.0/24"
    },
    {
        "pools": [ { "pool": "192.0.4.1 - 192.0.4.254" } ],
        "subnet": "192.0.4.0/24"
    }
]

Note that indentation is optional and is used for aesthetic purposes only. In some cases it may be preferable to use more compact notation.

After all the parameters have been specified, we have two contexts open: global and Dhcp4; thus, we need two closing curly brackets to close them.

8.2.2. Lease Storage

All leases issued by the server are stored in the lease database. Currently there are four database backends available: memfile (which is the default backend), MySQL, PostgreSQL, and Cassandra.

8.2.2.1. Memfile - Basic Storage for Leases

The server is able to store lease data in different repositories. Larger deployments may elect to store leases in a database. Lease Database Configuration describes this option. In typical smaller deployments, though, the server will store lease information in a CSV file rather than a database. As well as requiring less administration, an advantage of using a file for storage is that it eliminates a dependency on third-party database software.

The configuration of the file backend (memfile) is controlled through the Dhcp4/lease-database parameters. The type parameter is mandatory and it specifies which storage for leases the server should use. The value of "memfile" indicates that the file should be used as the storage. The following list gives additional optional parameters that can be used to configure the memfile backend.

  • persist: controls whether the new leases and updates to existing leases are written to the file. It is strongly recommended that the value of this parameter be set to true at all times during the server’s normal operation. Not writing leases to disk means that if a server is restarted (e.g. after a power failure), it will not know which addresses have been assigned. As a result, it may assign new clients addresses that are already in use. The value of false is mostly useful for performance-testing purposes. The default value of the persist parameter is true, which enables writing lease updates to the lease file.
  • name: specifies an absolute location of the lease file in which new leases and lease updates will be recorded. The default value for this parameter is "[kea-install-dir]/var/lib/kea/kea-leases4.csv".
  • lfc-interval: specifies the interval, in seconds, at which the server will perform a lease file cleanup (LFC). This removes redundant (historical) information from the lease file and effectively reduces the lease file size. The cleanup process is described in more detail later in this section. The default value of the lfc-interval is 3600. A value of 0 disables the LFC.
  • max-row-errors: when the server loads a lease file, it is processed row by row, each row contaning a single lease. If a row is flawed and cannot be processed correctly the server will log it, discard the row, and go on to the next row. This parameter can be used to set a limit on the number of such discards that may occur after which the server will abandon the effort and exit. The default value of 0 disables the limit and allows the server to process the entire file, regardless of how many rows are discarded.
"Dhcp4": {
    "lease-database": {
        "type": "memfile",
        "persist": true,
        "name": "/tmp/kea-leases4.csv",
        "lfc-interval": 1800,
        "max-row-errors": 100
    }
}

This configuration selects the /tmp/kea-leases4.csv as the storage for lease information and enables persistence (writing lease updates to this file). It also configures the backend to perform a periodic cleanup of the lease file every 30 minutes and sets the maximum number of row errors to 100.

It is important to know how the lease file contents are organized to understand why the periodic lease file cleanup is needed. Every time the server updates a lease or creates a new lease for the client, the new lease information must be recorded in the lease file. For performance reasons, the server does not update the existing client’s lease in the file, as this would potentially require rewriting the entire file. Instead, it simply appends the new lease information to the end of the file; the previous lease entries for the client are not removed. When the server loads leases from the lease file, e.g. at the server startup, it assumes that the latest lease entry for the client is the valid one. The previous entries are discarded, meaning that the server can re-construct the accurate information about the leases even though there may be many lease entries for each client. However, storing many entries for each client results in a bloated lease file and impairs the performance of the server’s startup and reconfiguration, as it needs to process a larger number of lease entries.

Lease file cleanup (LFC) removes all previous entries for each client and leaves only the latest ones. The interval at which the cleanup is performed is configurable, and it should be selected according to the frequency of lease renewals initiated by the clients. The more frequent the renewals, the smaller the value of lfc-interval should be. Note, however, that the LFC takes time and thus it is possible (although unlikely) that, if the lfc-interval is too short, a new cleanup may be started while the previous one is still running. The server would recover from this by skipping the new cleanup when it detected that the previous cleanup was still in progress. But it implies that the actual cleanups will be triggered more rarely than configured. Moreover, triggering a new cleanup adds overhead to the server, which will not be able to respond to new requests for a short period of time when the new cleanup process is spawned. Therefore, it is recommended that the lfc-interval value be selected in a way that allows the LFC to complete the cleanup before a new cleanup is triggered.

Lease file cleanup is performed by a separate process (in the background) to avoid a performance impact on the server process. To avoid conflicts between two processes both using the same lease files, the LFC process starts with Kea opening a new lease file; the actual LFC process operates on the lease file that is no longer used by the server. There are also other files created as a side effect of the lease file cleanup. The detailed description of the LFC process is located later in this Kea Administrator’s Reference Manual: The LFC Process.

8.2.2.2. Lease Database Configuration

Note

Lease database access information must be configured for the DHCPv4 server, even if it has already been configured for the DHCPv6 server. The servers store their information independently, so each server can use a separate database or both servers can use the same database.

Lease database configuration is controlled through the Dhcp4/lease-database parameters. The database type must be set to “memfile”, “mysql”, “postgresql”, or “cql”, e.g.:

"Dhcp4": { "lease-database": { "type": "mysql", ... }, ... }

Next, the name of the database to hold the leases must be set; this is the name used when the database was created (see First-Time Creation of the MySQL Database, First-Time Creation of the PostgreSQL Database, or First-Time Creation of the Cassandra Database).

"Dhcp4": { "lease-database": { "name": "database-name" , ... }, ... }

For Cassandra:

"Dhcp4": { "lease-database": { "keyspace": "database-name" , ... }, ... }

If the database is located on a different system from the DHCPv4 server, the database host name must also be specified:

"Dhcp4": { "lease-database": { "host": "remote-host-name", ... }, ... }

(It should be noted that this configuration may have a severe impact on server performance.)

Normally, the database will be on the same machine as the DHCPv4 server. In this case, set the value to the empty string:

"Dhcp4": { "lease-database": { "host" : "", ... }, ... }

Should the database use a port other than the default, it may be specified as well:

"Dhcp4": { "lease-database": { "port" : 12345, ... }, ... }

Should the database be located on a different system, the administrator may need to specify a longer interval for the connection timeout:

"Dhcp4": { "lease-database": { "connect-timeout" : timeout-in-seconds, ... }, ... }

The default value of five seconds should be more than adequate for local connections. If a timeout is given, though, it should be an integer greater than zero.

The maximum number of times the server will automatically attempt to reconnect to the lease database after connectivity has been lost may be specified:

"Dhcp4": { "lease-database": { "max-reconnect-tries" : number-of-tries, ... }, ... }

If the server is unable to reconnect to the database after making the maximum number of attempts, the server will exit. A value of zero (the default) disables automatic recovery and the server will exit immediately upon detecting a loss of connectivity (MySQL and PostgreSQL only). For Cassandra, Kea uses an interface that connects to all nodes in a cluster at the same time. Any connectivity issues should be handled by internal Cassandra mechanisms.

The number of milliseconds the server will wait between attempts to reconnect to the lease database after connectivity has been lost may also be specified:

"Dhcp4": { "lease-database": { "reconnect-wait-time" : number-of-milliseconds, ... }, ... }

The default value for MySQL and PostgreSQL is 0, which disables automatic recovery and causes the server to exit immediately upon detecting the loss of connectivity. The default value for Cassandra is 2000 ms.

Note

Automatic reconnection to database backends is configured individually per backend. This allows users to tailor the recovery parameters to each backend they use. We do suggest that users enable it either for all backends or none, so behavior is consistent. Losing connectivity to a backend for which reconnect is disabled will result in the server shutting itself down. This includes cases when the lease database backend and the hosts database backend are connected to the same database instance.

Note

Note that the host parameter is used by the MySQL and PostgreSQL backends. Cassandra has a concept of contact points that can be used to contact the cluster, instead of a single IP or hostname. It takes a list of comma-separated IP addresses, which may be specified as:

"Dhcp4": { "lease-database": { "contact-points" : "192.0.2.1,192.0.2.2", ... }, ... }

Finally, the credentials of the account under which the server will access the database should be set:

"Dhcp4": { "lease-database": { "user": "user-name",
                               "password": "password",
                              ... },
           ... }

If there is no password to the account, set the password to the empty string “”. (This is also the default.)

8.2.2.3. Cassandra-Specific Parameters

The Cassandra backend is configured slightly differently. Cassandra has a concept of contact points that can be used to contact the cluster, instead of a single IP or hostname. It takes a list of comma-separated IP addresses, which may be specified as:

"Dhcp4": {
    "lease-database": {
        "type": "cql",
        "contact-points": "ip-address1, ip-address2 [,...]",
        ...
    },
    ...
}

Cassandra also supports a number of optional parameters:

  • reconnect-wait-time - governs how long Kea waits before attempting to reconnect. Expressed in milliseconds. The default is 2000 [ms].
  • connect-timeout - sets the timeout for connecting to a node. Expressed in milliseconds. The default is 5000 [ms].
  • request-timeout - sets the timeout for waiting for a response from a node. Expressed in milliseconds. The default is 12000 [ms].
  • tcp-keepalive - governs the TCP keep-alive mechanism. Expressed in seconds of delay. If the parameter is not present, the mechanism is disabled.
  • tcp-nodelay - enables/disables Nagle’s algorithm on connections. The default is true.
  • consistency - configures consistency level. The default is “quorum”. Supported values: any, one, two, three, quorum, all, local-quorum, each-quorum, serial, local-serial, local-one. See Cassandra consistency for more details.
  • serial-consistency - configures serial consistency level which manages lightweight transaction isolation. The default is “serial”. Supported values: any, one, two, three, quorum, all, local-quorum, each-quorum, serial, local-serial, local-one. See Cassandra serial consistency for more details.

For example, a complex Cassandra configuration with most parameters specified could look as follows:

"Dhcp4": {
  "lease-database": {
      "type": "cql",
      "keyspace": "keatest",
      "contact-points": "192.0.2.1, 192.0.2.2, 192.0.2.3",
      "port": 9042,
      "reconnect-wait-time": 2000,
      "connect-timeout": 5000,
      "request-timeout": 12000,
      "tcp-keepalive": 1,
      "tcp-nodelay": true
    },
    ...
}

Similar parameters can be specified for the hosts database.

8.2.3. Hosts Storage

Kea is also able to store information about host reservations in the database. The hosts database configuration uses the same syntax as the lease database. In fact, a Kea server opens independent connections for each purpose, be it lease or hosts information. This arrangement gives the most flexibility. Kea can keep leases and host reservations separately, but can also point to the same database. Currently the supported hosts database types are MySQL, PostgreSQL, and Cassandra.

Please note that usage of hosts storage is optional. A user can define all host reservations in the configuration file, and that is the recommended way if the number of reservations is small. However, when the number of reservations grows, it is more convenient to use host storage. Please note that both storage methods (configuration file and one of the supported databases) can be used together. If hosts are defined in both places, the definitions from the configuration file are checked first and external storage is checked later, if necessary.

In fact, host information can be placed in multiple stores. Operations are performed on the stores in the order they are defined in the configuration file, although this leads to a restriction in ordering in the case of a host reservation addition; read-only stores must be configured after a (required) read-write store, or the addition will fail.

8.2.3.1. DHCPv4 Hosts Database Configuration

Hosts database configuration is controlled through the Dhcp4/hosts-database parameters. If enabled, the type of database must be set to “mysql” or “postgresql”.

"Dhcp4": { "hosts-database": { "type": "mysql", ... }, ... }

Next, the name of the database to hold the reservations must be set; this is the name used when the lease database was created (see Supported Backends for instructions on how to set up the desired database type):

"Dhcp4": { "hosts-database": { "name": "database-name" , ... }, ... }

If the database is located on a different system than the DHCPv4 server, the database host name must also be specified:

"Dhcp4": { "hosts-database": { "host": remote-host-name, ... }, ... }

(Again, it should be noted that this configuration may have a severe impact on server performance.)

Normally, the database will be on the same machine as the DHCPv4 server. In this case, set the value to the empty string:

"Dhcp4": { "hosts-database": { "host" : "", ... }, ... }

Should the database use a port different than the default, it may be specified as well:

"Dhcp4": { "hosts-database": { "port" : 12345, ... }, ... }

The maximum number of times the server will automatically attempt to reconnect to the host database after connectivity has been lost may be specified:

"Dhcp4": { "hosts-database": { "max-reconnect-tries" : number-of-tries, ... }, ... }

If the server is unable to reconnect to the database after making the maximum number of attempts, the server will exit. A value of zero (the default) disables automatic recovery and the server will exit immediately upon detecting a loss of connectivity (MySQL and PostgreSQL only).

The number of milliseconds the server will wait between attempts to reconnect to the host database after connectivity has been lost may also be specified:

"Dhcp4": { "hosts-database": { "reconnect-wait-time" : number-of-milliseconds, ... }, ... }

The default value for MySQL and PostgreSQL is 0, which disables automatic recovery and causes the server to exit immediately upon detecting the loss of connectivity. The default value for Cassandra is 2000 ms.

Note

Automatic reconnection to database backends is configured individually per backend. This allows users to tailor the recovery parameters to each backend they use. We do suggest that users enable it either for all backends or none, so behavior is consistent. Losing connectivity to a backend for which reconnect is disabled will result in the server shutting itself down. This includes cases when the lease database backend and the hosts database backend are connected to the same database instance.

Finally, the credentials of the account under which the server will access the database should be set:

"Dhcp4": { "hosts-database": { "user": "user-name",
                               "password": "password",
                              ... },
           ... }

If there is no password to the account, set the password to the empty string “”. (This is also the default.)

The multiple storage extension uses a similar syntax; a configuration is placed into a “hosts-databases” list instead of into a “hosts-database” entry, as in:

"Dhcp4": { "hosts-databases": [ { "type": "mysql", ... }, ... ], ... }

For additional Cassandra-specific parameters, see Cassandra-Specific Parameters.

8.2.3.2. Using Read-Only Databases for Host Reservations with DHCPv4

In some deployments the database user whose name is specified in the database backend configuration may not have write privileges to the database. This is often required by the policy within a given network to secure the data from being unintentionally modified. In many cases administrators have deployed inventory databases, which contain substantially more information about the hosts than just the static reservations assigned to them. The inventory database can be used to create a view of a Kea hosts database and such a view is often read-only.

Kea host database backends operate with an implicit configuration to both read from and write to the database. If the database user does not have write access to the host database, the backend will fail to start and the server will refuse to start (or reconfigure). However, if access to a read-only host database is required for retrieving reservations for clients and/or assigning specific addresses and options, it is possible to explicitly configure Kea to start in “read-only” mode. This is controlled by the readonly boolean parameter as follows:

"Dhcp4": { "hosts-database": { "readonly": true, ... }, ... }

Setting this parameter to false configures the database backend to operate in “read-write” mode, which is also the default configuration if the parameter is not specified.

Note

The readonly parameter is currently only supported for MySQL and PostgreSQL databases.

8.2.4. Interface Configuration

The DHCPv4 server must be configured to listen on specific network interfaces. The simplest network interface configuration tells the server to listen on all available interfaces:

"Dhcp4": {
    "interfaces-config": {
        "interfaces": [ "*" ]
    }
    ...
},

The asterisk plays the role of a wildcard and means “listen on all interfaces.” However, it is usually a good idea to explicitly specify interface names:

"Dhcp4": {
    "interfaces-config": {
        "interfaces": [ "eth1", "eth3" ]
    },
    ...
}

It is possible to use a wildcard interface name (asterisk) concurrently with explicit interface names:

"Dhcp4": {
    "interfaces-config": {
        "interfaces": [ "eth1", "eth3", "*" ]
    },
    ...
}

It is anticipated that this form of usage will only be used when it is desired to temporarily override a list of interface names and listen on all interfaces.

Some deployments of DHCP servers require that the servers listen on interfaces with multiple IPv4 addresses configured. In these situations, the address to use can be selected by appending an IPv4 address to the interface name in the following manner:

"Dhcp4": {
    "interfaces-config": {
        "interfaces": [ "eth1/10.0.0.1", "eth3/192.0.2.3" ]
    },
    ...
}

Should the server be required to listen on multiple IPv4 addresses assigned to the same interface, multiple addresses can be specified for an interface as in the example below:

"Dhcp4": {
    "interfaces-config": {
        "interfaces": [ "eth1/10.0.0.1", "eth1/10.0.0.2" ]
    },
    ...
}

Alternatively, if the server should listen on all addresses for the particular interface, an interface name without any address should be specified.

Kea supports responding to directly connected clients which don’t have an address configured. This requires the server to inject the hardware address of the destination into the data link layer of the packet being sent to the client. The DHCPv4 server uses raw sockets to achieve this, and builds the entire IP/UDP stack for the outgoing packets. The downside of raw socket use, however, is that incoming and outgoing packets bypass the firewalls (e.g. iptables).

Handling traffic on multiple IPv4 addresses assigned to the same interface can be a challenge, as raw sockets are bound to the interface. When the DHCP server is configured to use the raw socket on an interface to receive DHCP traffic, advanced packet filtering techniques (e.g. the BPF) must be used to receive unicast traffic on the desired addresses assigned to the interface. Whether clients use the raw socket or the UDP socket depends on whether they are directly connected (raw socket) or relayed (either raw or UDP socket).

Therefore, in deployments where the server does not need to provision the directly connected clients and only receives the unicast packets from the relay agents, the DHCP server should be configured to use UDP sockets instead of raw sockets. The following configuration demonstrates how this can be achieved:

"Dhcp4": {
    "interfaces-config": {
        "interfaces": [ "eth1", "eth3" ],
        "dhcp-socket-type": "udp"
    },
    ...
}

The dhcp-socket-type specifies that the IP/UDP sockets will be opened on all interfaces on which the server listens, i.e. “eth1” and “eth3” in our case. If dhcp-socket-type is set to raw, it configures the server to use raw sockets instead. If the dhcp-socket-type value is not specified, the default value raw is used.

Using UDP sockets automatically disables the reception of broadcast packets from directly connected clients. This effectively means that UDP sockets can be used for relayed traffic only. When using raw sockets, both the traffic from the directly connected clients and the relayed traffic are handled. Caution should be taken when configuring the server to open multiple raw sockets on the interface with several IPv4 addresses assigned. If the directly connected client sends the message to the broadcast address, all sockets on this link will receive this message and multiple responses will be sent to the client. Therefore, the configuration with multiple IPv4 addresses assigned to the interface should not be used when the directly connected clients are operating on that link. To use a single address on such interface, the “interface-name/address” notation should be used.

Note

Specifying the value raw as the socket type doesn’t guarantee that the raw sockets will be used! The use of raw sockets to handle the traffic from the directly connected clients is currently supported on Linux and BSD systems only. If the raw sockets are not supported on the particular OS in use, the server will issue a warning and fall back to using IP/UDP sockets.

In a typical environment, the DHCP server is expected to send back a response on the same network interface on which the query was received. This is the default behavior. However, in some deployments it is desired that the outbound (response) packets will be sent as regular traffic and the outbound interface will be determined by the routing tables. This kind of asymmetric traffic is uncommon, but valid. Kea supports a parameter called outbound-interface that controls this behavior. It supports two values; the first one, same-as-inbound, tells Kea to send back the response on the same interface where the query packet was received. This is the default behavior. The second one, use-routing, tells Kea to send regular UDP packets and let the kernel’s routing table determine the most appropriate interface. This only works when dhcp-socket-type is set to udp. An example configuration looks as follows:

"Dhcp4": {
    "interfaces-config": {
        "interfaces": [ "eth1", "eth3" ],
        "dhcp-socket-type": "udp",
        "outbound-interface": "use-routing"
    },
    ...
}

Interfaces are re-detected at each reconfiguration. This behavior can be disabled by setting the re-detect value to false, for instance:

"Dhcp4": {
    "interfaces-config": {
        "interfaces": [ "eth1", "eth3" ],
        "re-detect": false
    },
    ...
}

Note that interfaces are not re-detected during config-test.

Usually loopback interfaces (e.g. the “lo” or “lo0” interface) may not be configured, but if a loopback interface is explicitely configured and IP/UDP sockets are specified, the loopback interface is accepted.

For example, it can be used to run Kea in a FreeBSD jail having on