dhcp4-srv.rst 267 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
.. _dhcp4:

*****************
The DHCPv4 Server
*****************

.. _dhcp4-start-stop:

Starting and Stopping the DHCPv4 Server
=======================================

It is recommended that the Kea DHCPv4 server be started and stopped
13
using ``keactrl`` (described in :ref:`keactrl`); however, it is also
14 15 16 17 18 19 20 21
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
22
   debuglevel specified in the configuration file are ignored;
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
   "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
58
requires root access. This daemon must be run as root.
59 60

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

63 64
-  ``runstatedir``: The value as passed into the build configure
   script; it defaults to "/usr/local/var/run". Note that this value may be
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
   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.

.. _dhcp4-configuration:

DHCPv4 Server Configuration
===========================

Introduction
------------

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

::

   {
99
   # DHCPv4 configuration starts on the next line
100 101 102 103 104 105 106
   "Dhcp4": {

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

107
   # Next we set up the interfaces to be used by the server.
108 109 110 111 112 113 114 115
       "interfaces-config": {
           "interfaces": [ "eth0" ]
       },

   # And we specify the type of lease database
       "lease-database": {
           "type": "memfile",
           "persist": true,
116
           "name": "/var/lib/kea/dhcp4.leases"
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
       },

   # 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``.

147
.. note::
148 149 150

   In the current Kea release it is possible to specify configurations
   of multiple modules within a single configuration file, but this is
151 152
   not recommended and support for it will be removed in a future
   release. The only object, besides the one specifying module
153
   configuration, which can be (and usually was) included in the same file
154
   is ``Logging``. However, we don't include this object in the example
155
   above for clarity; its content, the list of loggers, should now be
156 157 158 159 160 161 162
   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.

163
In general, the order in which those parameters appear does not
164 165
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
166
parameters for any given scope must be separated by a comma, and there
167 168 169 170 171 172 173 174
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
175
in the configuration file.
176

177
The first few DHCPv4 configuration elements
178 179 180 181 182 183 184 185
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.

186 187
.. note::

188
   Beginning with Kea 1.6.0 the lease valid lifetime is extended from a
189 190 191 192
   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
193
   code 51 this value is used if it is not less than the  minimum (in this case
194 195 196
   the minimum is returned) or greater than the maximum (in this case the
   maximum is used).

197
.. note::
198

199 200 201 202 203
   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
204
   specified). In their absence, the client should select values for T1
205
   and T2 timers according to `RFC 2131 <https://tools.ietf.org/html/rfc2131>`_.
206
   See section :ref:`dhcp4-t1-t2-times`
207 208 209
   for more details on generating T1 and T2.

The ``interfaces-config`` map specifies the server configuration
210
concerning the network interfaces on which the server should listen to
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
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
227
CSV (comma-separated values) file. This is a very simple configuration; usually the lease
228 229
database configuration is more extensive and contains additional
parameters. Note that ``lease-database`` is an object and opens up a new
230 231
scope, using an opening brace. Its parameters (just one in this example:
``type``) follow. If there were more than one, they would be separated
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
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:
273
global and Dhcp4; thus, we need two closing curly brackets to close
274 275 276 277 278 279 280 281 282 283 284 285 286
them.

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.

Memfile - Basic Storage for Leases
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The server is able to store lease data in different repositories. Larger
287
deployments may elect to store leases in a database.
288 289
:ref:`database-configuration4` describes this option. In
typical smaller deployments, though, the server will store lease
290 291 292 293
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.

294
The configuration of the file backend (memfile) is controlled through
295 296 297 298
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
299
can be used to configure the memfile backend.
300 301 302

-  ``persist``: controls whether the new leases and updates to existing
   leases are written to the file. It is strongly recommended that the
303
   value of this parameter be set to ``true`` at all times during the
304 305
   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
306 307
   which addresses have been assigned. As a result, it may assign new clients
   addresses that are already in use. The value of
308 309 310 311 312 313
   ``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
314
   this parameter is ``"[kea-install-dir]/var/lib/kea/kea-leases4.csv"``.
315 316 317 318 319

-  ``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
320
   described in more detail later in this section. The default
321 322 323
   value of the ``lfc-interval`` is ``3600``. A value of 0 disables the
   LFC.

324 325 326 327 328 329 330 331
-  ``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.
332 333 334 335 336 337 338 339

::

   "Dhcp4": {
       "lease-database": {
           "type": "memfile",
           "persist": true,
           "name": "/tmp/kea-leases4.csv",
340 341
           "lfc-interval": 1800,
           "max-row-errors": 100
342 343 344 345 346 347
       }
   }

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
348 349
of the lease file every 30 minutes and sets the maximum number of row
errors to 100.
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375

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
376 377
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
378 379 380 381
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
382
``lfc-interval`` value be selected in a way that allows the LFC
383 384 385 386
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
387 388
avoid conflicts between two processes both using the same lease
files, the LFC process starts with Kea opening a new lease file; the
389 390
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
391
lease file cleanup. The detailed description of the LFC process is located later
392
in this Kea Administrator's Reference Manual: :ref:`kea-lfc`.
393 394 395 396 397 398

.. _database-configuration4:

Lease Database Configuration
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

399
.. note::
400 401 402 403 404 405 406

   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
407
Dhcp4/lease-database parameters. The database type must be set to
408 409 410 411 412 413 414 415
"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
416 417
:ref:`mysql-database-create`, :ref:`pgsql-database-create`, or
:ref:`cql-database-create`).
418 419 420 421 422 423 424 425 426 427 428 429

::

   "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,
430
the database host name must also be specified:
431 432 433 434 435

::

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

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

438 439 440 441 442 443 444
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" : "", ... }, ... }

445
Should the database use a port other than the default, it may be
446 447 448 449 450 451
specified as well:

::

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

452
Should the database be located on a different system, the administrator may need to
453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471
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
472
maximum number of attempts, the server will exit. A value of zero (the
473
default) disables automatic recovery and the server will exit
474 475
immediately upon detecting a loss of connectivity (MySQL and PostgreSQL
only). For Cassandra, Kea uses an interface that connects to
476 477 478 479 480 481 482 483 484 485 486
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, ... }, ... }

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

491
.. note::
492 493

   Automatic reconnection to database backends is configured
494 495 496 497
   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
498 499 500 501 502 503
   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.

..

504
.. note::
505

506
   Note that the host parameter is used by the MySQL and PostgreSQL backends.
507
   Cassandra has a concept of contact points that can be used to
508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532
   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.)

.. _cassandra-database-configuration4:

Cassandra-Specific Parameters
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The Cassandra backend is configured slightly differently. Cassandra has
533
a concept of contact points that can be used to contact the cluster,
534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569
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
570 571
   `Cassandra
   consistency <https://docs.datastax.com/en/cassandra/3.0/cassandra/dml/dmlConfigConsistency.html>`__
572 573 574 575 576
   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,
577 578
   each-quorum, serial, local-serial, local-one. See `Cassandra serial
   consistency <https://docs.datastax.com/en/cassandra/3.0/cassandra/dml/dmlConfigSerialConsistency.html>`__
579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626
   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.

.. _hosts4-storage:

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
627
configuration file, although this leads to a restriction in ordering
628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646
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.

.. _hosts-databases-configuration4:

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
647 648
:ref:`supported-databases` for instructions on how to set up the
desired database type):
649 650 651 652 653 654

::

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

If the database is located on a different system than the DHCPv4 server,
655
the database host name must also be specified:
656 657 658 659 660

::

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

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

663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685
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
686
maximum number of attempts, the server will exit. A value of zero (the
687
default) disables automatic recovery and the server will exit
688
immediately upon detecting a loss of connectivity (MySQL and PostgreSQL
689 690 691 692 693 694 695 696 697 698
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, ... }, ... }

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

703
.. note::
704 705

   Automatic reconnection to database backends is configured
706 707 708 709
   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
710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728
   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"
729
entry, as in:
730 731 732 733 734

::

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

735
For additional Cassandra-specific parameters, see
736
:ref:`cassandra-database-configuration4`.
737 738 739

.. _read-only-database-configuration4:

740 741
Using Read-Only Databases for Host Reservations with DHCPv4
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
742 743 744 745 746 747 748 749 750 751 752 753 754 755 756

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
757
to a read-only host database is required for retrieving reservations
758 759 760 761 762 763 764 765 766 767 768 769
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.

770
.. note::
771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859

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

.. _dhcp4-interface-configuration:

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
860 861 862 863
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
864
outgoing packets bypass the firewalls (e.g. iptables).
865 866 867 868 869 870 871 872 873 874 875 876 877 878 879

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:
880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912

::

   "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.

913
.. note::
914 915 916 917 918

   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
919
   supported on the particular OS in use, the server will issue a warning and
920 921 922 923 924 925 926
   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
927
kind of asymmetric traffic is uncommon, but valid. Kea supports a
928
parameter called ``outbound-interface`` that controls this behavior. It
929
supports two values; the first one, ``same-as-inbound``, tells Kea to
930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987
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 only a
loopback interface, to service a relayed DHCP request:

::

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

.. _dhcpinform-unicast-issues:

Issues with Unicast Responses to DHCPINFORM
-------------------------------------------

The use of UDP sockets has certain benefits in deployments where the
server receives only relayed traffic; these benefits are mentioned in
988
:ref:`dhcp4-interface-configuration`. From the
989
administrator's perspective it is often desirable to configure the
990
system's firewall to filter out unwanted traffic, and the use of UDP
991 992 993 994 995
sockets facilitates this. However, the administrator must also be aware
of the implications related to filtering certain types of traffic, as it
may impair the DHCP server's operation.

In this section we are focusing on the case when the server receives the
996 997
DHCPINFORM message from the client via a relay. According to `RFC
2131 <https://tools.ietf.org/html/rfc2131>`__, the server should unicast
998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008
the DHCPACK response to the address carried in the "ciaddr" field. When
the UDP socket is in use, the DHCP server relies on the low-level
functions of an operating system to build the data link, IP, and UDP
layers of the outgoing message. Typically, the OS will first use ARP to
obtain the client's link-layer address to be inserted into the frame's
header, if the address is not cached from a previous transaction that
the client had with the server. When the ARP exchange is successful, the
DHCP message can be unicast to the client, using the obtained address.

Some system administrators block ARP messages in their network, which
causes issues for the server when it responds to the DHCPINFORM
1009
messages because the server is unable to send the DHCPACK if the
1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020
preceding ARP communication fails. Since the OS is entirely responsible
for the ARP communication and then sending the DHCP packet over the
wire, the DHCP server has no means to determine that the ARP exchange
failed and the DHCP response message was dropped. Thus, the server does
not log any error messages when the outgoing DHCP response is dropped.
At the same time, all hooks pertaining to the packet-sending operation
will be called, even though the message never reaches its destination.

Note that the issue described in this section is not observed when the
raw sockets are in use, because, in this case, the DHCP server builds
all the layers of the outgoing message on its own and does not use ARP.
1021
Instead, it inserts the value carried in the "chaddr" field of the
1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048
DHCPINFORM message into the link layer.

Server administrators willing to support DHCPINFORM messages via relays
should not block ARP traffic in their networks or should use raw sockets
instead of UDP sockets.

.. _ipv4-subnet-id:

IPv4 Subnet Identifier
----------------------

The subnet identifier is a unique number associated with a particular
subnet. In principle, it is used to associate clients' leases with their
respective subnets. When a subnet identifier is not specified for a
subnet being configured, it will be automatically assigned by the
configuration mechanism. The identifiers are assigned from 1 and are
monotonically increased for each subsequent subnet: 1, 2, 3 ....

If there are multiple subnets configured with auto-generated identifiers
and one of them is removed, the subnet identifiers may be renumbered.
For example: if there are four subnets and the third is removed, the
last subnet will be assigned the identifier that the third subnet had
before removal. As a result, the leases stored in the lease database for
subnet 3 are now associated with subnet 4, something that may have
unexpected consequences. The only remedy for this issue at present is to
manually specify a unique identifier for each subnet.

1049
.. note::
1050 1051 1052 1053

   Subnet IDs must be greater than zero and less than 4294967295.

The following configuration will assign the specified subnet identifier
1054
to a newly configured subnet:
1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071

::

   "Dhcp4": {
       "subnet4": [
           {
               "subnet": "192.0.2.0/24",
               "id": 1024,
               ...
           }
       ]
   }

This identifier will not change for this subnet unless the "id"
parameter is removed or set to 0. The value of 0 forces auto-generation
of the subnet identifier.

1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082
.. _ipv4-subnet-prefix:

IPv4 Subnet Prefix
------------------

The subnet prefix is the second way to identify a subnet. It does not
need to have the address part to match the prefix length, for instance
this configuration is accepted:

::

Michal Nowikowski's avatar
Michal Nowikowski committed
1083 1084 1085 1086 1087 1088 1089 1090
   "Dhcp4": {
       "subnet4": [
           {
              "subnet": "192.0.2.1/24",
               ...
           }
       ]
   }
1091 1092 1093 1094 1095 1096 1097 1098 1099

Even there is another subnet with the "192.0.2.0/24" prefix: only the
textual form of subnets are compared to avoid duplicates.

.. note::

    Abuse of this feature can lead to incorrect subnet selection
    (see :ref:`dhcp4-subnet-selection`).

1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195
.. _dhcp4-address-config:

Configuration of IPv4 Address Pools
-----------------------------------

The main role of a DHCPv4 server is address assignment. For this, the
server must be configured with at least one subnet and one pool of
dynamic addresses to be managed. For example, assume that the server is
connected to a network segment that uses the 192.0.2.0/24 prefix. The
administrator of that network decides that addresses from range
192.0.2.10 to 192.0.2.20 are going to be managed by the Dhcp4 server.
Such a configuration can be achieved in the following way:

::

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

Note that ``subnet`` is defined as a simple string, but the ``pools``
parameter is actually a list of pools; for this reason, the pool
definition is enclosed in square brackets, even though only one range of
addresses is specified.

Each ``pool`` is a structure that contains the parameters that describe
a single pool. Currently there is only one parameter, ``pool``, which
gives the range of addresses in the pool.

It is possible to define more than one pool in a subnet; continuing the
previous example, further assume that 192.0.2.64/26 should be also be
managed by the server. It could be written as 192.0.2.64 to 192.0.2.127.
Alternatively, it can be expressed more simply as 192.0.2.64/26. Both
formats are supported by Dhcp4 and can be mixed in the pool list. For
example, one could define the following pools:

::

   "Dhcp4": {
       "subnet4": [
           {
               "subnet": "192.0.2.0/24",
               "pools": [
                   { "pool": "192.0.2.10-192.0.2.20" },
                   { "pool": "192.0.2.64/26" }
               ],
               ...
           }
       ],
       ...
   }

White space in pool definitions is ignored, so spaces before and after
the hyphen are optional. They can be used to improve readability.

The number of pools is not limited, but for performance reasons it is
recommended to use as few as possible.

The server may be configured to serve more than one subnet:

::

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

When configuring a DHCPv4 server using prefix/length notation, please
pay attention to the boundary values. When specifying that the server
can use a given pool, it will also be able to allocate the first
(typically a network address) and the last (typically a broadcast
address) address from that pool. In the aforementioned example of pool
192.0.3.0/24, both the 192.0.3.0 and 192.0.3.255 addresses may be
assigned as well. This may be invalid in some network configurations. To
1196
avoid this, use the "min-max" notation.
1197 1198 1199 1200 1201 1202

.. _dhcp4-t1-t2-times:

Sending T1 (Option 58) and T2 (Option 59)
-----------------------------------------

1203
According to `RFC 2131 <https://tools.ietf.org/html/rfc2131>`__,
1204
servers should send values for T1 and T2 that are 50% and 87.5% of the
1205
lease lifetime, respectively. By default, kea-dhcp4 does not send
1206 1207
either value. It can be configured to send values that are specified
explicitly or that are calculated as percentages of the lease time. The
1208
server's behavior is governed by a combination of configuration
1209 1210 1211 1212 1213 1214 1215
parameters, two of which have already been mentioned.
To send specific, fixed values use the following two parameters:

-  ``renew-timer`` - specifies the value of T1 in seconds.

-  ``rebind-timer`` - specifies the value of T2 in seconds.

1216 1217
The server will only send T2 if it is less than the valid lease time. T1
will only be sent if: T2 is being sent and T1 is less than T2; or T2
1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234
is not being sent and T1 is less than the valid lease time.

Calculating the values is controlled by the following three parameters.

-  ``calculate-tee-times`` - when true, T1 and T2 will be calculated as
   percentages of the valid lease time. It defaults to false.

-  ``t1-percent`` - the percentage of the valid lease time to use for
   T1. It is expressed as a real number between 0.0 and 1.0 and must be
   less than t2-percent. The default value is 0.50 per RFC 2131.

-  ``t2-percent`` - the percentage of the valid lease time to use for
   T2. It is expressed as a real number between 0.0 and 1.0 and must be
   greater than t1-percent. The default value is .875 per RFC 2131.

..

1235
.. note::
1236 1237 1238

   In the event that both explicit values are specified and
   calculate-tee-times is true, the server will use the explicit values.
1239 1240
   Administrators with a setup where some subnets or share-networks
   will use explicit values and some will use calculated values must
1241
   not define the explicit values at any level higher than where they
1242
   will be used. Inheriting them from too high a scope, such as
1243 1244 1245 1246 1247 1248 1249 1250 1251
   global, will cause them to have values at every level underneath
   (shared-networks and subnets), effectively disabling calculated
   values.

.. _dhcp4-std-options:

Standard DHCPv4 Options
-----------------------

1252
One of the major features of the DHCPv4 server is the ability to provide
1253 1254 1255 1256 1257 1258 1259 1260
configuration options to clients. Most of the options are sent by the
server only if the client explicitly requests them using the Parameter
Request List option. Those that do not require inclusion in the
Parameter Request List option are commonly used options, e.g. "Domain
Server", and options which require special behavior, e.g. "Client FQDN",
which is returned to the client if the client has included this option
in its message to the server.

1261
:ref:`dhcp4-std-options-list` comprises the list of the
1262 1263 1264
standard DHCPv4 options whose values can be configured using the
configuration structures described in this section. This table excludes
the options which require special processing and thus cannot be
1265
configured with fixed values. The last column of the table
1266
indicates which options can be sent by the server even when they are not
1267
requested in the Parameter Request List option, and those which are sent
1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290
only when explicitly requested.

The following example shows how to configure the addresses of DNS
servers, which is one of the most frequently used options. Options
specified in this way are considered global and apply to all configured
subnets.

::

   "Dhcp4": {
       "option-data": [
           {
              "name": "domain-name-servers",
              "code": 6,
              "space": "dhcp4",
              "csv-format": true,
              "data": "192.0.2.1, 192.0.2.2"
           },
           ...
       ]
   }


1291 1292 1293
Note that only one of name or code is required; there is no need to
specify both. Space has a default value of "dhcp4", so this can be skipped
as well if a regular (not encapsulated) DHCPv4 option is defined.
1294
Finally, csv-format defaults to true, so it too can be skipped, unless
1295
the option value is specified as a hexadecimal string. Therefore,
1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312
the above example can be simplified to:

::

   "Dhcp4": {
       "option-data": [
           {
              "name": "domain-name-servers",
              "data": "192.0.2.1, 192.0.2.2"
           },
           ...
       ]
   }


Defined options are added to the response when the client requests them
at a few exceptions, which are always added. To enforce the addition of
1313
a particular option, set the always-send flag to true as in:
1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361

::

   "Dhcp4": {
       "option-data": [
           {
              "name": "domain-name-servers",
              "data": "192.0.2.1, 192.0.2.2",
              "always-send": true
           },
           ...
       ]
   }


The effect is the same as if the client added the option code in the
Parameter Request List option (or its equivalent for vendor options):

::

   "Dhcp4": {
       "option-data": [
           {
              "name": "domain-name-servers",
              "data": "192.0.2.1, 192.0.2.2",
              "always-send": true
           },
           ...
       ],
       "subnet4": [
           {
              "subnet": "192.0.3.0/24",
              "option-data": [
                  {
                      "name": "domain-name-servers",
                      "data": "192.0.3.1, 192.0.3.2"
                  },
                  ...
              ],
              ...
           },
           ...
       ],
       ...
   }


The Domain Name Servers option is always added to responses (the
1362
always-send is "sticky"), but the value is the subnet one when the client
1363 1364 1365
is localized in the subnet.

The ``name`` parameter specifies the option name. For a list of
1366
currently supported names, see :ref:`dhcp4-std-options-list`
1367 1368 1369 1370
below. The ``code`` parameter specifies the option code, which must
match one of the values from that list. The next line specifies the
option space, which must always be set to "dhcp4" as these are standard
DHCPv4 options. For other option spaces, including custom option spaces,
1371
see :ref:`dhcp4-option-spaces`. The next line specifies the format in
1372 1373
which the data will be entered; use of CSV (comma-separated values) is
recommended. The sixth line gives the actual value to be sent to
1374
clients. The data parameter is specified as normal text, with values separated by
1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400
commas if more than one value is allowed.

Options can also be configured as hexadecimal values. If ``csv-format``
is set to false, option data must be specified as a hexadecimal string.
The following commands configure the domain-name-servers option for all
subnets with the following addresses: 192.0.3.1 and 192.0.3.2. Note that
``csv-format`` is set to false.

::

   "Dhcp4": {
       "option-data": [
           {
               "name": "domain-name-servers",
               "code": 6,
               "space": "dhcp4",
               "csv-format": false,
               "data": "C0 00 03 01 C0 00 03 02"
           },
           ...
       ],
       ...
   }

Kea supports the following formats when specifying hexadecimal data:

1401
-  ``Delimited octets`` - one or more octets separated by either colons or
1402 1403 1404 1405
   spaces (':' or ' '). While each octet may contain one or two digits,
   we strongly recommend always using two digits. Valid examples are
   "ab:cd:ef" and "ab cd ef".

1406
-  ``String of digits`` - a continuous string of hexadecimal digits with
1407 1408 1409
   or without a "0x" prefix. Valid examples are "0xabcdef" and "abcdef".

Care should be taken to use proper encoding when using hexadecimal
1410
format; Kea's ability to validate data correctness in hexadecimal is
1411 1412
limited.

1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433

As of Kea 1.6.0, it is also possible to specify data for binary options as
a single-quoted text string within double quotes as shown (note that
``csv-format`` must be set to false):

::

   "Dhcp4": {
       "option-data": [
           {
               "name": "user-class",
               "code": 77,
               "space": "dhcp4",
               "csv-format": false,
               "data": "'convert this text to binary'"
           },
           ...
       ],
       ...
   }

1434
Most of the parameters in the "option-data" structure are optional and
1435
can be omitted in some circumstances, as discussed in :ref:`dhcp4-option-data-defaults`.
1436 1437

It is possible to specify or override options on a per-subnet basis. If
1438 1439
clients connected to most subnets are expected to get the same
values of a given option, administrators should use global options; it is possible to
1440
override specific values for a small number of subnets. On the other
1441 1442 1443
hand, if different values are used in each subnet, it does not make sense
to specify global option values; rather, only
subnet-specific ones should be set.
1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470

The following commands override the global DNS servers option for a
particular subnet, setting a single DNS server with address 192.0.2.3:

::

   "Dhcp4": {
       "subnet4": [
           {
               "option-data": [
                   {
                       "name": "domain-name-servers",
                       "code": 6,
                       "space": "dhcp4",
                       "csv-format": true,
                       "data": "192.0.2.3"
                   },
                   ...
               ],
               ...
           },
           ...
       ],
       ...
   }

In some cases it is useful to associate some options with an address
1471
pool from which a client is assigned a lease. Pool-specific option
1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511
values override subnet-specific and global option values. The server's
administrator must not try to prioritize assignment of pool-specific
options by trying to order pool declarations in the server
configuration.

The following configuration snippet demonstrates how to specify the DNS
servers option, which will be assigned to a client only if the client
obtains an address from the given pool:

::

   "Dhcp4": {
       "subnet4": [
           {
               "pools": [
                   {
                       "pool": "192.0.2.1 - 192.0.2.200",
                       "option-data": [
                           {
                               "name": "domain-name-servers",
                               "data": "192.0.2.3"
                            },
                            ...
                       ],
                       ...
                   },
                   ...
               ],
               ...
           },
           ...
       ],
       ...
   }

Options can also be specified in class or host reservation scope. The
current Kea options precedence order is (from most important): host
reservation, pool, subnet, shared network, class, global.

The currently supported standard DHCPv4 options are listed in
1512
:ref:`dhcp4-std-options-list`. "Name" and "Code" are the
1513 1514
values that should be used as a name/code in the option-data structures.
"Type" designates the format of the data; the meanings of the various
1515
types are given in :ref:`dhcp-types`.
1516 1517 1518 1519 1520 1521

When a data field is a string and that string contains the comma (,;
U+002C) character, the comma must be escaped with two backslashes (\;
U+005C). This double escape is required because both the routine
splitting CSV data into fields and JSON use the same escape character; a
single escape (\,) would make the JSON invalid. For example, the string
1522
"foo,bar" must be represented as:
1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551

::

   "Dhcp4": {
       "subnet4": [
           {
               "pools": [
                   {
                       "option-data": [
                           {
                               "name": "boot-file-name",
                               "data": "foo\\,bar"
                           }
                       ]
                   },
                   ...
               ],
               ...
           },
           ...
       ],
       ...
   }

Some options are designated as arrays, which means that more than one
value is allowed in such an option. For example, the option time-servers
allows the specification of more than one IPv4 address, enabling clients
to obtain the addresses of multiple NTP servers.

1552
:ref:`dhcp4-custom-options` describes the
1553 1554 1555 1556 1557 1558
configuration syntax to create custom option definitions (formats).
Creation of custom definitions for standard options is generally not
permitted, even if the definition being created matches the actual
option format defined in the RFCs. There is an exception to this rule
for standard options for which Kea currently does not provide a
definition. In order to use such options, a server administrator must
1559
create a definition as described in
1560
:ref:`dhcp4-custom-options` in the "dhcp4" option space. This
1561 1562 1563 1564
definition should match the option format described in the relevant RFC,
but the configuration mechanism will allow any option format as it
currently has no means to validate it.

1565 1566
.. _dhcp4-std-options-list:

1567 1568
.. table:: List of Standard DHCPv4 Options

Michal Nowikowski's avatar
Michal Nowikowski committed
1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | Name                                   | Code | Type                      | Array?      | Returned if |
   |                                        |      |                           |             | not         |
   |                                        |      |                           |             | requested?  |
   +========================================+======+===========================+=============+=============+
   | time-offset                            | 2    | int32                     | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | routers                                | 3    | ipv4-address              | true        | true        |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | time-servers                           | 4    | ipv4-address              | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | name-servers                           | 5    | ipv4-address              | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | domain-name-servers                    | 6    | ipv4-address              | true        | true        |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | log-servers                            | 7    | ipv4-address              | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | cookie-servers                         | 8    | ipv4-address              | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | lpr-servers                            | 9    | ipv4-address              | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | impress-servers                        | 10   | ipv4-address              | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | resource-location-servers              | 11   | ipv4-address              | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | boot-size                              | 13   | uint16                    | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | merit-dump                             | 14   | string                    | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | domain-name                            | 15   | fqdn                      | false       | true        |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | swap-server                            | 16   | ipv4-address              | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | root-path                              | 17   | string                    | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | extensions-path                        | 18   | string                    | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | ip-forwarding                          | 19   | boolean                   | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | non-local-source-routing               | 20   | boolean                   | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | policy-filter                          | 21   | ipv4-address              | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | max-dgram-reassembly                   | 22   | uint16                    | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | default-ip-ttl                         | 23   | uint8                     | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | path-mtu-aging-timeout                 | 24   | uint32                    | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | path-mtu-plateau-table                 | 25   | uint16                    | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | interface-mtu                          | 26   | uint16                    | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | all-subnets-local                      | 27   | boolean                   | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | broadcast-address                      | 28   | ipv4-address              | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | perform-mask-discovery                 | 29   | boolean                   | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | mask-supplier                          | 30   | boolean                   | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | router-discovery                       | 31   | boolean                   | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | router-solicitation-address            | 32   | ipv4-address              | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | static-routes                          | 33   | ipv4-address              | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | trailer-encapsulation                  | 34   | boolean                   | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | arp-cache-timeout                      | 35   | uint32                    | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | ieee802-3-encapsulation                | 36   | boolean                   | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | default-tcp-ttl                        | 37   | uint8                     | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | tcp-keepalive-interval                 | 38   | uint32                    | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | tcp-keepalive-garbage                  | 39   | boolean                   | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | nis-domain                             | 40   | string                    | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | nis-servers                            | 41   | ipv4-address              | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | ntp-servers                            | 42   | ipv4-address              | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | vendor-encapsulated-options            | 43   | empty                     | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | netbios-name-servers                   | 44   | ipv4-address              | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | netbios-dd-server                      | 45   | ipv4-address              | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | netbios-node-type                      | 46   | uint8                     | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | netbios-scope                          | 47   | string                    | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | font-servers                           | 48   | ipv4-address              | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | x-display-manager                      | 49   | ipv4-address              | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | dhcp-option-overload                   | 52   | uint8                     | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | dhcp-server-identifier                 | 54   | ipv4-address              | false       | true        |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | dhcp-message                           | 56   | string                    | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | dhcp-max-message-size                  | 57   | uint16                    | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | vendor-class-identifier                | 60   | string                    | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | nwip-domain-name                       | 62   | string                    | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | nwip-suboptions                        | 63   | binary                    | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | nisplus-domain-name                    | 64   | string                    | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | nisplus-servers                        | 65   | ipv4-address              | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | tftp-server-name                       | 66   | string                    | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | boot-file-name                         | 67   | string                    | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | mobile-ip-home-agent                   | 68   | ipv4-address              | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | smtp-server                            | 69   | ipv4-address              | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | pop-server                             | 70   | ipv4-address              | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | nntp-server                            | 71   | ipv4-address              | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | www-server                             | 72   | ipv4-address              | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | finger-server                          | 73   | ipv4-address              | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | irc-server                             | 74   | ipv4-address              | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | streettalk-server                      | 75   | ipv4-address              | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | streettalk-directory-assistance-server | 76   | ipv4-address              | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | user-class                             | 77   | binary                    | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | slp-directory-agent                    | 78   | record (boolean,          | true        | false       |
Michal Nowikowski's avatar
Michal Nowikowski committed
1711
   |                                        |      | ipv4-address)             |             |             |
Michal Nowikowski's avatar
Michal Nowikowski committed
1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | slp-service-scope                      | 79   | record (boolean, string)  | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | nds-server                             | 85   | ipv4-address              | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | nds-tree-name                          | 86   | string                    | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | nds-context                            | 87   | string                    | false       | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | bcms-controller-names                  | 88   | fqdn                      | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | bcms-controller-address                | 89   | ipv4-address              | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | client-system                          | 93   | uint16                    | true        | false       |
   +----------------------------------------+------+---------------------------+-------------+-------------+
   | client-ndi                             | 94   | record (uint8, uint8,     | false       | false       |
Michal Nowikowski's avatar
Michal Nowikowski committed
1728
   |                                        |      | uint8)                    |             |             |
Michal Nowikowski's avatar
Michal Nowikowski committed
1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752