mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-10-09 13:46:20 +00:00
5566 lines
239 KiB
XML
5566 lines
239 KiB
XML
<!--
|
||
- Copyright (C) 2014-2019 Internet Systems Consortium, Inc. ("ISC")
|
||
-
|
||
- This Source Code Form is subject to the terms of the Mozilla Public
|
||
- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||
- file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||
-->
|
||
<!-- Converted by db4-upgrade version 1.1 -->
|
||
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="dhcp6">
|
||
<title>The DHCPv6 Server</title>
|
||
|
||
<section xml:id="dhcp6-start-stop">
|
||
<title>Starting and Stopping the DHCPv6 Server</title>
|
||
|
||
<para>
|
||
It is recommended that the Kea DHCPv6 server be started and stopped
|
||
using <command>keactrl</command> (described in <xref linkend="keactrl"/>).
|
||
However, it is also possible to run the server directly: it accepts
|
||
the following command-line switches:
|
||
</para>
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
<simpara>
|
||
<command>-c <replaceable>file</replaceable></command> -
|
||
specifies the configuration file. This is the only mandatory
|
||
switch.</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara>
|
||
<command>-d</command> - specifies whether the server
|
||
logging should be switched to verbose mode. In verbose mode,
|
||
the logging severity and debuglevel specified in the configuration
|
||
file are ignored and "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.</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara>
|
||
<command>-p <replaceable>port</replaceable></command> -
|
||
specifies UDP port on which the server will listen. This is only
|
||
useful during testing, as a DHCPv6 server listening on
|
||
ports other than the standard ones will not be able to
|
||
handle regular DHCPv6 queries.</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara>
|
||
<command>-t <replaceable>file</replaceable></command> -
|
||
specifies the configuration file to be tested. Kea-dhcp6
|
||
will attempt to load it, and will conduct sanity
|
||
checks. Note that certain checks are possible only while
|
||
running the actual server. The actual status is reported
|
||
with exit code (0 = configuration looks ok, 1 = error
|
||
encountered). Kea will print out log messages to standard
|
||
output and error to standard error when testing
|
||
configuration.</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara>
|
||
<command>-v</command> - prints out the Kea version and exits.
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara>
|
||
<command>-V</command> - prints out the Kea extended version with
|
||
additional parameters and exits. The listing includes the versions
|
||
of the libraries dynamically linked to Kea.
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara>
|
||
<command>-W</command> - prints out the Kea configuration report
|
||
and exits. The report is a copy of the
|
||
<filename>config.report</filename> file produced by
|
||
<userinput>./configure</userinput>: it is embedded in the
|
||
executable binary.
|
||
</simpara>
|
||
</listitem>
|
||
</itemizedlist>
|
||
|
||
<para>
|
||
The <filename>config.report</filename> may also be accessed more
|
||
directly. The following command may be used to extract this
|
||
information. The binary <userinput>path</userinput> may be found
|
||
in the install directory or in the <filename>.libs</filename>
|
||
subdirectory in the source tree. For example
|
||
<filename>kea/src/bin/dhcp6/.libs/kea-dhcp6</filename>.
|
||
|
||
<screen>
|
||
strings <userinput>path</userinput>/kea-dhcp6 | sed -n 's/;;;; //p'
|
||
</screen>
|
||
</para>
|
||
|
||
<para>
|
||
On start-up, the server will detect available network interfaces
|
||
and will attempt to open UDP sockets on all interfaces
|
||
mentioned in the configuration file.
|
||
Since the DHCPv6 server opens privileged ports, it requires root
|
||
access. Make sure you run this daemon as root.
|
||
</para>
|
||
|
||
<para>
|
||
During startup the server will attempt to create a PID file of the
|
||
form: localstatedir]/[conf name].kea-dhcp6.pid where:
|
||
<itemizedlist>
|
||
<listitem>
|
||
<simpara><command>localstatedir</command>: The value as passed into the
|
||
build configure script. It defaults to "/usr/local/var". Note
|
||
that this value may be overridden at run time by setting the environment
|
||
variable KEA_PIDFILE_DIR. This is intended primarily for testing purposes.
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara><command>conf name</command>: The configuration file name
|
||
used to start the server, minus all preceding path and file extension.
|
||
For example, given a pathname of "/usr/local/etc/kea/myconf.txt", the
|
||
portion used would be "myconf".
|
||
</simpara>
|
||
</listitem>
|
||
</itemizedlist>
|
||
If the file already exists and contains the PID of a live process,
|
||
the server will issue a DHCP6_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.
|
||
</para>
|
||
|
||
<para>
|
||
The server can be stopped using the <command>kill</command> command.
|
||
When running in a console, the server can be shut down by
|
||
pressing ctrl-c. It detects the key combination and shuts
|
||
down gracefully.
|
||
</para>
|
||
</section>
|
||
|
||
<section xml:id="dhcp6-configuration">
|
||
<title>DHCPv6 Server Configuration</title>
|
||
<section>
|
||
<title>Introduction</title>
|
||
<para>
|
||
This section explains how to configure the DHCPv6 server using a
|
||
configuration file. Before DHCPv6 is started, its configuration
|
||
file has to be created. The basic configuration is as follows:
|
||
<screen>
|
||
{
|
||
# DHCPv6 configuration starts on the next line
|
||
"Dhcp6": {
|
||
|
||
# First we set up global values
|
||
"valid-lifetime": 4000,
|
||
"renew-timer": 1000,
|
||
"rebind-timer": 2000,
|
||
"preferred-lifetime": 3000,
|
||
|
||
# Next we setup 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/kea/dhcp6.leases"
|
||
},
|
||
|
||
# Finally, we list the subnets from which we will be leasing addresses.
|
||
"subnet6": [
|
||
{
|
||
"subnet": "2001:db8:1::/64",
|
||
"pools": [
|
||
{
|
||
"pool": "2001:db8:1::1-2001:db8:1::ffff"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
# DHCPv6 configuration ends with the next line
|
||
}
|
||
|
||
} </screen>
|
||
</para>
|
||
|
||
<para>The following paragraphs provide a brief overview of the parameters in
|
||
the above example together with
|
||
their format. Subsequent sections of this chapter go into much greater detail
|
||
for these and other parameters.</para>
|
||
|
||
<para>The lines starting with a hash (#) are comments and are ignored by
|
||
the server; they do not impact its
|
||
operation in any way.</para>
|
||
|
||
|
||
<para>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 <command>Dhcp6</command>.
|
||
</para>
|
||
|
||
<note>
|
||
<para>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 the future releases. The
|
||
only object, besides the one specifying module configuration, which can
|
||
(and usually is) included in the same file is <command>Logging</command>.
|
||
However, we don't include this object in the example above for clarity.
|
||
</para>
|
||
</note>
|
||
|
||
<para>The Dhcp6 configuration starts with the <command>"Dhcp6": {</command> 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 Dhcp6 configuration.</para>
|
||
|
||
<para>In the general case, the order in which those parameters appear does not
|
||
matter. There are two caveats here though. The first one is to remember that
|
||
the configuration file must be well formed JSON. That means that 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 your configuration
|
||
file.</para>
|
||
|
||
<para>Moving onto the DHCPv6 configuration elements, the very first few elements
|
||
define some global parameters. <command>valid-lifetime</command>
|
||
defines for 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.) The address will become deprecated in 3000 seconds (clients are
|
||
allowed to keep old connections, but can't use this address for creating new
|
||
connections). <command>renew-timer</command> and
|
||
<command> rebind-timer</command> are values that define T1 and T2 timers that
|
||
govern when the client will begin the renewal and rebind procedures.</para>
|
||
|
||
<para>The <command>interfaces-config</command> map specifies the server
|
||
configuration concerning the network interfaces, on which the server should
|
||
listen to the DHCP messages. The <command>interfaces</command> 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. Had we wanted to listen on two interfaces, the
|
||
<command>interfaces-config</command> would look like this:
|
||
<screen>
|
||
"interfaces-config": {
|
||
"interfaces": [ "eth0", "eth1" ]
|
||
},
|
||
</screen>
|
||
</para>
|
||
|
||
<para>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
|
||
<command>memfile</command>, which is the simplest (and fastest) database
|
||
backend. It uses an in-memory database and stores leases on disk in a CSV
|
||
file. This is a very simple configuration. Usually the lease database configuration
|
||
is more extensive and contains additional parameters. Note that
|
||
<command>lease-database</command>
|
||
is an object and opens up a new scope, using an opening brace.
|
||
Its parameters (just one in this example - <command>type</command>)
|
||
follow. Had there been more than one, they would be separated by commas. This
|
||
scope is closed with a closing brace. As more parameters for the Dhcp6 definition
|
||
follow, a trailing comma is present.</para>
|
||
|
||
<para>Finally, we need to define a list of IPv6 subnets. This is the
|
||
most important DHCPv6 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 <command>subnet6</command> 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 minimum, a subnet definition
|
||
has to have at least two parameters: <command>subnet</command> (that
|
||
defines the whole subnet) and <command>pools</command> (which is a list of
|
||
dynamically allocated pools that are governed by the DHCP server).</para>
|
||
|
||
<para>The example contains a single subnet. Had more than one been defined,
|
||
additional elements
|
||
in the <command>subnet6</command> parameter would be specified and
|
||
separated by commas. For example, to define two subnets, the following
|
||
syntax would be used:
|
||
<screen>
|
||
"subnet6": [
|
||
{
|
||
"pools": [ { "pool": "2001:db8:1::/112" } ],
|
||
"subnet": "2001:db8:1::/64"
|
||
},
|
||
{
|
||
"pools": [ { "pool": "2001:db8:2::1-2001:db8:2::ffff" } ],
|
||
"subnet": "2001:db8:2::/64"
|
||
}
|
||
]
|
||
</screen>
|
||
Note that indentation is optional and is used for aesthetic purposes only.
|
||
In some cases in may be preferable to use more compact notation.
|
||
</para>
|
||
|
||
<para>After all parameters are specified, we have two contexts open:
|
||
global and Dhcp6, hence we need two closing curly brackets to close them.
|
||
In a real life configuration file there most likely would be additional
|
||
components defined such as Logging, so the closing brace would be followed
|
||
by a comma and another object definition.</para>
|
||
</section>
|
||
|
||
<section>
|
||
<title>Lease Storage</title>
|
||
<para>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.</para>
|
||
<section>
|
||
<title>Memfile - Basic Storage for Leases</title>
|
||
|
||
<para>The server is able to store lease data in different repositories. Larger
|
||
deployments may elect to store leases in a database. <xref linkend="database-configuration6"/> 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.</para>
|
||
|
||
<para>The configuration of the file backend (Memfile) is controlled through
|
||
the Dhcp6/lease-database parameters. The <command>type</command> parameter
|
||
is mandatory and it specifies which storage for leases the server should use.
|
||
The value of <userinput>"memfile"</userinput> 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.
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
<simpara><command>persist</command>: 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 is set to
|
||
<userinput>true</userinput> at all times, during the server's normal
|
||
operation. Not writing leases to disk will mean that if a server is restarted
|
||
(e.g. after a power failure), it will not know what addresses have been
|
||
assigned. As a result, it may hand out addresses to new clients that are
|
||
already in use. The value of <userinput>false</userinput> is mostly useful
|
||
for performance testing purposes. The default value of the
|
||
<command>persist</command> parameter is <userinput>true</userinput>,
|
||
which enables writing lease updates
|
||
to the lease file.
|
||
</simpara>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<simpara><command>name</command>: 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 <userinput>"[kea-install-dir]/var/kea/kea-leases6.csv"
|
||
</userinput>.</simpara>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<simpara><command>lfc-interval</command>: 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 detailed fashion further in this section. The default value of the
|
||
<command>lfc-interval</command> is <userinput>3600</userinput>. A value of 0
|
||
disables the LFC.</simpara>
|
||
</listitem>
|
||
|
||
</itemizedlist>
|
||
</para>
|
||
|
||
<para>An example configuration of the Memfile backend is presented below:
|
||
|
||
<screen>
|
||
"Dhcp6": {
|
||
"lease-database": {
|
||
<userinput>"type": "memfile"</userinput>,
|
||
<userinput>"persist": true</userinput>,
|
||
<userinput>"name": "/tmp/kea-leases6.csv"</userinput>,
|
||
<userinput>"lfc-interval": 1800</userinput>
|
||
}
|
||
}
|
||
</screen>
|
||
|
||
This configuration selects the <filename>/tmp/kea-leases6.csv</filename> as
|
||
the storage for lease information and enables persistence (writing lease updates
|
||
to this file). It also configures the backend perform the periodic cleanup
|
||
of the lease files, executed every 30 minutes.
|
||
</para>
|
||
|
||
<para>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 it 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. This means 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 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.
|
||
</para>
|
||
|
||
<para>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 <command>lfc-interval</command> should be. Note however, that the
|
||
LFC takes time and thus it is possible (although unlikely) that new cleanup
|
||
is started while the previous cleanup instance is still running, if the
|
||
<command>lfc-interval</command> is too short. The server would recover from
|
||
this by skipping the new cleanup when it detects that the previous cleanup
|
||
is still in progress. But it implies that the actual cleanups will be
|
||
triggered more rarely than configured. Moreover, triggering a new cleanup
|
||
adds an 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 <command>lfc-interval</command> value
|
||
is selected in a way that would allow for the LFC to complete the cleanup before a
|
||
new cleanup is triggered.
|
||
</para>
|
||
|
||
<para>Lease file cleanup is performed by a separate process (in background) to avoid
|
||
a performance impact on the server process. In order to avoid the conflicts
|
||
between two processes both using the same lease files, the LFC process
|
||
operates on the copy of the original lease file, rather than on the lease
|
||
file used by the server to record lease updates. There are also other files
|
||
being created as a side effect of the lease file cleanup. The detailed
|
||
description of the LFC is located in the Kea Administrator's Reference Manual:
|
||
<uri xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://jenkins.isc.org/job/Kea_doc/guide/kea-guide.html#kea-lfc">https://jenkins.isc.org/job/Kea_doc/guide/kea-guide.html#kea-lfc</uri>.
|
||
</para>
|
||
|
||
</section>
|
||
|
||
<section xml:id="database-configuration6">
|
||
<title>Lease Database Configuration</title>
|
||
|
||
<note>
|
||
<para>Lease database access information must be configured for the DHCPv6 server,
|
||
even if it has already been configured for the DHCPv4 server. The servers
|
||
store their information independently, so each server can use a separate
|
||
database or both servers can use the same database.</para>
|
||
</note>
|
||
|
||
<para>Lease database configuration is controlled through the
|
||
Dhcp6/lease-database parameters. The type of the database must be set to
|
||
"memfile", "mysql", "postgresql" or "cql", e.g.
|
||
<screen>
|
||
"Dhcp6": { "lease-database": { <userinput>"type": "mysql"</userinput>, ... }, ... }
|
||
</screen>
|
||
Next, the name of the database is to hold the leases must be set: this is the
|
||
name used when the database was created
|
||
(see <xref linkend="mysql-database-create"/>,
|
||
<xref linkend="pgsql-database-create"/>
|
||
or <xref linkend="cql-database-create"/>).
|
||
<screen>
|
||
"Dhcp6": { "lease-database": { <userinput>"name": "<replaceable>database-name</replaceable>" </userinput>, ... }, ... }
|
||
</screen>
|
||
For Cassandra:
|
||
<screen>
|
||
"Dhcp6": { "lease-database": { <userinput>"keyspace": "<replaceable>database-name</replaceable>" </userinput>, ... }, ... }
|
||
</screen>
|
||
If the database is located on a different system to the DHCPv6 server, the
|
||
database host name must also be specified. (It should be noted that this
|
||
configuration may have a severe impact on server performance.):
|
||
<screen>
|
||
"Dhcp6": { "lease-database": { <userinput>"host": "<replaceable>remote-host-name</replaceable>"</userinput>, ... }, ... }
|
||
</screen>
|
||
For Cassandra, multiple contact points can be provided:
|
||
<screen>
|
||
"Dhcp6": { "lease-database": { <userinput>"contact-points": "<replaceable>remote-host-name[, ...]</replaceable>" </userinput>, ... }, ... }
|
||
</screen>
|
||
The usual state of affairs will be to have the database on the same machine as
|
||
the DHCPv6 server. In this case, set the value to the empty string:
|
||
<screen>
|
||
"Dhcp6": { "lease-database": { <userinput>"host" : ""</userinput>, ... }, ... }
|
||
</screen>
|
||
For Cassandra:
|
||
<screen>
|
||
"Dhcp6": { "lease-database": { <userinput>"contact-points": ""</userinput>, ... }, ... }
|
||
</screen>
|
||
Should the database use a port different than default, it may be
|
||
specified as well:
|
||
<screen>
|
||
"Dhcp6": { "lease-database": { <userinput>"port" : 12345</userinput>, ... }, ... }
|
||
</screen>
|
||
Should the database be located on a different system, you may need to specify a longer interval
|
||
for the connection timeout:
|
||
<screen>
|
||
"Dhcp6": { "lease-database": { <userinput>"connect-timeout" : <replaceable>timeout-in-seconds</replaceable></userinput>, ... }, ... }
|
||
</screen>
|
||
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.
|
||
</para>
|
||
<para>
|
||
The maxiumum number of times the server will automatically attempt to reconnect to
|
||
the lease database after connectivity has been lost may be specified:
|
||
<screen>
|
||
"Dhcp6": { "lease-database": { <userinput>"max-reconnect-tries" : <replaceable>number-of-tries</replaceable></userinput>, ... }, ... }
|
||
</screen>
|
||
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 Postgres only).
|
||
</para>
|
||
<para>
|
||
The number of milliseconds the server will wait in between attempts to reconnect to the
|
||
lease database after connectivity has been lost may also be specified:
|
||
<screen>
|
||
"Dhcp6": { "lease-database": { <userinput>"reconnect-wait-time" : <replaceable>number-of-milliseconds</replaceable></userinput>, ... }, ... }
|
||
</screen>
|
||
The default value for MySQL and Postgres 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.
|
||
</para>
|
||
|
||
<note>
|
||
<para>
|
||
Automatic reconnect to database backends is configured individually per backend.
|
||
This allows you to tailor the recovery parameters to the each backend you use.
|
||
We do suggest that you either enable it for all backends or no backends so you
|
||
have consistent behavior. Losing connectivity to a backend for which reconnect
|
||
is disabled will result in the server shutting itself down. This includes the
|
||
cases when lease database backend and hosts database backend is connected to
|
||
the same database instance.
|
||
</para>
|
||
</note>
|
||
|
||
<para>
|
||
Note that host parameter is used by MySQL and PostgreSQL
|
||
backends. Cassandra has a concept of contact points that could be
|
||
used to contact the cluster, instead of a single IP or
|
||
hostname. It takes a list of comma separated IP addresses. This may be specified as:
|
||
<screen>
|
||
"Dhcp6": { "lease-database": { <userinput>"contact-points" : "192.0.2.1,192.0.2.2"</userinput>, ... }, ... }
|
||
</screen>
|
||
</para>
|
||
|
||
<para>Finally, the credentials of the account under which the server will
|
||
access the database should be set:
|
||
<screen>
|
||
"Dhcp6": { "lease-database": { <userinput>"user": "<replaceable>user-name</replaceable>"</userinput>,
|
||
<userinput>"password": "<replaceable>password</replaceable>"</userinput>,
|
||
... },
|
||
... }
|
||
</screen>
|
||
If there is no password to the account, set the password to the empty string
|
||
"". (This is also the default.)</para>
|
||
</section>
|
||
|
||
<section xml:id="cassandra-database-configuration6">
|
||
<title>Cassandra specific parameters</title>
|
||
<para>The parameters are the same for DHCPv4 and DHCPv6. See <xref
|
||
linkend="cassandra-database-configuration4"/> for details.</para>
|
||
</section>
|
||
|
||
</section>
|
||
|
||
<section xml:id="hosts6-storage">
|
||
<title>Hosts Storage</title>
|
||
<para>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 be used to keep leases and host reservations
|
||
separately, but can also point to the same database. Currently the
|
||
supported hosts database types are MySQL and PostgreSQL. The Cassandra
|
||
backend does not support host reservations yet.</para>
|
||
|
||
<para>Please note that usage of hosts storage is optional. A user can define
|
||
all host reservations in the configuration file. That is the recommended way
|
||
if the number of reservations is small. However, when the number of
|
||
reservations grows it's 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.</para>
|
||
|
||
<para>Version 1.4 extends the host storage to multiple storages. Operations
|
||
are performed on host storages in the configuration order with a special
|
||
case for addition: read-only storages must be configured after a
|
||
required read-write storage, or host reservation addition will
|
||
always fail.</para>
|
||
|
||
<section xml:id="hosts-databases-configuration6">
|
||
<title>DHCPv6 Hosts Database Configuration</title>
|
||
|
||
<para>Hosts database configuration is controlled through the Dhcp6/hosts-database
|
||
parameters. If enabled, the type of the database must be set to "mysql" or
|
||
"postgresql". Other hosts backends may be added in later version of Kea.
|
||
<screen>
|
||
"Dhcp6": { "hosts-database": { <userinput>"type": "mysql"</userinput>, ... }, ... }
|
||
</screen>
|
||
Next, the name of the database to hold the reservations must be set: this is the
|
||
name used when the database was created (see <xref linkend="supported-databases"/>
|
||
for instructions how to setup desired database type).
|
||
<screen>
|
||
"Dhcp6": { "hosts-database": { <userinput>"name": "<replaceable>database-name</replaceable>" </userinput>, ... }, ... }
|
||
</screen>
|
||
If the database is located on a different system than the DHCPv6 server, the
|
||
database host name must also be specified. (Again it should be noted that this
|
||
configuration may have a severe impact on server performance):
|
||
<screen>
|
||
"Dhcp6": { "hosts-database": { <userinput>"host": <replaceable>remote-host-name</replaceable></userinput>, ... }, ... }
|
||
</screen>
|
||
The usual state of affairs will be to have the database on the same machine as
|
||
the DHCPv6 server. In this case, set the value to the empty string:
|
||
<screen>
|
||
"Dhcp6": { "hosts-database": { <userinput>"host" : ""</userinput>, ... }, ... }
|
||
</screen>
|
||
<screen>
|
||
"Dhcp6": { "hosts-database": { <userinput>"port" : 12345</userinput>, ... }, ... }
|
||
</screen>
|
||
</para>
|
||
<para>
|
||
The maxiumum number of times the server will automatically attempt to reconnect to
|
||
the host database after connectivity has been lost may be specified:
|
||
<screen>
|
||
"Dhcp6": { "host-database": { <userinput>"max-reconnect-tries" : <replaceable>number-of-tries</replaceable></userinput>, ... }, ... }
|
||
</screen>
|
||
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 Postgres only).
|
||
</para>
|
||
<para>
|
||
The number of milliseconds the server will wait in between attempts to reconnect to the
|
||
host database after connectivity has been lost may also be specified:
|
||
<screen>
|
||
"Dhcp6": { "hosts-database": { <userinput>"reconnect-wait-time" : <replaceable>number-of-milliseconds</replaceable></userinput>, ... }, ... }
|
||
</screen>
|
||
The default value for MySQL and Postgres 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.
|
||
</para>
|
||
|
||
<note>
|
||
<para>
|
||
Automatic reconnect to database backends is configured individually per backend.
|
||
This allows you to tailor the recovery parameters to the each backend you use.
|
||
We do suggest that you either enable it for all backends or no backends so you
|
||
have consistent behavior. Losing connectivity to a backend for which reconnect
|
||
is disabled will result in the server shutting itself down. This includes the
|
||
cases when lease database backend and hosts database backend is connected to
|
||
the same database instance.
|
||
</para>
|
||
</note>
|
||
|
||
<para>Finally, the credentials of the account under which the server will
|
||
access the database should be set:
|
||
<screen>
|
||
"Dhcp6": { "hosts-database": { <userinput>"user": "<replaceable>user-name</replaceable>"</userinput>,
|
||
<userinput>"password": "<replaceable>password</replaceable>"</userinput>,
|
||
... },
|
||
... }
|
||
</screen>
|
||
If there is no password to the account, set the password to the empty string
|
||
"". (This is also the default.)</para>
|
||
|
||
<para>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:
|
||
<screen>
|
||
"Dhcp6": { "hosts-databases": [ { <userinput>"type": "mysql"</userinput>, ... }, ... ], ... }
|
||
</screen>
|
||
</para>
|
||
|
||
<para>
|
||
For additional Cassandra specific parameters, see <xref
|
||
linkend="cassandra-database-configuration4" />.</para>
|
||
|
||
</section>
|
||
|
||
<section xml:id="read-only-database-configuration6">
|
||
<title>Using Read-Only Databases for Host Reservations</title>
|
||
<para>
|
||
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 inventory databases
|
||
deployed, which contain substantially more information about the hosts than
|
||
static reservations assigned to them. The inventory database can be used to create
|
||
a view of a Kea hosts database and such view is often read only.
|
||
</para>
|
||
<para>
|
||
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 assign specific addresses and options, it is possible to explicitly
|
||
configure Kea to start in "read-only" mode. This is controlled by the
|
||
<command>readonly</command> boolean parameter as follows:
|
||
<screen>
|
||
"Dhcp6": { "hosts-database": { <userinput>"readonly": true</userinput>, ... }, ... }
|
||
</screen>
|
||
Setting this parameter to <userinput>false</userinput> would configure the
|
||
database backend to operate in "read-write" mode, which is also a default
|
||
configuration if the parameter is not specified.
|
||
</para>
|
||
<note><para>The <command>readonly</command> parameter is currently only supported
|
||
for MySQL and PostgreSQL databases.</para></note>
|
||
</section>
|
||
|
||
</section>
|
||
|
||
<section xml:id="dhcp6-interface-selection">
|
||
<title>Interface Selection</title>
|
||
<para>The DHCPv6 server has to be configured to listen on specific network
|
||
interfaces. The simplest network interface configuration instructs the server to
|
||
listen on all available interfaces:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"interfaces-config": {
|
||
"interfaces": [ <userinput>"*"</userinput> ]
|
||
}
|
||
...
|
||
}
|
||
</screen>
|
||
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:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"interfaces-config": {
|
||
"interfaces": [ <userinput>"eth1", "eth3"</userinput> ]
|
||
},
|
||
...
|
||
}
|
||
</screen>
|
||
</para>
|
||
<para>It is possible to use wildcard interface name (asterisk) concurrently
|
||
with the actual interface names:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"interfaces-config": {
|
||
"interfaces": [ <userinput>"eth1", "eth3", "*"</userinput> ]
|
||
},
|
||
...
|
||
}
|
||
</screen>
|
||
It is anticipated that this will form of usage only be used where it is desired to
|
||
temporarily override a list of interface names and listen on all interfaces.
|
||
</para>
|
||
|
||
<para>As for the DHCPv4 server binding to specific addresses and
|
||
disabling re-detection of interfaces are supported. But
|
||
<command>dhcp-socket-type</command> is not because DHCPv6 uses
|
||
UDP/IPv6 sockets only. The following example shows how to disable the
|
||
interface detection:
|
||
</para>
|
||
|
||
<screen>
|
||
"Dhcp6": {
|
||
"interfaces-config": {
|
||
"interfaces": [ <userinput>"eth1", "eth3"</userinput> ],
|
||
"re-detect": <userinput>false</userinput>
|
||
},
|
||
...
|
||
}
|
||
</screen>
|
||
|
||
<para>The loopback interfaces (i.e. the "lo" or "lo0" interface)
|
||
are not configured by default, unles explicitely mentioned in
|
||
the configration. Note Kea requires a link-local address which does
|
||
not exist on all systems, or a specified unicast address as in:
|
||
</para>
|
||
|
||
<screen>
|
||
"Dhcp6": {
|
||
"interfaces-config": {
|
||
"interfaces": [ <userinput>"lo/::1"</userinput> ]
|
||
},
|
||
...
|
||
}
|
||
</screen>
|
||
|
||
</section>
|
||
|
||
<section xml:id="ipv6-subnet-id">
|
||
<title>IPv6 Subnet Identifier</title>
|
||
<para>
|
||
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 ....
|
||
</para>
|
||
<para>
|
||
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. It is planned
|
||
to implement a mechanism to preserve auto-generated subnet ids in a
|
||
future version of Kea. However, the only remedy for this issue
|
||
at present is to
|
||
manually specify a unique identifier for each subnet.
|
||
</para>
|
||
<note>
|
||
Subnet IDs must be greater than zero and less than 4294967295.
|
||
</note>
|
||
<para>
|
||
The following configuration will assign the specified subnet
|
||
identifier to the newly configured subnet:
|
||
|
||
<screen>
|
||
"Dhcp6": {
|
||
"subnet6": [
|
||
{
|
||
"subnet": "2001:db8:1::/64",
|
||
<userinput>"id": 1024</userinput>,
|
||
...
|
||
}
|
||
]
|
||
}
|
||
</screen>
|
||
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.
|
||
</para>
|
||
<!-- @todo: describe whether database needs to be updated after changing
|
||
id -->
|
||
</section>
|
||
|
||
<section xml:id="dhcp6-unicast">
|
||
<title>Unicast Traffic Support</title>
|
||
<para>
|
||
When the DHCPv6 server starts, by default it listens to the DHCP traffic
|
||
sent to multicast address ff02::1:2 on each interface that it is
|
||
configured to listen on (see <xref linkend="dhcp6-interface-selection"/>).
|
||
In some cases it is useful to configure a server to handle incoming
|
||
traffic sent to the global unicast addresses as well. The most common
|
||
reason for this is to have relays send their traffic to the server
|
||
directly. To configure the server to listen on a specific unicast address,
|
||
nn interface name can be
|
||
optionally followed by a slash, followed by the global unicast address on which
|
||
the server should listen. The server listens to this address in addition to normal
|
||
link-local binding and listening on ff02::1:2 address. The sample configuration
|
||
below shows how to listen on 2001:db8::1 (a global address)
|
||
configured on the eth1 interface.
|
||
</para>
|
||
<para>
|
||
<screen>
|
||
"Dhcp6": {
|
||
"interfaces-config": {
|
||
"interfaces": [ <userinput>"eth1/2001:db8::1"</userinput> ]
|
||
},
|
||
...
|
||
"option-data": [
|
||
{
|
||
"name": "unicast",
|
||
"data": "2001:db8::1"
|
||
} ],
|
||
...
|
||
}
|
||
</screen>
|
||
|
||
This configuration will cause the server to listen on
|
||
eth1 on the link-local address, the multicast group (ff02::1:2) and 2001:db8::1.
|
||
</para>
|
||
<para>
|
||
Usually unicast support is associated with a server unicast option
|
||
which allows clients to send unicast messages to the server.
|
||
The example above includes a server unicast option specification
|
||
which will cause the client to send messages to the specified
|
||
unicast address.
|
||
</para>
|
||
<para>
|
||
It is possible to mix interface names, wildcards and interface name/addresses
|
||
in the list of interfaces. It is not possible however to specify more than one
|
||
unicast address on a given interface.
|
||
</para>
|
||
<para>
|
||
Care should be taken to specify proper unicast addresses. The server will
|
||
attempt to bind to the addresses specified without any additional checks.
|
||
This approach has selected on purpose to allow the software to
|
||
communicate over uncommon addresses if so desired.
|
||
</para>
|
||
</section>
|
||
|
||
<section xml:id="dhcp6-address-config">
|
||
<title>Subnet and Address Pool</title>
|
||
<para>
|
||
The main role of a DHCPv6 server is address assignment. For this,
|
||
the server has to 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 2001:db8:1::/64
|
||
prefix. The Administrator of that network has decided that addresses from range
|
||
2001:db8:1::1 to 2001:db8:1::ffff are going to be managed by the Dhcp6
|
||
server. Such a configuration can be achieved in the following way:
|
||
<screen>
|
||
"Dhcp6": {
|
||
<userinput>"subnet6": [
|
||
{
|
||
"subnet": "2001:db8:1::/64",
|
||
"pools": [
|
||
{
|
||
"pool": "2001:db8:1::1-2001:db8:1::ffff"
|
||
}
|
||
],
|
||
...
|
||
}
|
||
]</userinput>
|
||
}</screen>
|
||
|
||
Note that <command>subnet</command> is defined as a simple string, but
|
||
the <command>pools</command> 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.</para>
|
||
|
||
<para>Each <command>pool</command> is a structure that contains the
|
||
parameters that describe a single pool. Currently there is only one
|
||
parameter, <command>pool</command>, which gives the range of addresses
|
||
in the pool. Additional parameters will be added in future releases of
|
||
Kea.</para>
|
||
|
||
<para>It is possible to define more than one pool in a
|
||
subnet: continuing the previous example, further assume that
|
||
2001:db8:1:0:5::/80 should also be managed by the server. It could be written as
|
||
2001:db8:1:0:5:: to 2001:db8:1::5:ffff:ffff:ffff, but typing so many 'f's
|
||
is cumbersome. It can be expressed more simply as 2001:db8:1:0:5::/80. Both
|
||
formats are supported by Dhcp6 and can be mixed in the pool list.
|
||
For example, one could define the following pools:
|
||
<screen>
|
||
"Dhcp6": {
|
||
<userinput>"subnet6": [
|
||
{
|
||
"subnet": "2001:db8:1::/64",
|
||
"pools": [
|
||
{ "pool": "2001:db8:1::1-2001:db8:1::ffff" },
|
||
{ "pool": "2001:db8:1:05::/80" }
|
||
]</userinput>,
|
||
...
|
||
}
|
||
]
|
||
}</screen>
|
||
White space in pool definitions is ignored, so spaces before and after the hyphen are optional.
|
||
They can be used to improve readability.
|
||
</para>
|
||
<para>
|
||
The number of pools is not limited, but for performance reasons it is recommended to
|
||
use as few as possible.
|
||
</para>
|
||
<para>
|
||
The server may be configured to serve more than one subnet. To add a second subnet,
|
||
use a command similar to the following:
|
||
<screen>
|
||
"Dhcp6": {
|
||
<userinput>"subnet6": [
|
||
{
|
||
"subnet": "2001:db8:1::/64",
|
||
"pools": [
|
||
{ "pool": "2001:db8:1::1-2001:db8:1::ffff" }
|
||
]
|
||
},
|
||
{
|
||
"subnet": "2001:db8:2::/64",
|
||
"pools": [
|
||
{ "pool": "2001:db8:2::/64" }
|
||
]
|
||
},
|
||
</userinput>
|
||
...
|
||
]
|
||
}</screen>
|
||
In this example, we allow the server to
|
||
dynamically assign all addresses available in the whole subnet. Although
|
||
rather wasteful, it is certainly a valid configuration to dedicate the
|
||
whole /64 subnet for that purpose. Note that the Kea server does not preallocate
|
||
the leases, so there is no danger in using gigantic address pools.
|
||
</para>
|
||
<para>
|
||
When configuring a DHCPv6 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 network
|
||
address) address from that pool. For example, for pool 2001:db8:2::/64 the
|
||
2001:db8:2:: address may be assigned as well. If you want to avoid this,
|
||
use the "min-max" notation.
|
||
</para>
|
||
</section>
|
||
|
||
<section>
|
||
<title>Subnet and Prefix Delegation Pools</title>
|
||
<para>
|
||
Subnets may also be configured to delegate prefixes, as defined in
|
||
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc8415">RFC 8415</link>,
|
||
section 6.3. A subnet may have one or more prefix delegation pools.
|
||
Each pool has a prefixed address, which is specified as a prefix
|
||
(<command>prefix</command>) and a prefix length
|
||
(<command>prefix-len</command>), as well as a delegated prefix length
|
||
(<command>delegated-len</command>). The delegated length must not be
|
||
shorter (that is it must be numerically greater or equal) than the
|
||
prefix length. If both the delegated and prefix lengths are equal, the
|
||
server will be able to delegate only one prefix. The delegated prefix
|
||
does not have to match the subnet prefix.
|
||
</para>
|
||
<para> Below is a sample subnet configuration which enables prefix
|
||
delegation for the subnet:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"subnet6": [
|
||
{
|
||
"subnet": "2001:d8b:1::/64",
|
||
<userinput>"pd-pools": [
|
||
{
|
||
"prefix": "3000:1::",
|
||
"prefix-len": 64,
|
||
"delegated-len": 96
|
||
}
|
||
]</userinput>
|
||
}
|
||
],
|
||
...
|
||
}</screen>
|
||
</para>
|
||
|
||
</section>
|
||
|
||
<section xml:id="pd-exclude-option">
|
||
<title>Prefix Exclude Option</title>
|
||
<para>
|
||
For each delegated prefix the delegating router may choose to exclude
|
||
a single prefix out of the delegated prefix as specified in the
|
||
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc6603"> RFC 6603</link>.
|
||
The requesting router must not assign the excluded prefix to any
|
||
of its downstream interfaces and it is intended to be used on a
|
||
link through which the delegating router exchanges DHCPv6 messages with
|
||
the requesting router. The configuration example below demonstrates how
|
||
to specify an excluded prefix within a prefix pool definition. The
|
||
excluded prefix "2001:db8:1:babe:cafe:80::/72" will be sent to a
|
||
requesting router which includes Prefix Exclude option in the ORO, and
|
||
which is delegated a prefix from this pool.
|
||
</para>
|
||
<screen>
|
||
"Dhcp6": {
|
||
"subnet6": [
|
||
{
|
||
"subnet": "2001:db8:1::/48",
|
||
"pd-pools": [
|
||
{
|
||
"prefix": "2001:db8:1:8000::",
|
||
"prefix-len": 48,
|
||
"delegated-len": 64,
|
||
"excluded-prefix": "2001:db8:1:babe:cafe:80::",
|
||
"excluded-prefix-len": 72
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
</screen>
|
||
</section>
|
||
|
||
<section xml:id="dhcp6-std-options">
|
||
<title>Standard DHCPv6 Options</title>
|
||
<para>
|
||
One of the major features of a DHCPv6 server is to provide configuration
|
||
options to clients. Although there are several options that require
|
||
special behavior, most options are sent by the server only if the client
|
||
explicitly requests them. The following example shows how to
|
||
configure DNS servers, one of the most frequently used
|
||
options. Options specified in this way are considered
|
||
global and apply to all configured subnets.
|
||
|
||
<screen>
|
||
"Dhcp6": {
|
||
"option-data": [
|
||
{
|
||
<userinput>"name": "dns-servers",
|
||
"code": 23,
|
||
"space": "dhcp6",
|
||
"csv-format": true,
|
||
"data": "2001:db8::cafe, 2001:db8::babe"</userinput>
|
||
},
|
||
...
|
||
]
|
||
}
|
||
</screen>
|
||
</para>
|
||
|
||
<para>
|
||
The <command>option-data</command> line creates a new entry in
|
||
the option-data table. This table contains
|
||
information on all global options that the server is supposed to configure
|
||
in all subnets. The <command>name</command> line specifies the option name.
|
||
(For a complete list
|
||
of currently supported names, see <xref linkend="dhcp6-std-options-list"/>.) The next line specifies the option code,
|
||
which must match one of the values from that list. The line beginning with
|
||
<command>space</command> specifies the option space, which must always be set
|
||
to "dhcp6" as these are standard DHCPv6 options. For other name spaces,
|
||
including custom option spaces, see <xref linkend="dhcp6-option-spaces"/>. The following line specifies the format in
|
||
which the data will be entered: use of CSV (comma separated values) is
|
||
recommended. Finally, the <command>data</command> line gives the actual value to be sent to
|
||
clients. Data is specified as normal text, with values separated by
|
||
commas if more than one value is allowed.
|
||
</para>
|
||
|
||
<para>
|
||
Options can also be configured as hexadecimal values. If "csv-format" is
|
||
set to false, the option data must be specified as a string of hexadecimal
|
||
numbers. The
|
||
following commands configure the DNS-SERVERS option for all
|
||
subnets with the following addresses: 2001:db8:1::cafe and
|
||
2001:db8:1::babe.
|
||
<screen>
|
||
"Dhcp6": {
|
||
"option-data": [
|
||
{
|
||
<userinput>"name": "dns-servers",
|
||
"code": 23,
|
||
"space": "dhcp6",
|
||
"csv-format": false,
|
||
"data": "2001 0DB8 0001 0000 0000 0000 0000 CAFE
|
||
2001 0DB8 0001 0000 0000 0000 0000 BABE"</userinput>
|
||
},
|
||
...
|
||
]
|
||
}
|
||
</screen>
|
||
</para>
|
||
<note><para>
|
||
The value for the setting of the "data" element is split across two
|
||
lines in this example for clarity: when entering the command, the
|
||
whole string should be entered on the same line.
|
||
</para></note>
|
||
<para>
|
||
Care should be taken
|
||
to use proper encoding when using hexadecimal format as Kea's ability
|
||
to validate data correctness in hexadecimal is limited.
|
||
</para>
|
||
|
||
<para>
|
||
Most of the parameters in the "option-data" structure are
|
||
optional and can be omitted in some circumstances as discussed
|
||
in the <xref linkend="dhcp6-option-data-defaults"/>. Only one
|
||
of name or code is required, so you don't need to specify
|
||
both. Space has a default value of "dhcp6", so you can skip
|
||
this as well if you define a regular (not encapsulated) DHCPv6
|
||
option. Finally, csv-format defaults to true, so it too can
|
||
be skipped, unless you want to specify the option value as
|
||
hexstring. Therefore the above example can be simplified to:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"option-data": [
|
||
{
|
||
<userinput>"name": "dns-servers",
|
||
"data": "2001:db8::cafe, 2001:db8::babe"</userinput>
|
||
},
|
||
...
|
||
]
|
||
}
|
||
</screen>
|
||
Defined options are added to response when the client requests them
|
||
at a few exceptions which are always added. To enforce the addition
|
||
of a particular option set the always-send flag to true as in:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"option-data": [
|
||
{
|
||
<userinput>"name": "dns-servers",
|
||
"data": "2001:db8::cafe, 2001:db8::babe",
|
||
"always-send": true</userinput>
|
||
},
|
||
...
|
||
]
|
||
}
|
||
</screen>
|
||
The effect is the same as if the client added the option code in the
|
||
Option Request Option (or its equivalent for vendor options) so in:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"option-data": [
|
||
{
|
||
<userinput>"name": "dns-servers",
|
||
"data": "2001:db8::cafe, 2001:db8::babe",
|
||
"always-send": true</userinput>
|
||
},
|
||
...
|
||
],
|
||
"subnet6": [
|
||
{
|
||
"subnet": "2001:db8:1::/64",
|
||
"option-data": [
|
||
{
|
||
<userinput>"name": "dns-servers",
|
||
"data": "2001:db8:1::cafe, 2001:db8:1::babe"</userinput>
|
||
},
|
||
...
|
||
],
|
||
...
|
||
},
|
||
...
|
||
],
|
||
...
|
||
}
|
||
</screen>
|
||
The DNS Servers option is always added to responses
|
||
(the always-send is "sticky") but the value is the subnet one
|
||
when the client is localized in the subnet.
|
||
</para>
|
||
|
||
<para>
|
||
It is possible to override options on a per-subnet basis. If
|
||
clients connected to most of your subnets are expected to get the
|
||
same values of a given option, you should use global options: you
|
||
can then override specific values for a small number of subnets.
|
||
On the other hand, if you use different values in each subnet,
|
||
it does not make sense to specify global option values
|
||
(Dhcp6/option-data), rather you should set only subnet-specific values
|
||
(Dhcp6/subnet[X]/option-data[Y]).
|
||
</para>
|
||
|
||
<para>
|
||
The following commands override the global
|
||
DNS servers option for a particular subnet, setting a single DNS
|
||
server with address 2001:db8:1::3.
|
||
<screen>
|
||
"Dhcp6": {
|
||
"subnet6": [
|
||
{
|
||
<userinput>"option-data": [
|
||
{
|
||
"name": "dns-servers",
|
||
"code": 23,
|
||
"space": "dhcp6",
|
||
"csv-format": true,
|
||
"data": "2001:db8:1::3"
|
||
},
|
||
...
|
||
]</userinput>,
|
||
...
|
||
},
|
||
...
|
||
],
|
||
...
|
||
}
|
||
</screen>
|
||
</para>
|
||
|
||
<para>
|
||
In some cases it is useful to associate some options with an
|
||
address or prefix pool from which a client is assigned a lease. Pool
|
||
specific option values override subnet specific and global option
|
||
values. If the client is assigned multiple leases from different
|
||
pools, the server will assign options from all pools from which the
|
||
leases have been obtained. However, if the particular option is specified
|
||
in multiple pools from which the client obtains the leases, only one
|
||
instance of this option will be handed out to the client. The server's
|
||
administrator must not try to prioritize assignment of pool specific
|
||
options by trying to order pools declarations in the server
|
||
configuration. Future Kea releases may change the order in which
|
||
options are assigned from the pools without any notice.
|
||
</para>
|
||
|
||
<para>
|
||
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:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"subnet6": [
|
||
{
|
||
"pools": [
|
||
{
|
||
"pool": "2001:db8:1::100-2001:db8:1::300",
|
||
<userinput>"option-data": [
|
||
{
|
||
"name": "dns-servers",
|
||
"data": "2001:db8:1::10"
|
||
}
|
||
]</userinput>
|
||
}
|
||
]
|
||
},
|
||
...
|
||
],
|
||
...
|
||
}
|
||
</screen>
|
||
</para>
|
||
<para>
|
||
Options can be specified also in class of host reservation scope.
|
||
In Kea 1.4 options precedence order is (from most important):
|
||
host reservation, pool, subnet, shared network, class, global.
|
||
In Kea 1.5 order will be changed to:
|
||
host reservation, class, pool, subnet, shared network, global OR it will
|
||
be fully configurable.
|
||
</para>
|
||
<para>
|
||
The currently supported standard DHCPv6 options are
|
||
listed in <xref linkend="dhcp6-std-options-list"/>.
|
||
The "Name" and "Code"
|
||
are the values that should be used as a name in the option-data
|
||
structures. "Type" designates the format of the data: the meanings of
|
||
the various types is given in <xref linkend="dhcp-types"/>.
|
||
</para>
|
||
<para>When a data field is a string, and that string contains
|
||
the comma (,; U+002C) character, the comma must be escaped with a
|
||
reverse solidus character (\; 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
|
||
"EST5EDT4,M3.2.0/02:00,M11.1.0/02:00" would be
|
||
represented as:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"subnet6": [
|
||
{
|
||
"pools": [
|
||
{
|
||
<userinput>"option-data": [
|
||
{
|
||
"name": "new-posix-timezone",
|
||
"data": "EST5EDT4\,M3.2.0/02:00\,M11.1.0/02:00"
|
||
}
|
||
]</userinput>
|
||
},
|
||
...
|
||
],
|
||
...
|
||
},
|
||
...
|
||
],
|
||
...
|
||
}
|
||
</screen>
|
||
</para>
|
||
<para>
|
||
Some options are designated as arrays, which means that more than one
|
||
value is allowed in such an option. For example the option dns-servers
|
||
allows the specification of more than one IPv6 address, allowing
|
||
clients to obtain the addresses of multiple DNS servers.
|
||
</para>
|
||
|
||
<!-- @todo: describe record types -->
|
||
<!-- @todo: describe array in record types -->
|
||
|
||
<para>
|
||
The <xref linkend="dhcp6-custom-options"/> describes the configuration
|
||
syntax to create custom option definitions (formats). It is generally not
|
||
allowed to create custom definitions for standard options, even if the
|
||
definition being created matches the actual option format defined in the
|
||
RFCs. There is an exception from this rule for standard options for which
|
||
Kea does not yes provide a definition. In order to use such options,
|
||
a server administrator must create a definition as described in
|
||
<xref linkend="dhcp6-custom-options"/> in the 'dhcp6' option space. This
|
||
definition should match the option format described in the relevant
|
||
RFC but the configuration mechanism would allow any option format as it has
|
||
no means to validate the format at the moment.
|
||
</para>
|
||
|
||
<para>
|
||
<table frame="all" xml:id="dhcp6-std-options-list">
|
||
<title>List of Standard DHCPv6 Options</title>
|
||
<tgroup cols="4">
|
||
<colspec colname="name"/>
|
||
<colspec colname="code" align="center"/>
|
||
<colspec colname="type" align="center"/>
|
||
<colspec colname="array" align="center"/>
|
||
<thead>
|
||
<row><entry>Name</entry><entry>Code</entry><entry>Type</entry><entry>Array?</entry></row>
|
||
</thead>
|
||
<tbody>
|
||
<!-- Our engine uses those options on its own, admin must not configure them on his own
|
||
<row><entry>clientid</entry><entry>1</entry><entry>hex</entry><entry>false</entry></row>
|
||
<row><entry>serverid</entry><entry>2</entry><entry>hex</entry><entry>false</entry></row>
|
||
<row><entry>ia-na</entry><entry>3</entry><entry>record</entry><entry>false</entry></row>
|
||
<row><entry>ia-ta</entry><entry>4</entry><entry>uint32</entry><entry>false</entry></row>
|
||
<row><entry>iaaddr</entry><entry>5</entry><entry>record</entry><entry>false</entry></row>
|
||
<row><entry>oro</entry><entry>6</entry><entry>uint16</entry><entry>true</entry></row> -->
|
||
<row><entry>preference</entry><entry>7</entry><entry>uint8</entry><entry>false</entry></row>
|
||
|
||
<!-- Our engine uses those options on its own, admin must not configure them on his own
|
||
<row><entry>elapsed-time</entry><entry>8</entry><entry>uint16</entry><entry>false</entry></row>
|
||
<row><entry>relay-msg</entry><entry>9</entry><entry>hex</entry><entry>false</entry></row>
|
||
<row><entry>auth</entry><entry>11</entry><entry>hex</entry><entry>false</entry></row>
|
||
-->
|
||
<row><entry>unicast</entry><entry>12</entry><entry>ipv6-address</entry><entry>false</entry></row>
|
||
<!--
|
||
<row><entry>status-code</entry><entry>13</entry><entry>record</entry><entry>false</entry></row>
|
||
<row><entry>rapid-commit</entry><entry>14</entry><entry>empty</entry><entry>false</entry></row>
|
||
<row><entry>user-class</entry><entry>15</entry><entry>hex</entry><entry>false</entry></row>
|
||
<row><entry>vendor-class</entry><entry>16</entry><entry>record</entry><entry>false</entry></row>
|
||
-->
|
||
<!-- Vendor-specific Information is configurable by the administrator -->
|
||
<row><entry>vendor-opts</entry><entry>17</entry><entry>uint32</entry><entry>false</entry></row>
|
||
<!--
|
||
<row><entry>interface-id</entry><entry>18</entry><entry>hex</entry><entry>false</entry></row>
|
||
<row><entry>reconf-msg</entry><entry>19</entry><entry>uint8</entry><entry>false</entry></row>
|
||
<row><entry>reconf-accept</entry><entry>20</entry><entry>empty</entry><entry>false</entry></row> -->
|
||
-->
|
||
<row><entry>sip-server-dns</entry><entry>21</entry><entry>fqdn</entry><entry>true</entry></row>
|
||
<row><entry>sip-server-addr</entry><entry>22</entry><entry>ipv6-address</entry><entry>true</entry></row>
|
||
<row><entry>dns-servers</entry><entry>23</entry><entry>ipv6-address</entry><entry>true</entry></row>
|
||
<row><entry>domain-search</entry><entry>24</entry><entry>fqdn</entry><entry>true</entry></row>
|
||
<!-- <row><entry>ia-pd</entry><entry>25</entry><entry>record</entry><entry>false</entry></row> -->
|
||
<!-- <row><entry>iaprefix</entry><entry>26</entry><entry>record</entry><entry>false</entry></row> -->
|
||
<row><entry>nis-servers</entry><entry>27</entry><entry>ipv6-address</entry><entry>true</entry></row>
|
||
<row><entry>nisp-servers</entry><entry>28</entry><entry>ipv6-address</entry><entry>true</entry></row>
|
||
<row><entry>nis-domain-name</entry><entry>29</entry><entry>fqdn</entry><entry>true</entry></row>
|
||
<row><entry>nisp-domain-name</entry><entry>30</entry><entry>fqdn</entry><entry>true</entry></row>
|
||
<row><entry>sntp-servers</entry><entry>31</entry><entry>ipv6-address</entry><entry>true</entry></row>
|
||
<row><entry>information-refresh-time</entry><entry>32</entry><entry>uint32</entry><entry>false</entry></row>
|
||
<row><entry>bcmcs-server-dns</entry><entry>33</entry><entry>fqdn</entry><entry>true</entry></row>
|
||
<row><entry>bcmcs-server-addr</entry><entry>34</entry><entry>ipv6-address</entry><entry>true</entry></row>
|
||
<row><entry>geoconf-civic</entry><entry>36</entry><entry>record (uint8, uint16, hex)</entry><entry>false</entry></row>
|
||
<row><entry>remote-id</entry><entry>37</entry><entry>record (uint32, hex)</entry><entry>false</entry></row>
|
||
<row><entry>subscriber-id</entry><entry>38</entry><entry>hex</entry><entry>false</entry></row>
|
||
<row><entry>client-fqdn</entry><entry>39</entry><entry>record (uint8, fqdn)</entry><entry>false</entry></row>
|
||
<row><entry>pana-agent</entry><entry>40</entry><entry>ipv6-address</entry><entry>true</entry></row>
|
||
<row><entry>new-posix-timezone</entry><entry>41</entry><entry>string</entry><entry>false</entry></row>
|
||
<row><entry>new-tzdb-timezone</entry><entry>42</entry><entry>string</entry><entry>false</entry></row>
|
||
<row><entry>ero</entry><entry>43</entry><entry>uint16</entry><entry>true</entry></row>
|
||
<row><entry>lq-query (1)</entry><entry>44</entry><entry>record (uint8, ipv6-address)</entry><entry>false</entry></row>
|
||
<row><entry>client-data (1)</entry><entry>45</entry><entry>empty</entry><entry>false</entry></row>
|
||
<row><entry>clt-time (1)</entry><entry>46</entry><entry>uint32</entry><entry>false</entry></row>
|
||
<row><entry>lq-relay-data (1)</entry><entry>47</entry><entry>record (ipv6-address, hex)</entry><entry>false</entry></row>
|
||
<row><entry>lq-client-link (1)</entry><entry>48</entry><entry>ipv6-address</entry><entry>true</entry></row>
|
||
<row><entry>v6-lost</entry><entry>51</entry><entry>fqdn</entry><entry>false</entry></row>
|
||
<row><entry>capwap-ac-v6</entry><entry>52</entry><entry>ipv6-address</entry><entry>true</entry></row>
|
||
<row><entry>relay-id</entry><entry>53</entry><entry>hex</entry><entry>false</entry></row>
|
||
<row><entry>v6-access-domain</entry><entry>57</entry><entry>fqdn</entry><entry>false</entry></row>
|
||
<row><entry>sip-ua-cs-list</entry><entry>58</entry><entry>fqdn</entry><entry>true</entry></row>
|
||
<row><entry>bootfile-url</entry><entry>59</entry><entry>string</entry><entry>false</entry></row>
|
||
<row><entry>bootfile-param</entry><entry>60</entry><entry>tuple</entry><entry>true</entry></row>
|
||
<row><entry>client-arch-type</entry><entry>61</entry><entry>uint16</entry><entry>true</entry></row>
|
||
<row><entry>nii</entry><entry>62</entry><entry>record (uint8, uint8, uint8)</entry><entry>false</entry></row>
|
||
<row><entry>aftr-name</entry><entry>64</entry><entry>fqdn</entry><entry>false</entry></row>
|
||
<row><entry>erp-local-domain-name</entry><entry>65</entry><entry>fqdn</entry><entry>false</entry></row>
|
||
<row><entry>rsoo</entry><entry>66</entry><entry>empty</entry><entry>false</entry></row>
|
||
<row><entry>pd-exclude</entry><entry>67</entry><entry>hex</entry><entry>false</entry></row>
|
||
<row><entry>rdnss-selection</entry><entry>74</entry><entry>record (ipv6-address, uint8, fqdn)</entry><entry>true</entry></row>
|
||
<row><entry>client-linklayer-addr</entry><entry>79</entry><entry>hex</entry><entry>false</entry></row>
|
||
<row><entry>link-address</entry><entry>80</entry><entry>ipv6-address</entry><entry>false</entry></row>
|
||
<row><entry>solmax-rt</entry><entry>82</entry><entry>uint32</entry><entry>false</entry></row>
|
||
<row><entry>inf-max-rt</entry><entry>83</entry><entry>uint32</entry><entry>false</entry></row>
|
||
<!-- <row><entry>dhcpv4-message</entry><entry>87</entry><entry>hex</entry><entry>false</entry></row> -->
|
||
<row><entry>dhcp4o6-server-addr</entry><entry>88</entry><entry>ipv6-address</entry><entry>true</entry></row>
|
||
<row><entry>s46-rule</entry><entry>89</entry><entry>record (uint8, uint8, uint8, ipv4-address, ipv6-prefix)</entry><entry>false</entry></row>
|
||
<row><entry>s46-br</entry><entry>90</entry><entry>ipv6-address</entry><entry>false</entry></row>
|
||
<row><entry>s46-dmr</entry><entry>91</entry><entry>ipv6-prefix</entry><entry>false</entry></row>
|
||
<row><entry>s46-v4v6bind</entry><entry>92</entry><entry>record (ipv4-address, ipv6-prefix)</entry><entry>false</entry></row>
|
||
<row><entry>s46-portparams</entry><entry>93</entry><entry>record(uint8, psid)</entry><entry>false</entry></row>
|
||
<row><entry>s46-cont-mape</entry><entry>94</entry><entry>empty</entry><entry>false</entry></row>
|
||
<row><entry>s46-cont-mapt</entry><entry>95</entry><entry>empty</entry><entry>false</entry></row>
|
||
<row><entry>s46-cont-lw</entry><entry>96</entry><entry>empty</entry><entry>false</entry></row>
|
||
<row><entry>v6-captive-portal</entry><entry>103</entry><entry>string</entry><entry>false</entry></row>
|
||
<row><entry>ipv6-address-andsf</entry><entry>143</entry><entry>ipv6-address</entry><entry>true</entry></row>
|
||
</tbody>
|
||
</tgroup>
|
||
</table>
|
||
Options marked with (1) have option definitions, but the logic
|
||
behind them is not implemented. That means that technically Kea
|
||
knows how to parse them in incoming message or how to send them
|
||
if configured to do so, but not what to do with them. Since the
|
||
related RFCs require certain processing, the support for those
|
||
options is non-functional. However, it may be useful in some
|
||
limited lab testing, hence the definition formats are listed here.
|
||
</para>
|
||
</section>
|
||
|
||
<section id="s46-options">
|
||
<title>Common Softwire46 Options</title>
|
||
<para>
|
||
Softwire46 options are involved in IPv4 over IPv6 provisioning by
|
||
means of tunneling or translation as specified in the
|
||
<ulink url="http://tools.ietf.org/html/rfc7598">RFC 7598</ulink>.
|
||
The following sections provide configuration examples of these
|
||
options.
|
||
</para>
|
||
|
||
<section id="s46-containers">
|
||
<title>Softwire46 Container Options</title>
|
||
<para>
|
||
S46 container options group rules and optional port parameters
|
||
for a specified domain. There are three container options specified
|
||
in the "dhcp6" (top level) option space: MAP-E Container option,
|
||
MAP-T Container option and S46 Lightweight 4over6 Container option.
|
||
These options only contain encapsulated options specified below.
|
||
They do not include any data fields.
|
||
</para>
|
||
|
||
<para>
|
||
In order to configure the server to send specific container option
|
||
along with all encapsulated options, the container option must be
|
||
included in the server configuration as shown below:
|
||
<screen>
|
||
"Dhcp6": {
|
||
...
|
||
"option-data": [
|
||
{
|
||
"name": "s46-cont-mape"
|
||
} ],
|
||
...
|
||
}
|
||
</screen>
|
||
|
||
This configuration will cause the server to include MAP-E Container
|
||
option to the client. Use "s46-cont-mapt" or "s46-cont-lw" for the
|
||
MAP-T Container and S46 Lightweight 4over6 Container options
|
||
respectively.
|
||
</para>
|
||
|
||
<para>
|
||
All remaining softwire options described below are included in one
|
||
of the container options. Thus, they have to be included in appropriate
|
||
option spaces by selecting a "space" name, which specifies in which
|
||
option they are supposed to be included.
|
||
</para>
|
||
</section>
|
||
|
||
<section>
|
||
<title>S46 Rule Option</title>
|
||
<para>
|
||
The S46 Rule option is used for conveying the Basic Mapping Rule (BMR)
|
||
and Forwarding Mapping Rule (FMR).
|
||
<screen>
|
||
{
|
||
"space": "s46-cont-mape-options",
|
||
"name": "s46-rule",
|
||
"data": "128, 0, 24, 192.0.2.0, 2001:db8:1::/64"
|
||
}
|
||
</screen>
|
||
Other possible "space" value is "s46-cont-mapt-options".
|
||
</para>
|
||
|
||
<para>
|
||
The S46 Rule option conveys a number of parameters:
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
<simpara><command>flags</command>, an unsigned 8 bits integer, with
|
||
currently only the most significant bit specified. It denotes whether
|
||
the rule can be used for forwarding (128) or not (0).
|
||
</simpara>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<simpara><command>ea-len</command>, an 8 bits long Embedded Address length. Allowed values
|
||
range from 0 to 48.</simpara>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<simpara><command>IPv4 prefix length</command>, 8 bits long; expresses the prefix length of the
|
||
Rule IPv4 prefix specified in the ipv4-prefix field. Allowed
|
||
values range from 0 to 32.</simpara>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<simpara><command>IPv4 prefix</command>, a fixed-length 32-bit field that specifies the IPv4
|
||
prefix for the S46 rule. The bits in the prefix after prefix4-len
|
||
number of bits are reserved and MUST be initialized to zero by the
|
||
sender and ignored by the receiver.</simpara>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<simpara><command>IPv6 prefix</command> in prefix/length notation that specifies the IPv6 domain
|
||
prefix for the S46 rule. The field is padded on the right with zero
|
||
bits up to the nearest octet boundary when prefix6-len is not evenly
|
||
divisible by 8.</simpara>
|
||
</listitem>
|
||
|
||
</itemizedlist>
|
||
</para>
|
||
</section>
|
||
<section>
|
||
<title>S46 BR Option</title>
|
||
<para>
|
||
The S46 BR option is used to convey the IPv6 address of the
|
||
Border Relay. This option is mandatory in the MAP-E
|
||
Container option and not permitted in the MAP-T and
|
||
S46 Lightweight 4over6 Container options.
|
||
<screen>
|
||
{
|
||
"space": "s46-cont-mape-options",
|
||
"name": "s46-br",
|
||
"data": "2001:db8:cafe::1",
|
||
}
|
||
</screen>
|
||
Other possible "space" value is "s46-cont-lw-options".
|
||
</para>
|
||
</section>
|
||
|
||
<section>
|
||
<title>S46 DMR Option</title>
|
||
<para>
|
||
The S46 DMR option is used to convey values for the Default
|
||
Mapping Rule (DMR). This option is mandatory in the MAP-T
|
||
container option and not permitted in the MAP-E and S46
|
||
Lightweight 4over6 Container options.
|
||
<screen>
|
||
{
|
||
"space": "s46-cont-mapt-options",
|
||
"name": "s46-dmr",
|
||
"data": "2001:db8:cafe::/64",
|
||
}
|
||
</screen>
|
||
This option must not be included in other containers.
|
||
</para>
|
||
</section>
|
||
|
||
<section>
|
||
<title>S46 IPv4/IPv6 Address Binding option.</title>
|
||
<para>
|
||
The S46 IPv4/IPv6 Address Binding option may be used to specify
|
||
the full or shared IPv4 address of the Customer Edge (CE).
|
||
The IPv6 prefix field is used by the CE to identify the
|
||
correct prefix to use for the tunnel source.
|
||
<screen>
|
||
{
|
||
"space": "s46-cont-lw",
|
||
"name": "s46-v4v6bind",
|
||
"data": "192.0.2.3, 2001:db8:1:cafe::/64"
|
||
}
|
||
</screen>
|
||
This option must not be included in other containers.
|
||
</para>
|
||
</section>
|
||
<section>
|
||
<title>S46 Port Parameters</title>
|
||
<para>
|
||
The S46 Port Parameters option specifies optional port set
|
||
information that MAY be provided to CEs
|
||
<screen>
|
||
{
|
||
"space": "s46-rule-options",
|
||
"name": "s46-portparams",
|
||
"data": "2, 3/4",
|
||
}
|
||
</screen>
|
||
Other possible "space" value is "s46-v4v6bind" to include
|
||
this option in the S46 IPv4/IPv6 Address Binding option.
|
||
</para>
|
||
<para>
|
||
Note that the second value in the example above specifies the
|
||
PSID and PSID length fields in the format of PSID/PSID length.
|
||
This is equivalent to the values of PSID-len=4 and
|
||
PSID=12288 conveyed in the S46 Port Parameters option.
|
||
</para>
|
||
</section>
|
||
</section>
|
||
|
||
<section xml:id="dhcp6-custom-options">
|
||
<title>Custom DHCPv6 Options</title>
|
||
<para>It is possible to define options in addition to the standard ones.
|
||
Assume that we want to define a new DHCPv6 option called "foo" which will have
|
||
code 100 and which will convey a single unsigned 32 bit integer value. We can define
|
||
such an option by using the following commands:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"option-def": [
|
||
{
|
||
<userinput>"name": "foo",
|
||
"code": 100,
|
||
"type": "uint32",
|
||
"array": false,
|
||
"record-types": "",
|
||
"space": "dhcp6",
|
||
"encapsulate": ""</userinput>
|
||
}, ...
|
||
],
|
||
...
|
||
}
|
||
</screen>
|
||
The "false" value of the <command>array</command> parameter determines that the option does
|
||
NOT comprise an array of "uint32" values but rather a single value. Two
|
||
other parameters have been left blank: <command>record-types</command> and
|
||
<command>encapsulate</command>.
|
||
The former specifies the comma separated list of option data fields if the
|
||
option comprises a record of data fields. The <command>record-types</command> value should
|
||
be non-empty if the <command>type</command> is set to "record". Otherwise it must be left
|
||
blank. The latter parameter specifies the name of the option space being
|
||
encapsulated by the particular option. If the particular option does not
|
||
encapsulate any option space it should be left blank. Note that the above
|
||
example only defines the format of the new option, it does not set its
|
||
value(s).
|
||
</para>
|
||
|
||
<para>The <command>name</command>, <command>code</command> and
|
||
<command>type</command> parameters are required, all others are
|
||
optional. The <command>array</command> default value is
|
||
<command>false</command>. The <command>record-types</command>
|
||
and <command>encapsulate</command> default values are blank
|
||
(i.e. ""). The default <command>space</command> is "dhcp6".
|
||
</para>
|
||
|
||
<para>Once the new option format is defined, its value is set
|
||
in the same way as for a standard option. For example the following
|
||
commands set a global value that applies to all subnets.
|
||
<screen>
|
||
"Dhcp6": {
|
||
"option-data": [
|
||
{
|
||
<userinput>"name": "foo",
|
||
"code": 100,
|
||
"space": "dhcp6",
|
||
"csv-format": true,
|
||
"data": "12345"</userinput>
|
||
}, ...
|
||
],
|
||
...
|
||
}
|
||
</screen>
|
||
</para>
|
||
|
||
<para>New options can take more complex forms than simple use of
|
||
primitives (uint8, string, ipv6-address etc): it is possible to
|
||
define an option comprising a number of existing primitives.
|
||
</para>
|
||
<para>
|
||
For example, assume we want to define a new option that will consist of an IPv6
|
||
address, followed by an unsigned 16 bit integer, followed by a
|
||
boolean value, followed by a text string. Such an option could
|
||
be defined in the following way:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"option-def": [
|
||
{
|
||
<userinput>"name": "bar",
|
||
"code": 101,
|
||
"space": "dhcp6",
|
||
"type": "record",
|
||
"array": false,
|
||
"record-types": "ipv6-address, uint16, boolean, string",
|
||
"encapsulate": ""</userinput>
|
||
}, ...
|
||
],
|
||
...
|
||
}
|
||
</screen>
|
||
The "type" is set to "record" to indicate that the option contains
|
||
multiple values of different types. These types are given as a comma-separated
|
||
list in the "record-types" field and should be those listed in <xref linkend="dhcp-types"/>.
|
||
</para>
|
||
<para>
|
||
The values of the option are set as follows:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"option-data": [
|
||
{
|
||
<userinput>"name": "bar",
|
||
"space": "dhcp6",
|
||
"code": 101,
|
||
"csv-format": true,
|
||
"data": "2001:db8:1::10, 123, false, Hello World"</userinput>
|
||
}
|
||
],
|
||
...
|
||
}</screen>
|
||
|
||
<command>csv-format</command> is set <command>true</command> to indicate
|
||
that the <command>data</command> field comprises a command-separated list
|
||
of values. The values in the "data" must correspond to the types set in
|
||
the "record-types" field of the option definition.
|
||
</para>
|
||
|
||
<para>
|
||
When <command>array</command> is set to <command>true</command>
|
||
and <command>type</command> is set to "record", the last field
|
||
is an array, i.e., it can contain more than one value as in:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"option-def": [
|
||
{
|
||
<userinput>"name": "bar",
|
||
"code": 101,
|
||
"space": "dhcp6",
|
||
"type": "record",
|
||
"array": true,
|
||
"record-types": "ipv6-address, uint16",
|
||
"encapsulate": ""</userinput>
|
||
}, ...
|
||
],
|
||
...
|
||
}
|
||
</screen>
|
||
The new option content is one IPv6 address followed by one or more 16
|
||
bit unsigned integers.
|
||
</para>
|
||
|
||
<note>
|
||
<para>In the general case, boolean values are specified as <command>true</command> or
|
||
<command>false</command>, without quotes. Some specific boolean parameters may
|
||
accept also <command>"true"</command>, <command>"false"</command>,
|
||
<command>0</command>, <command>1</command>, <command>"0"</command> and
|
||
<command>"1"</command>. Future versions of Kea will accept all those values
|
||
for all boolean parameters.</para>
|
||
</note>
|
||
|
||
</section>
|
||
|
||
<section xml:id="dhcp6-vendor-opts">
|
||
<title>DHCPv6 Vendor-Specific Options</title>
|
||
<para>
|
||
Currently there are two option spaces defined for the DHCPv6
|
||
daemon: "dhcp6" (for top level DHCPv6 options) and "vendor-opts-space",
|
||
which is empty by default, but in which options can be defined.
|
||
Those options will be carried in the Vendor-Specific
|
||
Information option (code 17). The following examples show how to
|
||
define an option "foo" with code 1 that consists of an IPv6 address,
|
||
an unsigned 16 bit integer and a string. The "foo" option is
|
||
conveyed in a Vendor-Specific Information option. This option
|
||
comprises a single uint32 value that is set to "12345".
|
||
The sub-option "foo" follows the data field holding this value.
|
||
<screen>
|
||
"Dhcp6": {
|
||
"option-def": [
|
||
{
|
||
<userinput>"name": "foo",
|
||
"code": 1,
|
||
"space": "vendor-opts-space",
|
||
"type": "record",
|
||
"array": false,
|
||
"record-types": "ipv6-address, uint16, string",
|
||
"encapsulate": ""</userinput>
|
||
}
|
||
],
|
||
...
|
||
}</screen>
|
||
(Note that the option space is set to <command>vendor-opts-space</command>.)
|
||
Once the option format is defined, the next step is to define actual values
|
||
for that option:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"option-data": [
|
||
{
|
||
<userinput>"name": "foo",
|
||
"space": "vendor-opts-space",
|
||
"data": "2001:db8:1::10, 123, Hello World"</userinput>
|
||
},
|
||
...
|
||
],
|
||
...
|
||
}</screen>
|
||
We should also define a value (enterprise-number) for the
|
||
Vendor-specific Information option, that conveys our option "foo".
|
||
<screen>
|
||
"Dhcp6": {
|
||
"option-data": [
|
||
...,
|
||
{
|
||
<userinput>"name": "vendor-opts",
|
||
"data": "12345"</userinput>
|
||
}
|
||
],
|
||
...
|
||
}</screen>
|
||
Alternatively, the option can be specified using its code.
|
||
<screen>
|
||
"Dhcp6": {
|
||
"option-data": [
|
||
...,
|
||
{
|
||
<userinput>"code": 17,
|
||
"data": "12345"</userinput>
|
||
}
|
||
],
|
||
...
|
||
}</screen>
|
||
</para>
|
||
</section>
|
||
|
||
<section xml:id="dhcp6-option-spaces">
|
||
<title>Nested DHCPv6 Options (Custom Option Spaces)</title>
|
||
<para>It is sometimes useful to define completely new option
|
||
spaces. This is useful if the user wants their new option to
|
||
convey sub-options that use a separate numbering scheme, for
|
||
example sub-options with codes 1 and 2. Those option codes
|
||
conflict with standard DHCPv6 options, so a separate option
|
||
space must be defined.
|
||
</para>
|
||
<para>Note that it is not required to create a new option space when
|
||
defining sub-options for a standard option because it is
|
||
created by default if the standard option is meant to convey
|
||
any sub-options (see <xref linkend="dhcp6-vendor-opts"/>).
|
||
</para>
|
||
<para>
|
||
Assume that we want to have a DHCPv6 option called "container"
|
||
with code 102 that conveys two sub-options with codes 1 and 2.
|
||
First we need to define the new sub-options:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"option-def": [
|
||
{
|
||
<userinput>"name": "subopt1",
|
||
"code": 1,
|
||
"space": "isc",
|
||
"type": "ipv6-address",
|
||
"record-types": "",
|
||
"array": false,
|
||
"encapsulate": ""</userinput>
|
||
},
|
||
{
|
||
<userinput>"name": "subopt2",
|
||
"code": 2,
|
||
"space": "isc",
|
||
"type": "string",
|
||
"record-types": "",
|
||
"array": false
|
||
"encapsulate": ""</userinput>
|
||
}
|
||
],
|
||
...
|
||
}</screen>
|
||
Note that we have defined the options to belong to a new option space
|
||
(in this case, "isc").
|
||
</para>
|
||
<para>
|
||
The next step is to define a regular DHCPv6 option and specify that it
|
||
should include options from the isc option space:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"option-def": [
|
||
...,
|
||
{
|
||
<userinput>"name": "container",
|
||
"code": 102,
|
||
"space": "dhcp6",
|
||
"type": "empty",
|
||
"array": false,
|
||
"record-types": "",
|
||
"encapsulate": "isc"</userinput>
|
||
}
|
||
],
|
||
...
|
||
}</screen>
|
||
|
||
The name of the option space in which the sub-options are defined is set in
|
||
the <command>encapsulate</command> field. The <command>type</command> field
|
||
is set to <command>empty</command> which limits this option to only carrying
|
||
data in sub-options.
|
||
</para>
|
||
<para>
|
||
Finally, we can set values for the new options:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"option-data": [
|
||
{
|
||
<userinput>"name": "subopt1",
|
||
"code": 1,
|
||
"space": "isc",
|
||
"data": "2001:db8::abcd"</userinput>
|
||
},
|
||
}
|
||
<userinput>"name": "subopt2",
|
||
"code": 2,
|
||
"space": "isc",
|
||
"data": "Hello world"</userinput>
|
||
},
|
||
{
|
||
<userinput>"name": "container",
|
||
"code": 102,
|
||
"space": "dhcp6"</userinput>
|
||
}
|
||
],
|
||
...
|
||
}
|
||
</screen>
|
||
</para>
|
||
|
||
<para>Note that it is possible to create an option which carries some data
|
||
in addition to the sub-options defined in the encapsulated option space.
|
||
For example, if the "container" option from the previous example was
|
||
required to carry an uint16 value as well as the sub-options, the "type"
|
||
value would have to be set to "uint16" in the option definition. (Such an
|
||
option would then have the following data structure: DHCP header, uint16
|
||
value, sub-options.) The value specified with the "data" parameter — which
|
||
should be a valid integer enclosed in quotes, e.g. "123" — would then be
|
||
assigned to the uint16 field in the "container" option.
|
||
</para>
|
||
</section>
|
||
|
||
<section xml:id="dhcp6-option-data-defaults">
|
||
<title>Unspecified Parameters for DHCPv6 Option Configuration</title>
|
||
<para>In many cases it is not required to specify all parameters for
|
||
an option configuration and the default values can be used. However, it is
|
||
important to understand the implications of not specifying some of them
|
||
as it may result in configuration errors. The list below explains
|
||
the behavior of the server when a particular parameter is not explicitly
|
||
specified:
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
<simpara><command>name</command> - the server requires an option name or
|
||
option code to identify an option. If this parameter is unspecified, the
|
||
option code must be specified.
|
||
</simpara>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<simpara><command>code</command> - the server requires an option name or
|
||
option code to identify an option. This parameter may be left unspecified if
|
||
the <command>name</command> parameter is specified. However, this also
|
||
requires that the particular option has its definition (it is either a
|
||
standard option or an administrator created a definition for the option
|
||
using an 'option-def' structure), as the option definition associates an
|
||
option with a particular name. It is possible to configure an option
|
||
for which there is no definition (unspecified option format).
|
||
Configuration of such options requires the use of option code.
|
||
</simpara>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<simpara><command>space</command> - if the option space is unspecified it
|
||
will default to 'dhcp6' which is an option space holding DHCPv6 standard
|
||
options.
|
||
</simpara>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<simpara><command>data</command> - if the option data is unspecified it
|
||
defaults to an empty value. The empty value is mostly used for the
|
||
options which have no payload (boolean options), but it is legal to specify
|
||
empty values for some options which carry variable length data and which
|
||
spec allows for the length of 0. For such options, the data parameter
|
||
may be omitted in the configuration.</simpara>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<simpara><command>csv-format</command> - if this value is not
|
||
specified the server will assume that the option data is specified as
|
||
a list of comma separated values to be assigned to individual fields
|
||
of the DHCP option. This behavior has changed in Kea 1.2. Older
|
||
versions used additional logic to determine whether the csv-format
|
||
should be true or false. That is no longer the case.
|
||
</simpara>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
|
||
</section>
|
||
|
||
<section xml:id="dhcp6-config-subnets">
|
||
<title>IPv6 Subnet Selection</title>
|
||
<para>
|
||
The DHCPv6 server may receive requests from local (connected to the
|
||
same subnet as the server) and remote (connecting via relays) clients.
|
||
As the server may have many subnet configurations defined, it must select
|
||
an appropriate subnet for a given request.
|
||
</para>
|
||
<para>
|
||
The server can not assume which of the configured subnets are local. In IPv4
|
||
it is possible as there is a reasonable expectation that the
|
||
server will have a (global) IPv4 address configured on the interface,
|
||
and can use that information to detect whether a subnet is local or
|
||
not. That assumption is not true in IPv6: the DHCPv6 server must be able
|
||
to operate while only using link-local addresses. Therefore an optional
|
||
<command>interface</command> parameter is available within a subnet definition
|
||
to designate that a given subnet is local, i.e. reachable directly over
|
||
the specified interface. For example the server that is intended to serve
|
||
a local subnet over eth0 may be configured as follows:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"subnet6": [
|
||
{
|
||
"subnet": "2001:db8:beef::/48",
|
||
"pools": [
|
||
{
|
||
"pool": "2001:db8:beef::/48"
|
||
}
|
||
],
|
||
<userinput>"interface": "eth0"</userinput>
|
||
}
|
||
],
|
||
...
|
||
}
|
||
</screen>
|
||
</para>
|
||
</section>
|
||
|
||
<section xml:id="dhcp6-rapid-commit">
|
||
<title>Rapid Commit</title>
|
||
<para>The Rapid Commit option, described in
|
||
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc8415">RFC 8415</link>, is supported
|
||
by the Kea DHCPv6 server. However, support is disabled by default for
|
||
all subnets. It can be enabled for a particular subnet using the
|
||
<command>rapid-commit</command> parameter as shown below:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"subnet6": [
|
||
{
|
||
"subnet": "2001:db8:beef::/48",
|
||
<userinput>"rapid-commit": true</userinput>,
|
||
"pools": [
|
||
{
|
||
"pool": "2001:db8:beef::1-2001:db8:beef::10"
|
||
}
|
||
],
|
||
}
|
||
],
|
||
...
|
||
}
|
||
</screen>
|
||
</para>
|
||
<para>
|
||
This setting only affects the subnet for which the
|
||
<command>rapid-commit</command> is set to <command>true</command>.
|
||
For clients connected to other subnets, the server will ignore the
|
||
Rapid Commit option sent by the client and will follow the 4-way
|
||
exchange procedure, i.e. respond with an Advertise for a Solicit
|
||
containing a Rapid Commit option.
|
||
</para>
|
||
</section>
|
||
|
||
<section xml:id="dhcp6-relays">
|
||
<title>DHCPv6 Relays</title>
|
||
<para>
|
||
A DHCPv6 server with multiple subnets defined must select the
|
||
appropriate subnet when it receives a request from a client. For clients
|
||
connected via relays, two mechanisms are used:
|
||
</para>
|
||
<para>
|
||
The first uses the linkaddr field in the RELAY_FORW message. The name
|
||
of this field is somewhat misleading in that it does not contain a link-layer
|
||
address: instead, it holds an address (typically a global address) that is
|
||
used to identify a link. The DHCPv6 server checks if the address belongs
|
||
to a defined subnet and, if it does, that subnet is selected for the client's
|
||
request.
|
||
</para>
|
||
<para>
|
||
The second mechanism is based on interface-id options. While forwarding a client's
|
||
message, relays may insert an interface-id option into the message that
|
||
identifies the interface on the relay that received the message. (Some
|
||
relays allow configuration of that parameter, but it is sometimes
|
||
hardcoded and may range from the very simple (e.g. "vlan100") to the very cryptic:
|
||
one example seen on real hardware was "ISAM144|299|ipv6|nt:vp:1:110"). The
|
||
server can use this information to select the appropriate subnet.
|
||
The information is also returned to the relay which then knows the
|
||
interface to use to transmit the response to the client. In order for
|
||
this to work successfully, the relay interface IDs must be unique within
|
||
the network and the server configuration must match those values.
|
||
</para>
|
||
<para>
|
||
When configuring the DHCPv6 server, it should be noted that two
|
||
similarly-named parameters can be configured for a subnet:
|
||
<itemizedlist>
|
||
<listitem><simpara>
|
||
<command>interface</command> defines which local network interface can be used
|
||
to access a given subnet.
|
||
</simpara></listitem>
|
||
<listitem><simpara>
|
||
<command>interface-id</command> specifies the content of the interface-id option
|
||
used by relays to identify the interface on the relay to which
|
||
the response packet is sent.
|
||
</simpara></listitem>
|
||
</itemizedlist>
|
||
The two are mutually exclusive: a subnet cannot be both reachable locally
|
||
(direct traffic) and via relays (remote traffic). Specifying both is a
|
||
configuration error and the DHCPv6 server will refuse such a configuration.
|
||
</para>
|
||
|
||
<para>
|
||
The following example configuration shows how to specify an interface-id with
|
||
a value of "vlan123".
|
||
<screen>
|
||
"Dhcp6": {
|
||
"subnet6": [
|
||
{
|
||
"subnet": "2001:db8:beef::/48",
|
||
"pools": [
|
||
{
|
||
"pool": "2001:db8:beef::/48"
|
||
}
|
||
],
|
||
<userinput>"interface-id": "vlan123"</userinput>
|
||
}
|
||
],
|
||
...
|
||
}
|
||
</screen>
|
||
</para>
|
||
</section>
|
||
|
||
<section xml:id="dhcp6-rsoo">
|
||
<title>Relay-Supplied Options</title>
|
||
<para><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc6422">RFC 6422</link>
|
||
defines a mechanism called Relay-Supplied DHCP Options. In certain cases relay
|
||
agents are the only entities that may have specific information. They can
|
||
insert options when relaying messages from the client to the server. The
|
||
server will then do certain checks and copy those options to the response
|
||
that will be sent to the client.</para>
|
||
|
||
<para>There are certain conditions that must be met for the option to be
|
||
included. First, the server must not provide the option itself. In
|
||
other words, if both relay and server provide an option, the server always
|
||
takes precedence. Second, the option must be RSOO-enabled. IANA maintains a
|
||
list of RSOO-enabled options <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml#options-relay-supplied">here</link>.
|
||
However, there may be cases when system administrators want to echo other
|
||
options. Kea can be instructed to treat other options as RSOO-enabled.
|
||
For example, to mark options 110, 120 and 130 as RSOO-enabled, the following
|
||
syntax should be used:
|
||
<screen>
|
||
"Dhcp6": {
|
||
<userinput>"relay-supplied-options": [ "110", "120", "130" ],</userinput>
|
||
...
|
||
}
|
||
</screen>
|
||
</para>
|
||
<para>As of March 2015, only option 65 is RSOO-enabled by IANA. This
|
||
option will always be treated as such and there's no need to explicitly
|
||
mark it. Also, when enabling standard options, it is possible to use their
|
||
names, rather than option code, e.g. (e.g. use
|
||
<command>dns-servers</command> instead of <command>23</command>). See
|
||
<xref linkend="dhcp6-std-options-list"/> for the names. In certain cases
|
||
it could also work for custom options, but due to the nature of the parser
|
||
code this may be unreliable and should be avoided.
|
||
</para>
|
||
|
||
</section>
|
||
|
||
<section xml:id="dhcp6-client-classifier">
|
||
<title>Client Classification in DHCPv6</title>
|
||
|
||
<para>
|
||
The DHCPv6 server includes support for client classification. For a deeper
|
||
discussion of the classification process see <xref linkend="classify"/>.
|
||
</para>
|
||
|
||
<para>In certain cases it is useful to configure the server to differentiate between
|
||
DHCP clients types and treat them accordingly. It is envisaged that client
|
||
classification will be used for modifying the behavior of almost any part of
|
||
the DHCP message processing. In the current release of Kea, there are three
|
||
mechanisms that take advantage of the client classification in DHCPv6: subnet
|
||
selection, address pool selection and DHCP options assignment.
|
||
</para>
|
||
|
||
<para>
|
||
In certain cases it is useful to differentiate between different types
|
||
of clients and treat them accordingly. It is envisaged that client
|
||
classification will be used for changing the behavior of almost any part of
|
||
the DHCP message processing. In the current release of the software however,
|
||
there are only some mechanisms that take advantage of client classification:
|
||
subnet selection, pool selection, and assignment of different options.
|
||
</para>
|
||
|
||
<para>
|
||
Kea can be instructed to limit access to given subnets based on class information.
|
||
This is particularly useful for cases where two types of devices share the
|
||
same link and are expected to be served from two different subnets. The
|
||
primary use case for such a scenario is cable networks. Here, there are two
|
||
classes of devices: the cable modem itself, which should be handed a lease
|
||
from subnet A and all other devices behind the modem that should get a lease
|
||
from subnet B. That segregation is essential to prevent overly curious
|
||
users from playing with their cable modems. For details on how to set up
|
||
class restrictions on subnets, see <xref linkend="classification-subnets"/>.
|
||
</para>
|
||
|
||
<para>
|
||
When subnets belong to a shared network the classification applies
|
||
to subnet selection but not to pools, e.g., a pool in a subnet
|
||
limited to a particular class can still be used by clients which do not
|
||
belong to the class if the pool they are expected to use is exhausted.
|
||
So the limit access based on class information is also available
|
||
at the address/prefix pool level, see <xref
|
||
linkend="classification-pools"/> within a subnet.
|
||
This is useful when to segregate clients belonging to the same subnet
|
||
into different address ranges.
|
||
</para>
|
||
|
||
<para>
|
||
In a similar way a pool can be constrained to serve only known
|
||
clients, i.e. clients which have a reservation, using the
|
||
built-in "KNOWN" or "UNKNOWN" classes. One can assign addresses
|
||
to registered clients without giving a different address per
|
||
reservations, for instance when there is not enough available
|
||
addresses. The determination whether there is a reservation
|
||
for a given client is made after a subnet is selected. As such, it
|
||
is not possible to use KNOWN/UNKNOWN classes to select a shared
|
||
network or a subnet.
|
||
</para>
|
||
|
||
<para>
|
||
The process of doing classification is conducted in five steps.
|
||
The first step is to assess an incoming packet and assign it to
|
||
zero or more classes.
|
||
The second step is to choose a subnet, possibly based on the
|
||
class information.
|
||
The next step is to evaluate class expressions depending on the
|
||
built-in "KNOWN"/"UNKNOWN" classes after host reservation lookup,
|
||
using them for pool/pd-pool selection and to assign classes from host
|
||
reservations.
|
||
After the list of required classes is built and each class of the list
|
||
has its expression evaluated: when it returns true the packet is added
|
||
as a member of the class.
|
||
The last step is to assign options again possibly based on the class
|
||
information.
|
||
More complete and detailed description is available in
|
||
<xref linkend="classify"/>.
|
||
</para>
|
||
|
||
<para>
|
||
There are two main methods of doing classification. The first is automatic and relies
|
||
on examining the values in the vendor class options or existence of a
|
||
host reservation. Information from these
|
||
options is extracted and a class name is constructed from it and added to
|
||
the class list for the packet. The second allows for specifying an expression
|
||
that is evaluated for each packet. If the result is true the packet is
|
||
a member of the class.
|
||
</para>
|
||
|
||
<note><para>
|
||
Care should be taken with client classification as it is easy for
|
||
clients that do not meet class criteria to be denied any service altogether.
|
||
</para></note>
|
||
|
||
<section>
|
||
<title>Defining and Using Custom Classes</title>
|
||
<para>
|
||
The following example shows how to configure a class using an expression
|
||
and a subnet making use of that class. This configuration defines the
|
||
class named "Client_enterprise". It is comprised
|
||
of all clients whose client identifiers start with the given hex string (which
|
||
would indicate a DUID based on an enterprise id of 0xAABBCCDD).
|
||
They will be given an address from 2001:db8:1::0 to 2001:db8:1::FFFF and
|
||
the addresses of their DNS servers set to 2001:db8:0::1 and 2001:db8:2::1.
|
||
|
||
<screen>
|
||
"Dhcp6": {
|
||
"client-classes": [
|
||
{<userinput>
|
||
"name": "Client_enterprise",
|
||
"test": "substring(option[1].hex,0,6) == 0x0002AABBCCDD'",
|
||
"option-data": [
|
||
{
|
||
"name": "dns-servers",
|
||
"code": 23,
|
||
"space": "dhcp6",
|
||
"csv-format": true,
|
||
"data": "2001:db8:0::1, 2001:db8:2::1"
|
||
}
|
||
]</userinput>
|
||
},
|
||
...
|
||
],
|
||
"subnet6": [
|
||
{
|
||
"subnet": "2001:db8:1::/64",
|
||
"pools": [ { "pool": "2001:db8:1::-2001:db8:1::ffff" } ],
|
||
<userinput>"client-class": "Client_enterprise"</userinput>
|
||
}
|
||
],
|
||
...
|
||
}</screen>
|
||
</para>
|
||
|
||
<para>
|
||
This example shows a configuration using an automatically generated
|
||
"VENDOR_CLASS_" class. The Administrator of the network has
|
||
decided that addresses from range 2001:db8:1::1 to 2001:db8:1::ffff are
|
||
going to be managed by the Dhcp6 server and only clients belonging to the
|
||
eRouter1.0 client class are allowed to use that pool.
|
||
|
||
<screen>
|
||
"Dhcp6": {
|
||
"subnet6": [
|
||
{
|
||
"subnet": "2001:db8:1::/64",
|
||
"pools": [
|
||
{
|
||
"pool": "2001:db8:1::-2001:db8:1::ffff"
|
||
}
|
||
],
|
||
<userinput>"client-class": "VENDOR_CLASS_eRouter1.0"</userinput>
|
||
}
|
||
],
|
||
...
|
||
}
|
||
</screen>
|
||
</para>
|
||
</section>
|
||
|
||
<section id="dhcp6-required-class">
|
||
<title>Required classification</title>
|
||
<para>
|
||
In some cases it is useful to limit the scope of a class to
|
||
a shared-network, subnet or pool. There are two parameters
|
||
which are used to limit the scope of the class by instructing
|
||
the server to perform evaluation of test expressions when
|
||
required.
|
||
</para>
|
||
|
||
<para>
|
||
The first one is the per-class <command>only-if-required</command>
|
||
flag which is false by default. When it is set to
|
||
<command>true</command> the test expression of the class is not
|
||
evaluated at the reception of the incoming packet but later and
|
||
only if the class evaluation is required.
|
||
</para>
|
||
|
||
<para>
|
||
The second is the <command>require-client-classes</command> which
|
||
takes a list of class names and is valid in shared-network,
|
||
subnet and pool scope. Classes in these lists are marked as
|
||
required and evaluated after selection of this specific
|
||
shared-network/subnet/pool and before output option processing.
|
||
</para>
|
||
|
||
<para>
|
||
In this example, a class is assigned to the incoming packet
|
||
when the specified subnet is used.
|
||
|
||
<screen>
|
||
"Dhcp6": {
|
||
"client-classes": [
|
||
{<userinput>
|
||
"name": "Client_foo",
|
||
"test": "member('ALL')",
|
||
"only-if-required": true</userinput>
|
||
},
|
||
...
|
||
],
|
||
"subnet6": [
|
||
{
|
||
"subnet": "2001:db8:1::/64"
|
||
"pools": [
|
||
{
|
||
"pool": "2001:db8:1::-2001:db8:1::ffff"
|
||
}
|
||
],
|
||
<userinput>"require-client-classes": [ "Client_foo" ],</userinput>
|
||
...
|
||
},
|
||
...
|
||
],
|
||
...
|
||
}</screen>
|
||
</para>
|
||
|
||
<para>
|
||
Required evaluation can be used to express complex dependencies,
|
||
for example, subnet membership. It can also be used to reverse the
|
||
precedence: if you set an option-data in a subnet it takes
|
||
precedence over an option-data in a class. When you move the
|
||
option-data to a required class and require it in
|
||
the subnet, a class evaluated earlier may take precedence.
|
||
</para>
|
||
|
||
<para>
|
||
Required evaluation is also available at shared-network and
|
||
pool/pd-pool levels. The order in which required classes are
|
||
considered is: shared-network, subnet and (pd-)pool, i.e.
|
||
the opposite order option-data are processed.
|
||
</para>
|
||
|
||
</section>
|
||
</section>
|
||
|
||
<section xml:id="dhcp6-ddns-config">
|
||
<title>DDNS for DHCPv6</title>
|
||
<para>
|
||
As mentioned earlier, kea-dhcp6 can be configured to generate requests to
|
||
the DHCP-DDNS server (referred to here as "D2") to update
|
||
DNS entries. These requests are known as NameChangeRequests or NCRs.
|
||
Each NCR contains the following information:
|
||
<orderedlist>
|
||
<listitem><para>
|
||
Whether it is a request to add (update) or remove DNS entries
|
||
</para></listitem>
|
||
<listitem><para>
|
||
Whether the change requests forward DNS updates (AAAA records), reverse
|
||
DNS updates (PTR records), or both.
|
||
</para></listitem>
|
||
<listitem><para>
|
||
The FQDN, lease address, and DHCID
|
||
</para></listitem>
|
||
</orderedlist>
|
||
The parameters controlling the generation of NCRs for submission to D2
|
||
are contained in the <command>dhcp-ddns</command> section of the kea-dhcp6
|
||
configuration. The mandatory parameters for the DHCP DDNS configuration
|
||
are <command>enable-updates</command> which is unconditionally
|
||
required, and <command>qualifying-suffix</command> which has no
|
||
default value and is required when <command>enable-updates</command>
|
||
is set to <command>true</command>.
|
||
|
||
The two (disabled and enabled) minimal DHCP DDNS configurations are:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"dhcp-ddns": {
|
||
<userinput>"enable-updates": false</userinput>
|
||
},
|
||
...
|
||
}
|
||
</screen>
|
||
and for example:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"dhcp-ddns": {
|
||
<userinput>"enable-updates": true,
|
||
"qualifying-suffix": "example."</userinput>
|
||
},
|
||
...
|
||
}
|
||
</screen>
|
||
|
||
The default values for the "dhcp-ddns" section are as follows:
|
||
<itemizedlist>
|
||
<listitem><simpara>
|
||
<command>"server-ip": "127.0.0.1"</command>
|
||
</simpara></listitem>
|
||
<listitem><simpara>
|
||
<command>"server-port": 53001</command>
|
||
</simpara></listitem>
|
||
<listitem><simpara>
|
||
<command>"sender-ip": ""</command>
|
||
</simpara></listitem>
|
||
<listitem><simpara>
|
||
<command>"sender-port": 0</command>
|
||
</simpara></listitem>
|
||
<listitem><simpara>
|
||
<command>"max-queue-size": 1024</command>
|
||
</simpara></listitem>
|
||
<listitem><simpara>
|
||
<command>"ncr-protocol": "UDP"</command>
|
||
</simpara></listitem>
|
||
<listitem><simpara>
|
||
<command>"ncr-format": "JSON"</command>
|
||
</simpara></listitem>
|
||
<listitem><simpara>
|
||
<command>"override-no-update": false</command>
|
||
</simpara></listitem>
|
||
<listitem><simpara>
|
||
<command>"override-client-update": false</command>
|
||
</simpara></listitem>
|
||
<listitem><simpara>
|
||
<command>"replace-client-name": "never"</command>
|
||
</simpara></listitem>
|
||
<listitem><simpara>
|
||
<command>"generated-prefix": "myhost"</command>
|
||
</simpara></listitem>
|
||
<listitem><simpara>
|
||
<command>"hostname-char-set": ""</command>
|
||
</simpara></listitem>
|
||
<listitem><simpara>
|
||
<command>"hostname-char-replacement": ""</command>
|
||
</simpara></listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
|
||
<section xml:id="dhcpv6-d2-io-config">
|
||
<title>DHCP-DDNS Server Connectivity</title>
|
||
<para>
|
||
In order for NCRs to reach the D2 server, kea-dhcp6 must be able
|
||
to communicate with it. kea-dhcp6 uses the following configuration
|
||
parameters to control this communication:
|
||
<itemizedlist>
|
||
<listitem><simpara>
|
||
<command>enable-updates</command> - determines whether or not kea-dhcp6 will
|
||
generate NCRs. If missing, this value is assumed to be false hence DDNS updates
|
||
are disabled. To enable DDNS updates set this value to true:
|
||
</simpara></listitem>
|
||
<listitem><simpara>
|
||
<command>server-ip</command> - IP address on which D2 listens for requests. The default is
|
||
the local loopback interface at address 127.0.0.1. You may specify
|
||
either an IPv4 or IPv6 address.
|
||
</simpara></listitem>
|
||
<listitem><simpara>
|
||
<command>server-port</command> - port on which D2 listens for requests. The default value
|
||
is 53001.
|
||
</simpara></listitem>
|
||
<listitem><simpara>
|
||
<command>sender-ip</command> - IP address which kea-dhcp6 should use to send requests to D2.
|
||
The default value is blank which instructs kea-dhcp6 to select a suitable
|
||
address.
|
||
</simpara></listitem>
|
||
<listitem><simpara>
|
||
<command>sender-port</command> - port which kea-dhcp6 should use to send requests to D2. The
|
||
default value of 0 instructs kea-dhcp6 to select a suitable port.
|
||
</simpara></listitem>
|
||
<listitem><simpara>
|
||
<command>max-queue-size</command> - maximum number of requests allowed to queue waiting to
|
||
be sent to D2. This value guards against requests accumulating
|
||
uncontrollably if they are being generated faster than they can be
|
||
delivered. If the number of requests queued for transmission reaches
|
||
this value, DDNS updating will be turned off until the queue backlog has
|
||
been sufficiently reduced. The intent is to allow kea-dhcp6 to
|
||
continue lease operations. The default value is 1024.
|
||
</simpara></listitem>
|
||
<listitem><simpara>
|
||
<command>ncr-protocol</command> - socket protocol use when sending requests to D2. Currently
|
||
only UDP is supported. TCP may be available in an upcoming release.
|
||
</simpara></listitem>
|
||
<listitem><simpara>
|
||
<command>ncr-format</command> - packet format to use when sending requests to D2.
|
||
Currently only JSON format is supported. Other formats may be available
|
||
in future releases.
|
||
</simpara></listitem>
|
||
</itemizedlist>
|
||
By default, kea-dhcp-ddns is assumed to running on the same machine as kea-dhcp6, and
|
||
all of the default values mentioned above should be sufficient.
|
||
If, however, D2 has been configured to listen on a different address or
|
||
port, these values must altered accordingly. For example, if D2 has been
|
||
configured to listen on 2001:db8::5 port 900, the following configuration
|
||
would be required:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"dhcp-ddns": {
|
||
<userinput>"server-ip": "2001:db8::5",
|
||
"server-port": 900</userinput>,
|
||
...
|
||
},
|
||
...
|
||
}
|
||
</screen>
|
||
</para>
|
||
</section>
|
||
<section xml:id="dhcpv6-d2-rules-config">
|
||
<title>When Does kea-dhcp6 Generate a DDNS Request?</title>
|
||
<para>kea-dhcp6 follows the behavior prescribed for DHCP servers in
|
||
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc4704">RFC 4704</link>.
|
||
It is important to keep in mind that kea-dhcp6 provides the initial
|
||
decision making of when and what to update and forwards that
|
||
information to D2 in the form of NCRs. Carrying out the actual
|
||
DNS updates and dealing with such things as conflict resolution
|
||
are within the purview of D2 itself (<xref linkend="dhcp-ddns-server"/>).
|
||
This section describes when kea-dhcp6 will generate NCRs and the
|
||
configuration parameters that can be used to influence this decision.
|
||
It assumes that the <command>enable-updates</command> parameter is true.
|
||
</para>
|
||
<note>
|
||
<para>
|
||
Currently the interface between kea-dhcp6 and D2 only supports requests
|
||
which update DNS entries for a single IP address. If a lease grants
|
||
more than one address, kea-dhcp6 will create the DDNS update request for
|
||
only the first of these addresses. Support for multiple address
|
||
mappings may be provided in a future release.
|
||
</para>
|
||
</note>
|
||
<para>
|
||
In general, kea-dhcp6 will generate DDNS update requests when:
|
||
<orderedlist>
|
||
<listitem><para>
|
||
A new lease is granted in response to a REQUEST
|
||
</para></listitem>
|
||
<listitem><para>
|
||
An existing lease is renewed but the FQDN associated with it has
|
||
changed.
|
||
</para></listitem>
|
||
<listitem><para>
|
||
An existing lease is released in response to a RELEASE
|
||
</para></listitem>
|
||
</orderedlist>
|
||
In the second case, lease renewal, two DDNS requests will be issued: one
|
||
request to remove entries for the previous FQDN and a second request to
|
||
add entries for the new FQDN. In the last case, a lease release, a
|
||
single DDNS request to remove its entries will be made.
|
||
</para>
|
||
<para>
|
||
The decision making involved when granting a new lease the first case) is more
|
||
involved. When a new lease is granted, kea-dhcp6 will generate a DDNS
|
||
update request only if the REQUEST contains the FQDN option (code 39).
|
||
By default kea-dhcp6 will respect the FQDN N and S flags specified by the client
|
||
as shown in the following table:
|
||
</para>
|
||
<table xml:id="dhcp6-fqdn-flag-table">
|
||
<title>Default FQDN Flag Behavior</title>
|
||
<tgroup cols="4" align="left">
|
||
<colspec colname="cflags"/>
|
||
<colspec colname="meaning"/>
|
||
<colspec colname="response"/>
|
||
<colspec colname="sflags"/>
|
||
<thead>
|
||
<row>
|
||
<entry>Client Flags:N-S</entry>
|
||
<entry>Client Intent</entry>
|
||
<entry>Server Response</entry>
|
||
<entry>Server Flags:N-S-O</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
<row>
|
||
<entry>0-0</entry>
|
||
<entry>
|
||
Client wants to do forward updates, server should do reverse updates
|
||
</entry>
|
||
<entry>Server generates reverse-only request</entry>
|
||
<entry>1-0-0</entry>
|
||
</row>
|
||
<row>
|
||
<entry>0-1</entry>
|
||
<entry>Server should do both forward and reverse updates</entry>
|
||
<entry>Server generates request to update both directions</entry>
|
||
<entry>0-1-0</entry>
|
||
</row>
|
||
<row>
|
||
<entry>1-0</entry>
|
||
<entry>Client wants no updates done</entry>
|
||
<entry>Server does not generate a request</entry>
|
||
<entry>1-0-0</entry>
|
||
</row>
|
||
</tbody>
|
||
</tgroup>
|
||
</table>
|
||
<para>
|
||
The first row in the table above represents "client delegation". Here
|
||
the DHCP client states that it intends to do the forward DNS updates and
|
||
the server should do the reverse updates. By default, kea-dhcp6 will honor
|
||
the client's wishes and generate a DDNS request to D2 to update only
|
||
reverse DNS data. The parameter, <command>override-client-update</command>, can be used
|
||
to instruct the server to override client delegation requests. When
|
||
this parameter is true, kea-dhcp6 will disregard requests for client
|
||
delegation and generate a DDNS request to update both forward and
|
||
reverse DNS data. In this case, the N-S-O flags in the server's
|
||
response to the client will be 0-1-1 respectively.
|
||
</para>
|
||
<para>
|
||
(Note that the flag combination N=1, S=1 is prohibited according to
|
||
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc4702">RFC 4702</link>. If such a
|
||
combination is received from the client, the packet will be dropped by kea-dhcp6.)
|
||
</para>
|
||
<para>
|
||
To override client delegation, set the following values in the configuration:
|
||
</para>
|
||
<screen>
|
||
"Dhcp6": {
|
||
"dhcp-ddns": {
|
||
<userinput>"override-client-update": true</userinput>,
|
||
...
|
||
},
|
||
...
|
||
}
|
||
</screen>
|
||
<para>
|
||
The third row in the table above describes the case in which the client
|
||
requests that no DNS updates be done. The parameter, <command>override-no-update</command>,
|
||
can be used to instruct the server to disregard the client's wishes. When
|
||
this parameter is true, kea-dhcp6 will generate DDNS update requests to
|
||
kea-dhcp-ddns even if the client requests no updates be done. The N-S-O
|
||
flags in the server's response to the client will be 0-1-1.
|
||
</para>
|
||
<para>
|
||
To override client delegation, issue the following commands:
|
||
</para>
|
||
<screen>
|
||
"Dhcp6": {
|
||
"dhcp-ddns": {
|
||
<userinput>"override-no-update": true</userinput>,
|
||
...
|
||
},
|
||
...
|
||
}
|
||
</screen>
|
||
</section>
|
||
<section xml:id="dhcpv6-fqdn-name-generation">
|
||
<title>kea-dhcp6 Name Generation for DDNS Update Requests</title>
|
||
<para>Each NameChangeRequest must of course include the fully qualified
|
||
domain name whose DNS entries are to be affected. kea-dhcp6 can be
|
||
configured to supply a portion or all of that name based upon what it
|
||
receives from the client.</para>
|
||
<para>
|
||
The default rules for constructing the FQDN that will be used for DNS
|
||
entries are:
|
||
<orderedlist>
|
||
<listitem><para>
|
||
If the DHCPREQUEST contains the client FQDN option, the candidate name
|
||
is taken from there.
|
||
</para></listitem>
|
||
<listitem><para>
|
||
If the candidate name is a partial (i.e. unqualified) name then add a
|
||
configurable suffix to the name and use the result as the FQDN.
|
||
</para></listitem>
|
||
<listitem><para>
|
||
If the candidate name provided is empty, generate an FQDN using a
|
||
configurable prefix and suffix.
|
||
</para></listitem>
|
||
<listitem><para>
|
||
If the client provided neither option, then no DNS action will be taken.
|
||
</para></listitem>
|
||
</orderedlist>
|
||
These rules can amended by setting the
|
||
<command>replace-client-name</command> parameter which provides the
|
||
following modes of behavior:
|
||
<itemizedlist>
|
||
<listitem><para>
|
||
<command>never</command> - Use the name the client sent. If the client
|
||
sent no name, do not generate one. This is the default mode.
|
||
</para></listitem>
|
||
<listitem><para>
|
||
<command>always</command> - Replace the name the client sent. If the
|
||
client sent no name, generate one for the client.
|
||
</para></listitem>
|
||
<listitem><para>
|
||
<command>when-present</command> - Replace the name the client sent.
|
||
If the client sent no name, do not generate one.
|
||
</para></listitem>
|
||
<listitem><para>
|
||
<command>when-not-present</command> - Use the name the client sent.
|
||
If the client sent no name, generate one for the client.
|
||
</para></listitem>
|
||
</itemizedlist>
|
||
<note>
|
||
Note that formerly, this parameter was a boolean and permitted only values
|
||
of <command>true</command> and <command>false</command>. Boolean values
|
||
have been deprecated and are no longer accepted. If you are currently using
|
||
booleans, you must replace them with the desired mode name. A value of
|
||
<command>true</command> maps to <command>"when-present"</command>, while
|
||
<command>false</command> maps to <command>"never"</command>.
|
||
</note>
|
||
|
||
For example, To instruct kea-dhcp6 to always generate the FQDN for a
|
||
client, set the parameter <command>replace-client-name</command> to
|
||
<command>always</command> as follows:
|
||
</para>
|
||
<screen>
|
||
"Dhcp6": {
|
||
"dhcp-ddns": {
|
||
<userinput>"replace-client-name": "always"</userinput>,
|
||
...
|
||
},
|
||
...
|
||
}
|
||
</screen>
|
||
<para>
|
||
The prefix used in the generation of an FQDN is specified by the
|
||
<command>generated-prefix</command> parameter. The default value is "myhost". To alter
|
||
its value, simply set it to the desired string:
|
||
</para>
|
||
<screen>
|
||
"Dhcp6": {
|
||
"dhcp-ddns": {
|
||
<userinput>"generated-prefix": "another.host"</userinput>,
|
||
...
|
||
},
|
||
...
|
||
}
|
||
</screen>
|
||
<para>
|
||
The suffix used when generating an FQDN or when qualifying a
|
||
partial name is specified by
|
||
the <command>qualifying-suffix</command> parameter. This
|
||
parameter has no default value, thus it is mandatory when
|
||
DDNS updates are enabled.
|
||
To set its value simply set it to the desired string:
|
||
</para>
|
||
<screen>
|
||
"Dhcp6": {
|
||
"dhcp-ddns": {
|
||
<userinput>"qualifying-suffix": "foo.example.org"</userinput>,
|
||
...
|
||
},
|
||
...
|
||
}
|
||
</screen>
|
||
</section>
|
||
<para>
|
||
When qualifying a partial name, kea-dhcp6 will construct a name with the
|
||
format:
|
||
</para>
|
||
<para>
|
||
[candidate-name].[qualifying-suffix].
|
||
</para>
|
||
<para>
|
||
where candidate-name is the partial name supplied in the REQUEST.
|
||
For example, if FQDN domain name value was "some-computer" and
|
||
qualifying-suffix "example.com", the generated FQDN would be:
|
||
</para>
|
||
<para>
|
||
some-computer.example.com.
|
||
</para>
|
||
<para>
|
||
When generating the entire name, kea-dhcp6 will construct name of the
|
||
format:
|
||
</para>
|
||
<para>
|
||
[generated-prefix]-[address-text].[qualifying-suffix].
|
||
</para>
|
||
<para>
|
||
where address-text is simply the lease IP address converted to a
|
||
hyphenated string. For example, if lease address is 3001:1::70E,
|
||
the qualifying suffix "example.com", and the default value is used for
|
||
<command>generated-prefix</command>, the generated FQDN would be:
|
||
</para>
|
||
<para>
|
||
myhost-3001-1--70E.example.com.
|
||
</para>
|
||
<section xml:id="host-name-sanitization">
|
||
<title>Sanitizing Client FQDN Names</title>
|
||
It may be that some of your DHCP clients provide values in the name
|
||
component of the FQDN option (Option code 39), that contain undesirable
|
||
characters. It is possible to configure kea-dhcp5 to sanitize these
|
||
values. The most typical use case would be ensuring that only
|
||
characters that are permitted by RFC 1035 be included:
|
||
A-Z,a-z,0-9, and '-'. This may be accomplished with following two
|
||
parameters:
|
||
<itemizedlist>
|
||
<listitem><simpara>
|
||
<command>hostname-char-set</command> - a regular expression describing
|
||
the invalid character set. This can be any valid, regular expression
|
||
using POSIX extended expression syntax. For example, "[^A-Za-z0-9-]"
|
||
would replace any character other then the letters A through z, digits
|
||
0 through 9, and '-'. An empty string, the default value, disables
|
||
sanitization.
|
||
</simpara></listitem>
|
||
<listitem><simpara>
|
||
<command>hostname-char-replacement</command> - a string of zero or
|
||
more characters with which to replace each invalid character in the
|
||
client value. The default value is an empty string and will cause
|
||
invalid characters to be OMITTED rather than replaced.
|
||
</simpara></listitem>
|
||
</itemizedlist>
|
||
The following configuration, will replace anything other than a
|
||
letter, digit, hyphen, or dot with the letter 'x':
|
||
<screen>
|
||
"Dhcp4": {
|
||
"dhcp-ddns": {
|
||
"hostname-char-set": "[^A-Za-z0-9.-]",
|
||
"hostname-char-replacement": "x",
|
||
...
|
||
},
|
||
...
|
||
}
|
||
</screen>
|
||
Thus, a client supplied value of "myhost-$[123.org" would become
|
||
"myhost-xx123.org". Sanitizing is performed only on the portion of
|
||
the name supplied by the client and it is performed before applying
|
||
a qualifying suffix (if one is defined and needed).
|
||
<note>
|
||
The following are some considerations to keep in mind:
|
||
<para>
|
||
Name sanitizing is meant to catch the more common cases of invalid
|
||
characters through a relatively simple character replacement scheme.
|
||
It is difficult to devise a scheme that works well in all cases and
|
||
should you find you have clients that are using odd, corner cases of
|
||
character combinations that cannot be readily handled with this
|
||
mechanism, you should consider writing a hook that can carry out
|
||
sufficiently complex logic to address your needs.
|
||
</para>
|
||
<para>
|
||
You do not account for dots ins your hostname-char-set expression.
|
||
When scrubbing FQDNs, dots are treated as delimiters and used to
|
||
separate the option value into individual domain labels that are
|
||
scrubbed and then re-assembled.
|
||
</para>
|
||
<para>
|
||
If your clients are sending values that differ only by characters
|
||
considered as invalid by your hostname-char-set, be aware that scrubbing
|
||
them will yield identical values. In such cases, DDNS conflict rules
|
||
will permit only one of them from registering the name.
|
||
</para>
|
||
<para>
|
||
Finally, given the latitude clients have in the values they send, it is
|
||
virtually impossible to guarantee that a combination of these two
|
||
parameters will always yield a name that is valid for use in DNS. For
|
||
example, using an empty value for hostname-char-replacment could yield
|
||
an empty domain label within a name, if that label consists only of
|
||
invalid characters.
|
||
</para>
|
||
</note>
|
||
</section>
|
||
</section>
|
||
|
||
<section xml:id="dhcp6-dhcp4o6-config">
|
||
<title>DHCPv4-over-DHCPv6: DHCPv6 Side</title>
|
||
<para>
|
||
The support of DHCPv4-over-DHCPv6 transport is described in
|
||
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc7341">RFC 7341</link>
|
||
and is implemented using cooperating DHCPv4 and DHCPv6 servers.
|
||
This section is about the configuration of the DHCPv6 side
|
||
(the DHCPv4 side is described in <xref linkend="dhcp4-dhcp4o6-config"/>).
|
||
</para>
|
||
<note>
|
||
DHCPv4-over-DHCPv6 support is experimental and the details of
|
||
the inter-process communication can change: both the
|
||
DHCPv4 and DHCPv6 sides should be running the same version of Kea.
|
||
For instance the support of port relay (RFC 8357) introduced such
|
||
such incompatible change.
|
||
</note>
|
||
<para>
|
||
There is only one specific parameter for the DHCPv6 side:
|
||
<command>dhcp4o6-port</command> which specifies the first of the
|
||
two consecutive ports of the UDP sockets used for the communication
|
||
between the DHCPv6 and DHCPv4 servers (the DHCPv6 server is bound
|
||
to ::1 on <command>port</command> and connected to ::1 on
|
||
<command>port</command> + 1).
|
||
</para>
|
||
<para>
|
||
Two other configuration entries are in general required: unicast traffic
|
||
support (see <xref linkend="dhcp6-unicast"/>) and DHCP 4o6 server
|
||
address option (name "dhcp4o6-server-addr", code 88).
|
||
</para>
|
||
<para>
|
||
The following configuration was used during some tests:
|
||
<screen>
|
||
{
|
||
|
||
# DHCPv6 conf
|
||
"Dhcp6": {
|
||
|
||
"interfaces-config": {
|
||
"interfaces": [ "eno33554984/2001:db8:1:1::1" ]
|
||
},
|
||
|
||
"lease-database": {
|
||
"type": "memfile",
|
||
"name": "leases6"
|
||
},
|
||
|
||
"preferred-lifetime": 3000,
|
||
"valid-lifetime": 4000,
|
||
"renew-timer": 1000,
|
||
"rebind-timer": 2000,
|
||
|
||
"subnet6": [ {
|
||
"subnet": "2001:db8:1:1::/64",
|
||
"interface": "eno33554984",
|
||
"pools": [ { "pool": "2001:db8:1:1::1:0/112" } ]
|
||
} ],
|
||
|
||
<userinput>"dhcp4o6-port": 6767,
|
||
|
||
"option-data": [ {
|
||
"name": "dhcp4o6-server-addr",
|
||
"code": 88,
|
||
"space": "dhcp6",
|
||
"csv-format": true,
|
||
"data": "2001:db8:1:1::1"
|
||
} ]
|
||
</userinput>
|
||
},
|
||
|
||
"Logging": {
|
||
"loggers": [ {
|
||
"name": "kea-dhcp6",
|
||
"output_options": [ {
|
||
"output": "/tmp/kea-dhcp6.log"
|
||
} ],
|
||
"severity": "DEBUG",
|
||
"debuglevel": 0
|
||
} ]
|
||
}
|
||
|
||
}
|
||
</screen>
|
||
</para>
|
||
<note>
|
||
Relayed DHCPv4-QUERY DHCPv6 messages are not yet supported.
|
||
</note>
|
||
</section>
|
||
|
||
<section xml:id="sanity-checks6">
|
||
<title>Sanity checks in DHCPv6</title>
|
||
|
||
<para>
|
||
An important aspect of a well running DHCP system is an assurance that
|
||
the data remains consisent. However, in some cases it may be convenient
|
||
to tolerate certain inconsistent data. For example, a network
|
||
administrator that temporarily removed a subnet from a configuration
|
||
wouldn't want all the leases associated with it disappear from the
|
||
lease database. Kea 1.5 introduced a mechanism to better control sanity
|
||
checks such as this. While currently the scope of configurable sanity
|
||
checks is limited and their default value is set low, it is expected
|
||
that over time the default settings will be set to more aggressive
|
||
values and more parameters of similar nature will be added in the
|
||
future.
|
||
</para>
|
||
|
||
<para>
|
||
Kea now supports a new configuration scope called
|
||
<command>sanity-checks</command>. It currently allows only a
|
||
single parameter called <command>lease-checks</command>. It
|
||
governs what sort of verification is done when a new lease is
|
||
being loaded from a lease file. With the introduction of
|
||
sanity checks mechanism, it is now possible to tell Kea to
|
||
try to correct inconsistent data.
|
||
</para>
|
||
|
||
<para>
|
||
Every subnet has a subnet-id value. This is how Kea internally
|
||
identifies subnets. Each lease has a subnet-id parameter as well, which
|
||
identifies which subnet it belongs to. However, if configuration has
|
||
changed, it is possible that a lease could exist with a subnet-id
|
||
without any subnet that matches it. Also, it may be possible that
|
||
subnets configuration has changed and the subnet-id now belongs to a
|
||
subnet that does not match the lease. Kea corrective algorithm first
|
||
checks if there is a subnet with subnet-id specified by the lease. If
|
||
there is, it checks whether the lease belongs to that subnet. If not,
|
||
depending on the lease-checks setting, the lease is discarded, a
|
||
warning is printed or a new subnet is selected for the lease that
|
||
matches it topologically.
|
||
</para>
|
||
|
||
<para>
|
||
Since delegated prefixes do not have to belong to a subnet in which
|
||
they're offered, there is no way to implement such a mechanism for IPv6
|
||
prefixes. As such, the mechanism works for IPv6 addresses only.
|
||
</para>
|
||
|
||
<para>
|
||
There are five levels which are supported:
|
||
</para>
|
||
|
||
<itemizedlist>
|
||
<listitem>
|
||
<simpara><command>none</command> - do no special checks, accept the
|
||
lease as is</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara><command>warn</command> - if problems are detected, a
|
||
warning will be printed, but the lease data will be accepted
|
||
anyway. This is the default value. If not explicitly configured to
|
||
some other value, this level will be used.</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara><command>fix</command> - If data inconsistency is
|
||
discovered, Kea will try to correct it. If the correction is
|
||
not successful, the data will be inserted anyway.</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara><command>fix-del</command> - If data inconsistency is
|
||
discovered, Kea will try to correct it. If the correction is not
|
||
succesful, the lease will be rejected. This setting ensures the data
|
||
correctness, but some incorrect data may be lost. Use with
|
||
care.</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara><command>del</command> - This is the strictest mode. If any
|
||
inconsistency is detected, the lease is rejected. Use with care.
|
||
</simpara>
|
||
</listitem>
|
||
</itemizedlist>
|
||
|
||
<para>This feature is currently implemented for memfile backend.</para>
|
||
|
||
<para>
|
||
An example configuration that sets this parameter looks as follows:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"sanity-checks": {
|
||
// This parameter determines what to do when a new lease appears in the
|
||
// system (i.e. either is read from disk during memfile startup or is
|
||
// added via lease commands). There are five modes supported:
|
||
// none - do nothing, accept them as is
|
||
// warn - if subnet-id problems are detected, print a warning, but
|
||
// otherwise load the lease as is. This is the default value.
|
||
// fix - attempt to fix the lease by finding appropriate subnet-id value.
|
||
// if there is no suitable subnet, the lease is loaded as is.
|
||
// fix-del - attempt to fix the lease by findind appropriate subnet-id
|
||
// value. If there is no suitable subnet, the lease is deleted.
|
||
// del - delete leases that have incorrect subnet-id values.
|
||
<userinput>"lease-checks": "fix-del"</userinput>
|
||
},
|
||
...
|
||
}</screen>
|
||
</para>
|
||
|
||
</section>
|
||
|
||
</section>
|
||
|
||
<!-- Host reservation is a large topic. There will be many subsections,
|
||
so it should be a section on its own. -->
|
||
<section xml:id="host-reservation-v6">
|
||
<title>Host Reservation in DHCPv6</title>
|
||
|
||
<para>There are many cases where it is useful to provide a configuration on
|
||
a per host basis. The most obvious one is to reserve specific, static IPv6
|
||
address or/and prefix for exclusive use by a given client (host) ‐ returning
|
||
client will get the same address or/and prefix every time and other clients will
|
||
never get that address. Note that there may be cases when the
|
||
new reservation has been made for the client for the address or prefix being
|
||
currently in use by another client. We call this situation a "conflict". The
|
||
conflicts get resolved automatically over time as described in the subsequent
|
||
sections. Once conflict is resolved, the client will keep receiving the reserved
|
||
configuration when it renews.</para>
|
||
|
||
<para>Another example when the host reservations are applicable is when a host
|
||
has specific requirements, e.g. a printer that needs additional DHCP options
|
||
or a cable modem needs specific parameters. Yet another possible use case for
|
||
host reservation is to define unique names for hosts.</para>
|
||
|
||
<para>Hosts reservations are defined as parameters for each subnet. Each host
|
||
can be identified by either DUID or its hardware/MAC address. See
|
||
<xref linkend="mac-in-dhcpv6"/> for details. There is an optional
|
||
<command>reservations</command> array in the
|
||
<command>subnet6</command> structure. Each element in that array
|
||
is a structure, that holds information about a single host. In
|
||
particular, the structure has an identifier that
|
||
uniquely identifies a host. In the DHCPv6 context, such an identifier
|
||
is usually a DUID, but can also be a hardware or MAC address. Also,
|
||
either one or more addresses or prefixes may be specified. It is
|
||
possible to specify a hostname and DHCPv6 options for a given host.</para>
|
||
|
||
<para>The following example shows how to reserve addresses and prefixes
|
||
for specific hosts:
|
||
|
||
<screen>
|
||
"subnet6": [
|
||
{
|
||
"subnet": "2001:db8:1::/48",
|
||
"pools": [ { "pool": "2001:db8:1::/80" } ],
|
||
"pd-pools": [
|
||
{
|
||
"prefix": "2001:db8:1:8000::",
|
||
"prefix-len": 48,
|
||
"delegated-len": 64
|
||
}
|
||
],
|
||
<userinput>"reservations": [
|
||
{
|
||
"duid": "01:02:03:04:05:0A:0B:0C:0D:0E",
|
||
"ip-addresses": [ "2001:db8:1::100" ]
|
||
},
|
||
{
|
||
"hw-address": "00:01:02:03:04:05",
|
||
"ip-addresses": [ "2001:db8:1::101", "2001:db8:1::102" ]
|
||
},
|
||
{
|
||
"duid": "01:02:03:04:05:06:07:08:09:0A",
|
||
"ip-addresses": [ "2001:db8:1::103" ],
|
||
"prefixes": [ "2001:db8:2:abcd::/64" ],
|
||
"hostname": "foo.example.com"
|
||
}
|
||
]</userinput>
|
||
}
|
||
]
|
||
</screen>
|
||
|
||
This example includes reservations for three different clients. The first reservation
|
||
is made for the address 2001:db8:1::100 for a client using DUID
|
||
01:02:03:04:05:0A:0B:0C:0D:0E. The second reservation is made for two addresses
|
||
2001:db8:1::101 and 2001:db8:1::102 for a client using MAC address
|
||
00:01:02:03:04:05. Lastly, address 2001:db8:1::103 and prefix 2001:db8:2:abcd::/64
|
||
are reserved for a client using DUID 01:02:03:04:05:06:07:08:09:0A. The
|
||
last reservation also assigns a hostname to this client.
|
||
</para>
|
||
|
||
<para>Note that DHCPv6 allows for a single client to lease multiple addresses
|
||
and multiple prefixes at the same time. Therefore <command>ip-addresses</command>
|
||
and <command>prefixes</command> are plural and are actually arrays.
|
||
When the client sends multiple IA options (IA_NA or IA_PD), each reserved
|
||
address or prefix is assigned to an individual IA of the appropriate type. If
|
||
the number of IAs of specific type is lower than the number of reservations
|
||
of that type, the number of reserved addresses or prefixes assigned to the
|
||
client is equal to the number of IA_NAs or IA_PDs sent by the client, i.e.
|
||
some reserved addresses or prefixes are not assigned. However,
|
||
they still remain reserved for this client and the server will not assign
|
||
them to any other client. If the number of IAs of specific type sent by the
|
||
client is greater than the number of reserved addresses or prefixes, the
|
||
server will try to assign all reserved addresses or prefixes to the individual
|
||
IAs and dynamically allocate addresses or prefixes to remaining IAs. If the
|
||
server cannot assign a reserved address or prefix because it is in use,
|
||
the server will select the next reserved address or prefix and try to assign it to
|
||
the client. If the server subsequently finds that there are no more reservations
|
||
that can be assigned to the client at the moment, the server will try to
|
||
assign leases dynamically.
|
||
</para>
|
||
|
||
<para>Making a reservation for a mobile host that may visit multiple subnets
|
||
requires a separate host definition in each subnet it is expected to visit.
|
||
It is not allowed to define multiple host definitions with the same hardware
|
||
address in a single subnet. Multiple host definitions with the same hardware
|
||
address are valid if each is in a different subnet. The reservation for a given host
|
||
should include only one identifier, either DUID or hardware address. Defining
|
||
both for the same host is considered a configuration error, but as of 1.1.0,
|
||
it is not rejected.
|
||
</para>
|
||
|
||
<para>Adding host reservation incurs a performance penalty. In principle,
|
||
when a server that does not support host reservation responds to a query,
|
||
it needs to check whether there is a lease for a given address being
|
||
considered for allocation or renewal. The server that also supports host
|
||
reservation, has to perform additional checks: not only if the address is
|
||
currently used (i.e. if there is a lease for it), but also whether the address
|
||
could be used by someone else (i.e. if there is a reservation for it). That
|
||
additional check incurs additional overhead.</para>
|
||
|
||
<section xml:id="reservation6-types">
|
||
<title>Address/Prefix Reservation Types</title>
|
||
|
||
<para>In a typical scenario there is an IPv6 subnet defined with a certain
|
||
part of it dedicated for dynamic address allocation by the DHCPv6
|
||
server. There may be an additional address space defined for prefix
|
||
delegation. Those dynamic parts are referred to as dynamic pools, address
|
||
and prefix pools or simply pools. In principle, the host reservation can
|
||
reserve any address or prefix that belongs to the subnet. The reservations
|
||
that specify an address that belongs to configured pools are called
|
||
"in-pool reservations". In contrast, those that do not
|
||
belong to dynamic pools are called "out-of-pool
|
||
reservations". There is no formal difference in the reservation
|
||
syntax and both reservation types are handled
|
||
uniformly. However, upcoming releases may offer improved performance if
|
||
there are only out-of-pool reservations as the server will be able to skip
|
||
reservation checks when dealing with existing leases. Therefore, system
|
||
administrators are encouraged to use out-of-pool reservations if
|
||
possible.</para>
|
||
|
||
<para>Beginning with Kea 1.5.0, there is now support for global
|
||
host reservations. These are reservations that are specified at the
|
||
global level within the configuration and that do not belong to any
|
||
specific subnet. Kea will still match inbound client packets to a
|
||
subnet as before, but when the subnet's reservation mode is set to
|
||
<command>"global"</command>, Kea will look for host reservations only
|
||
among the global reservations defined. Typcially, such reservations would
|
||
be used to reserve hostnames for clients which may move from one subnet
|
||
to another.
|
||
</para>
|
||
|
||
<note>You can reserve any ip-address or prefix in a global reservation.
|
||
Just keep in mind that Kea will not do any sanity checking on the address
|
||
or prefix and that for Kea 1.5.0, support for global reservations should
|
||
be considered experimental.
|
||
</note>
|
||
|
||
</section>
|
||
|
||
<section xml:id="reservation6-conflict">
|
||
<title>Conflicts in DHCPv6 Reservations</title>
|
||
<para>As reservations and lease information are stored separately,
|
||
conflicts may arise. Consider the following series of events. The server
|
||
has configured the dynamic pool of addresses from the range of 2001:db8::10
|
||
to 2001:db8::20. Host A requests an address and gets 2001:db8::10. Now the
|
||
system administrator decides to reserve address 2001:db8::10 for Host B.
|
||
In general, reserving an address
|
||
that is currently assigned to someone else is not recommended, but there
|
||
are valid use cases where such an operation is warranted.</para>
|
||
|
||
<para>The server now has a conflict to resolve. Let's analyze the
|
||
situation here. If Host B boots up and request an address, the server is
|
||
not able to assign the reserved address 2001:db8::10. A naive approach
|
||
would to be immediately remove the lease for Host A and create a new one
|
||
for Host B. That would not solve the problem, though, because as soon as
|
||
Host B get the address, it will detect that the address is already in use
|
||
by someone else (Host A) and would send a Decline message. Therefore in this
|
||
situation, the server has to temporarily assign a different address from the
|
||
dynamic pool (not matching what has been reserved) to Host B.</para>
|
||
|
||
<para>When Host A renews its address, the server will discover that
|
||
the address being renewed is now reserved for someone else (Host
|
||
B). Therefore the server will remove the lease for 2001:db8::10, select
|
||
a new address and create a new lease for it. It will send two
|
||
addresses in its response: the old address with lifetime set to 0 to
|
||
explicitly indicate that it is no longer valid and the new address with a
|
||
non-zero lifetime. When Host B renews its temporarily assigned
|
||
address, the server will detect that the existing lease does not match
|
||
reservation, so it will release the current address Host B has and will
|
||
create a new lease matching the reservation. Similar as before, the server
|
||
will send two addresses: the temporarily assigned one with zeroed
|
||
lifetimes, and the new one that matches reservation with proper lifetimes
|
||
set.</para>
|
||
|
||
<para>This recovery will succeed, even if other hosts will attempt to get
|
||
the reserved address. Had Host C requested address 2001:db8::10 after
|
||
the reservation was made, the server will propose a different address.</para>
|
||
|
||
<para>This recovery mechanism allows the server to fully recover from a
|
||
case where reservations conflict with existing leases. This procedure
|
||
takes time and will roughly take as long as renew-timer value specified.
|
||
The best way to avoid such recovery is to not define new reservations that
|
||
conflict with existing leases. Another recommendation is to use
|
||
out-of-pool reservations. If the reserved address does not belong to a
|
||
pool, there is no way that other clients could get this address.
|
||
</para>
|
||
|
||
<note>
|
||
<para>The conflict resolution mechanism does not work for global
|
||
reservations. As of Kea 1.5.0, it is generally recommended to not use
|
||
global reservations for addresses or prefixes. If you want to use it
|
||
anyway, you have to manually ensure that the reserved values are not
|
||
in the dynamic pools.</para>
|
||
</note>
|
||
|
||
</section>
|
||
|
||
<section xml:id="reservation6-hostname">
|
||
<title>Reserving a Hostname</title>
|
||
<para>When the reservation for the client includes the <command>hostname</command>,
|
||
the server will assign this hostname to the client and send
|
||
it back in the Client FQDN, if the client sent the FQDN option to the
|
||
server. The reserved hostname always takes precedence over the hostname
|
||
supplied by the client (via the FQDN option) or the autogenerated
|
||
(from the IPv6 address) hostname.</para>
|
||
|
||
<para>The server qualifies the reserved hostname with the value
|
||
of the <command>qualifying-suffix</command> parameter. For example, the
|
||
following subnet configuration:
|
||
<screen>
|
||
"subnet6": [
|
||
{
|
||
"subnet": "2001:db8:1::/48",
|
||
"pools": [ { "pool": "2001:db8:1::/80" } ],
|
||
"reservations": [
|
||
{
|
||
"duid": "01:02:03:04:05:0A:0B:0C:0D:0E",
|
||
"ip-addresses": [ "2001:db8:1::100" ]
|
||
"hostname": "alice-laptop"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"dhcp-ddns": {
|
||
"enable-updates": true,
|
||
"qualifying-suffix": "example.isc.org."
|
||
}
|
||
</screen>
|
||
will result in assigning the "alice-laptop.example.isc.org." hostname to the
|
||
client using the DUID "01:02:03:04:05:0A:0B:0C:0D:0E". If the <command>qualifying-suffix
|
||
</command> is not specified, the default (empty) value will be used, and
|
||
in this case the value specified as a <command>hostname</command> will
|
||
be treated as fully qualified name. Thus, by leaving the
|
||
<command>qualifying-suffix</command> empty it is possible to qualify
|
||
hostnames for the different clients with different domain names:
|
||
<screen>
|
||
"subnet6": [
|
||
{
|
||
"subnet": "2001:db8:1::/48",
|
||
"pools": [ { "pool": "2001:db8:1::/80" } ],
|
||
"reservations": [
|
||
{
|
||
"duid": "01:02:03:04:05:0A:0B:0C:0D:0E",
|
||
"ip-addresses": [ "2001:db8:1::100" ]
|
||
"hostname": "mark-desktop.example.org."
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"dhcp-ddns": {
|
||
"enable-updates": true,
|
||
}
|
||
</screen>
|
||
The above example results in the assignment of the "mark-desktop.example.org." hostname to the
|
||
client using the DUID "01:02:03:04:05:0A:0B:0C:0D:0E".
|
||
</para>
|
||
</section>
|
||
|
||
<section xml:id="reservation6-options">
|
||
<title>Including Specific DHCPv6 Options in Reservations</title>
|
||
<para>Kea 1.1.0 introduced the ability to specify options on a
|
||
per host basis. The options follow the same rules as any other
|
||
options. These can be standard options (see <xref linkend="dhcp6-std-options"/>), custom options (see <xref linkend="dhcp6-custom-options"/>) or vendor specific options
|
||
(see <xref linkend="dhcp6-vendor-opts"/>). The following
|
||
example demonstrates how standard options can be defined.</para>
|
||
|
||
<screen>
|
||
"reservations": [
|
||
{
|
||
"duid": "01:02:03:05:06:07:08",
|
||
"ip-addresses": [ "2001:db8:1::2" ],
|
||
<userinput>"option-data": [
|
||
{
|
||
"option-data": [ {
|
||
"name": "dns-servers",
|
||
"data": "3000:1::234"
|
||
},
|
||
{
|
||
"name": "nis-servers",
|
||
"data": "3000:1::234"
|
||
}
|
||
} ]</userinput>
|
||
} ]</screen>
|
||
|
||
<para>Vendor specific options can be reserved in a similar manner:</para>
|
||
|
||
<screen>
|
||
"reservations": [
|
||
{
|
||
"duid": "aa:bb:cc:dd:ee:ff",
|
||
"ip-addresses": [ "2001:db8::1" ],
|
||
<userinput>"option-data": [
|
||
{
|
||
"name": "vendor-opts",
|
||
"data": 4491
|
||
},
|
||
{
|
||
"name": "tftp-servers",
|
||
"space": "vendor-4491",
|
||
"data": "3000:1::234"
|
||
} ]</userinput>
|
||
} ]</screen>
|
||
|
||
<para>
|
||
Options defined at host level have the highest priority. In other words,
|
||
if there are options defined with the same type on global, subnet, class and
|
||
host level, the host specific values will be used.
|
||
</para>
|
||
|
||
</section>
|
||
|
||
<section xml:id="reservation6-client-classes">
|
||
<title>Reserving Client Classes in DHCPv6</title>
|
||
<para>The <xref linkend="classification-using-expressions"/> explains how
|
||
to configure the server to assign classes to a client based on the content
|
||
of the options that this client sends to the server. Host reservations
|
||
mechanisms also allow for the static assignment of classes to clients.
|
||
The definitions of these classes are placed in the Kea
|
||
configuration. The following configuration snippet shows how to specify
|
||
that the client belongs to classes <command>reserved-class1</command>
|
||
and <command>reserved-class2</command>. Those classes are associated with
|
||
specific options being sent to the clients which belong to them.
|
||
</para>
|
||
<screen>
|
||
{
|
||
"client-classes": [
|
||
{
|
||
"name": "reserved-class1",
|
||
"option-data": [
|
||
{
|
||
"name": "dns-servers",
|
||
"data": "2001:db8:1::50"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"name": "reserved-class2",
|
||
"option-data": [
|
||
{
|
||
"name": "nis-servers",
|
||
"data": "2001:db8:1::100"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"subnet6": [
|
||
{ "pools": [ { "pool": "2001:db8:1::/64" } ],
|
||
"subnet": "2001:db8:1::/48",
|
||
"reservations": [
|
||
{
|
||
"duid": "01:02:03:04:05:06:07:08",
|
||
<userinput>
|
||
"client-classes": [ "reserved-class1", "reserved-class2" ]
|
||
</userinput>
|
||
} ]
|
||
} ]
|
||
}
|
||
|
||
</screen>
|
||
<para>Static class assignments, as shown above, can be used in conjunction
|
||
with classification using expressions. The "KNOWN" or "UNKNOWN" builtin
|
||
class is added to the packet and any class depending on it directly or
|
||
indirectly and not only-if-required is evaluated.
|
||
</para>
|
||
|
||
<note>
|
||
<para>If you want to force the evaluation of a class expression after
|
||
the host reservation lookup, for instance because of a dependency on
|
||
"reserved-class1" from the previous example, you should add a
|
||
"member('KNOWN')" in the expression.</para>
|
||
</note>
|
||
|
||
</section>
|
||
|
||
<section id="reservations6-mysql-pgsql-cql">
|
||
<title>Storing Host Reservations in MySQL, PostgreSQL or Cassandra</title>
|
||
|
||
<para>
|
||
It is possible to store host reservations in MySQL, PostgreSQL or Cassandra. See
|
||
<xref linkend="hosts6-storage" /> for information on how to configure Kea to use
|
||
reservations stored in MySQL, PostgreSQL or Cassandra. Kea provides dedicated hook for
|
||
managing reservations in a database, section <xref linkend="host-cmds" /> provide
|
||
detailed information. The Kea wiki <uri
|
||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||
xlink:href="https://gitlab.isc.org/isc-projects/kea/wikis/designs/commands#23-host-reservations-hr-management">https://gitlab.isc.org/isc-projects/kea/wikis/designs/commands#23-host-reservations-hr-management</uri>
|
||
provides some examples how to conduct some common operations
|
||
on host reservations.
|
||
</para>
|
||
|
||
<note><simpara>In Kea maximum length of an option specified per host is
|
||
arbitrarily set to 4096 bytes.</simpara></note>
|
||
</section>
|
||
|
||
<section xml:id="reservations6-tuning">
|
||
<title>Fine Tuning DHCPv6 Host Reservation</title>
|
||
|
||
<para>The host reservation capability introduces additional restrictions for the
|
||
allocation engine (the component of Kea that selects an address for a client)
|
||
during lease selection and renewal. In particular, three
|
||
major checks are necessary. First, when selecting a new lease, it is not
|
||
sufficient for a candidate lease to not be used by another DHCP client. It
|
||
also must not be reserved for another client. Second, when renewing a lease,
|
||
additional check must be performed whether the address being renewed is not
|
||
reserved for another client. Finally, when a host renews an address or a
|
||
prefix, the server has to check whether there is a reservation for this host,
|
||
so the existing (dynamically allocated) address should be revoked and the
|
||
reserved one be used instead.</para>
|
||
<para>Some of those checks may be unnecessary in certain deployments and not
|
||
performing them may improve performance. The Kea server provides the
|
||
<command>reservation-mode</command> configuration parameter to select the
|
||
types of reservations allowed for the particular subnet. Each reservation
|
||
type has different constraints for the checks to be performed by the
|
||
server when allocating or renewing a lease for the client.
|
||
Allowed values are:
|
||
|
||
<itemizedlist>
|
||
<listitem><simpara> <command>all</command> - enables both in-pool
|
||
and out-of-pool host reservation types. This is the default value. This
|
||
setting is the safest and the most flexible. As all checks are conducted,
|
||
it is also the slowest. This does not check against global reservations.
|
||
</simpara></listitem>
|
||
|
||
<listitem><simpara> <command>out-of-pool</command> - allows only out of
|
||
pool host reservations. With this setting in place, the server may assume
|
||
that all host reservations are for addresses that do not belong to the
|
||
dynamic pool. Therefore it can skip the reservation checks when dealing
|
||
with in-pool addresses, thus improving performance. Do not use this mode
|
||
if any of your reservations use in-pool address. Caution is advised when
|
||
using this setting. Kea does not sanity check the reservations against
|
||
<command>reservation-mode</command> and misconfiguration may cause
|
||
problems.
|
||
</simpara></listitem>
|
||
|
||
<listitem><simpara> <command>global</command> - allows only global
|
||
host reservations. With this setting in place, the server searches for
|
||
reservations for a client only among the defined global reservations.
|
||
If an address is specified, the server will skip the reservation checks
|
||
done when dealing in other modes, thus improving performance.
|
||
Caution is advised when using this setting: Kea does not sanity check
|
||
the reservations when <command>global</command> and
|
||
misconfiguration may cause problems.
|
||
</simpara></listitem>
|
||
|
||
<listitem><simpara>
|
||
<command>disabled</command> - host reservation support is disabled. As there
|
||
are no reservations, the server will skip all checks. Any reservations defined
|
||
will be completely ignored. As the checks are skipped, the server may
|
||
operate faster in this mode.
|
||
</simpara></listitem>
|
||
|
||
</itemizedlist>
|
||
The parameter can be specified at global, subnet and shared network
|
||
levels.
|
||
</para>
|
||
|
||
<para>
|
||
An example configuration that disables reservation looks like follows:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"subnet6": [
|
||
{
|
||
"subnet": "2001:db8:1::/64",
|
||
<userinput>"reservation-mode": "disabled"</userinput>,
|
||
...
|
||
}
|
||
]
|
||
}
|
||
</screen>
|
||
</para>
|
||
|
||
<para>
|
||
An example configuration using global reservations is shown below:
|
||
<screen>
|
||
"Dhcp6": {
|
||
|
||
<userinput>
|
||
"reservation-mode": "global",
|
||
"reservations": [
|
||
{
|
||
"duid": "00:03:00:01:11:22:33:44:55:66",
|
||
"hostname": "host-one"
|
||
},
|
||
{
|
||
"duid": "00:03:00:01:99:88:77:66:55:44",
|
||
"hostname": "host-two"
|
||
}
|
||
],
|
||
</userinput>
|
||
"subnet6": [
|
||
{
|
||
"subnet": "2001:db8:1::/64",
|
||
...
|
||
}
|
||
]
|
||
}
|
||
</screen>
|
||
For more details regarding global reservations, see
|
||
<xref linkend="global-reservations6"/>.
|
||
</para>
|
||
|
||
<para>Another aspect of the host reservations are different types of
|
||
identifiers. Kea 1.1.0 supports two types of identifiers
|
||
in DHCPv6: hw-address and duid, but more identifier types
|
||
are likely to be added in the future. This is beneficial from a
|
||
usability perspective. However, there is a drawback. For each incoming
|
||
packet Kea has to to extract each identifier type and then query the
|
||
database to see if there is a reservation done by this particular
|
||
identifier. If nothing is found, the next identifier is extracted and next
|
||
query is issued. This process continues until either a reservation is
|
||
found or all identifier types have been checked. Over time with an increasing
|
||
number of supported identifier types, Kea would become slower and
|
||
slower.</para>
|
||
|
||
<para>To address this problem, a parameter called
|
||
<command>host-reservation-identifiers</command> has been introduced. It
|
||
takes a list of identifier types as a parameter. Kea will check only those
|
||
identifier types enumerated in host-reservation-identifiers. From a
|
||
performance perspective the number of identifier types should be kept to
|
||
minimum, ideally limited to one. If your deployment uses several
|
||
reservation types, please enumerate them from most to least frequently
|
||
used as this increases the chances of Kea finding the reservation using the
|
||
fewest number of queries. An example of host reservation identifiers looks
|
||
as follows:
|
||
|
||
<screen>
|
||
<userinput>"host-reservation-identifiers": [ "duid", "hw-address" ],</userinput>
|
||
"subnet6": [
|
||
{
|
||
"subnet": "2001:db8:1::/64",
|
||
...
|
||
}
|
||
]</screen>
|
||
</para>
|
||
|
||
<para>
|
||
If not specified, the default value is:
|
||
<screen>
|
||
<userinput>"host-reservation-identifiers": [ "hw-address", "duid" ]</userinput>
|
||
</screen>
|
||
|
||
</para>
|
||
|
||
</section>
|
||
<section id="global-reservations6">
|
||
<title>Global reservations in DHCPv6</title>
|
||
|
||
<para>In some deployments, such as mobile, clients can roam within the
|
||
network and there is a desire to specify certain parameters regardless of
|
||
the client's current location. To facilitate such a need, a global
|
||
reservation mechanism has been implemented. The idea behind it is that
|
||
regular host reservations are tied to specific subnets, by using specific
|
||
subnet-id. Kea 1.5.0 introduced a new capability to specify global
|
||
reservation that can be used in every subnet that has global reservations
|
||
enabled.</para>
|
||
|
||
<para>This feature can be used to assign certain parameters, such as
|
||
hostname or other dedicated, host-specific options. It can also be used to
|
||
assign addresses or prefixes. However, global reservations that assign
|
||
either of these bypass the whole topology determination provided by DHCP
|
||
logic implemented in Kea. It is very easy to misuse this feature and get
|
||
configuration that is inconsistent. To give a specific example, imagine a
|
||
global reservation for an address 2001:db8:1111::1 and two subnets
|
||
2001:db8:1111::/48 and 2001:db8:ffff::/48. If global reservations are used
|
||
in both subnets and a device matching global host reservations visits part
|
||
of the network that is covered by 2001:db8:ffff::/48, it will get an IP
|
||
address 2001:db8:ffff::1, which will be outside of the prefix announced
|
||
by its local router using Router Advertisements. Such a configuration
|
||
would be unsuable or at the very least ridden with issues, such as the
|
||
downlink traffic not reaching the device.</para>
|
||
|
||
<para>
|
||
To use global host reservations a configuration similar to the following
|
||
can be used:
|
||
|
||
<screen>
|
||
"Dhcp6:" {
|
||
// This specifies global reservations. They will apply to all subnets that
|
||
// have global reservations enabled.
|
||
<userinput>
|
||
"reservations": [
|
||
{
|
||
"hw-address": "aa:bb:cc:dd:ee:ff",
|
||
"hostname": "hw-host-dynamic"
|
||
},
|
||
{
|
||
"hw-address": "01:02:03:04:05:06",
|
||
"hostname": "hw-host-fixed",
|
||
|
||
// Use of IP address is global reservation is risky. If used outside of
|
||
// matching subnet, such as 3001::/64, it will result in a broken
|
||
// configuration being handled to the client.
|
||
"ip-address": "2001:db8:ff::77"
|
||
},
|
||
{
|
||
"duid": "01:02:03:04:05",
|
||
"hostname": "duid-host"
|
||
}
|
||
]</userinput>,
|
||
"valid-lifetime": 600,
|
||
"subnet4": [ {
|
||
"subnet": "2001:db8:1::/64",
|
||
<userinput>"reservation-mode": "global",</userinput>
|
||
"pools": [ { "pool": "2001:db8:1::-2001:db8:1::100" } ]
|
||
} ]
|
||
}
|
||
</screen>
|
||
</para>
|
||
|
||
<para>When using database backends, the global host reservations are
|
||
distinguished from regular reservations by using subnet-id value of
|
||
zero.</para>
|
||
<!-- see CfgHostOperations::createConfig6() in
|
||
src/lib/dhcpsrv/cfg_host_operations.cc -->
|
||
|
||
</section>
|
||
|
||
<!-- @todo: add support for per IA reservation (that specifies IAID in
|
||
the ip-addresses and prefixes) -->
|
||
</section>
|
||
<!-- end of host reservations section -->
|
||
|
||
<!-- shared networks starts here -->
|
||
<section id="shared-network6">
|
||
<title>Shared networks in DHCPv6</title>
|
||
|
||
<para>DHCP servers use subnet information in two ways. First, it is used
|
||
to determine the point of attachment, or simply put, where the client is
|
||
connected to the network. Second, the subnet information is used to group
|
||
information pertaining to specific location in the network. This approach
|
||
works well in general case, but the are scenarios where the boundaries are
|
||
blurred. Sometimes it is useful to have more than one logical IP subnet
|
||
being deployed on the same physical link. The need to understand
|
||
that two or more subnets are used on the same link requires additional logic
|
||
in the DHCP server. This capability has been added in Kea 1.3.0. It is
|
||
called "shared networks" in Kea and ISC DHCP projects. It is sometimes also
|
||
called "shared subnets". In Microsoft's nomenclature it is called "multinet".
|
||
</para>
|
||
|
||
<para>There are many use cases where the feature is useful. The most common
|
||
example in the IPv4 case is when the server is running out of available
|
||
addresses in a subnet. This is less common in IPv6, but the shared networks
|
||
are still useful in IPv6. One of the use cases is an exhaustion of IPv6
|
||
delegated prefixes within a subnet. Another IPv6 specific example
|
||
is an experiment with addressing scheme. With the advent of IPv6 deployment
|
||
and vast address space, many organizations split the address space into
|
||
subnets, then deploy it and after a while discover that they want to split it
|
||
differently. In the transition period they want both old and new addressing
|
||
to be available. Thus the need for more than one subnet on the same physical
|
||
link.</para>
|
||
|
||
<para>Finally, the case of cable networks is directly applicable in
|
||
IPv6. There are two types of devices in cable networks: cable modems and the
|
||
end user devices behind them. It is a common practice to use different
|
||
subnet for cable modems to prevent users from tinkering with their cable
|
||
modems. In this case, the distinction is based on the type of device, rather
|
||
than coming out of running out address space.</para>
|
||
|
||
<para>A client connected to a shared network may be assigned a lease (address
|
||
or prefix) from any of the pools defined within the subnets belonging to the
|
||
shared network. Internally, the server selects one of the subnets belonging to the
|
||
shared network and tries to allocate a lease from this subnet. If the
|
||
server is unable to allocate a lease from the selected subnet (e.g. due
|
||
to pools exhaustion) it will use another subnet from the same shared
|
||
network and try to allocate a lease from this subnet etc. Therefore, in the
|
||
typical case, the server will allocate all leases available in a given
|
||
subnet before it starts allocating leases from other subnets belonging to
|
||
the same shared network. However, in certain situations the client can be
|
||
allocated a lease from the other subnets before the pools in the first
|
||
subnet get exhausted, e.g. when the client provides a hint that belongs
|
||
to another subnet or the client has reservations in a different than
|
||
default subnet.
|
||
</para>
|
||
|
||
<note>
|
||
<para>It is strongly discouraged for the Kea deployments to assume that the
|
||
server doesn't allocate leases from other subnets until it uses all
|
||
the leases from the first subnet in the shared network. Apart from the
|
||
fact that hints, host reservations and client classification affect subnet
|
||
selection, it is also foreseen that we will enhance allocation strategies
|
||
for shared networks in the future versions of Kea, so as the selection
|
||
of subnets within a shared network is equally probable (unpredictable).</para>
|
||
</note>
|
||
|
||
<para>In order to define a shared network an additional configuration scope
|
||
is introduced:
|
||
<screen>
|
||
{
|
||
"Dhcp6": {
|
||
<userinput>"shared-networks": [
|
||
{
|
||
// Name of the shared network. It may be an arbitrary string
|
||
// and it must be unique among all shared networks.
|
||
"name": "ipv6-lab-1",
|
||
|
||
// Subnet selector can be specifed on the shared network level.
|
||
// Subnets from this shared network will be selected for clients
|
||
// communicating via relay agent having the specified IP address.
|
||
"relay": {
|
||
"ip-addresses": [ "2001:db8:2:34::1" ]
|
||
},
|
||
|
||
// This starts a list of subnets in this shared network.
|
||
// There are two subnets in this example.
|
||
"subnet6": [
|
||
{
|
||
"subnet": "2001:db8::/48",
|
||
"pools": [ { "pool": "2001:db8::1 - 2001:db8::ffff" } ]
|
||
},
|
||
{
|
||
"subnet": "3ffe:ffe::/64",
|
||
"pools": [ { "pool": "3ffe:ffe::/64" } ]
|
||
}
|
||
]
|
||
} ]</userinput>, // end of shared-networks
|
||
|
||
// It is likely that in your network you'll have a mix of regular,
|
||
// "plain" subnets and shared networks. It is perfectly valid to mix
|
||
// them in the same config file.
|
||
//
|
||
// This is regular subnet. It's not part of any shared-network.
|
||
"subnet6": [
|
||
{
|
||
"subnet": "2001:db9::/48",
|
||
"pools": [ { "pool": "2001:db9::/64" } ],
|
||
"relay": {
|
||
"ip-addresses": [ "2001:db8:1:2::1" ]
|
||
}
|
||
}
|
||
]
|
||
|
||
} // end of Dhcp6
|
||
}
|
||
</screen>
|
||
</para>
|
||
<para>As you see in the example, it is possible to mix shared and regular
|
||
("plain") subnets. Each shared network must have a unique name. This is a
|
||
similar concept to ID for subnets, but it offers more flexibility. This is used
|
||
for logging, but also internally for identifying shared networks.</para>
|
||
|
||
<para>In principle it makes sense to define only shared networks that
|
||
consist of two or more subnets. However, for testing purposes it is allowed
|
||
to define a shared network with just one subnet or even an empty one. This
|
||
is not a recommended practice in production networks, as the shared network
|
||
logic requires additional processing and thus lowers server's performance.
|
||
To avoid unnecessary performance degradation the shared subnets should only
|
||
be defined when required by the deployment.
|
||
</para>
|
||
|
||
<para>Shared networks provide an ability to specify many parameters in
|
||
the shared network scope that will apply to all subnets within it. If
|
||
necessary, you can specify a parameter in the shared network scope and then
|
||
override its value on the subnet scope. For example:
|
||
<screen>
|
||
"shared-networks": [
|
||
{
|
||
"name": "lab-network3",
|
||
"relay": {
|
||
"ip-addresses": [ "2001:db8:2:34::1" ]
|
||
},
|
||
|
||
// This applies to all subnets in this shared network, unless
|
||
// values are overridden on subnet scope.
|
||
<userinput>"valid-lifetime": 600</userinput>,
|
||
|
||
// This option is made available to all subnets in this shared
|
||
// network.
|
||
<userinput>"option-data": [ {
|
||
"name": "dns-servers",
|
||
"data": "2001:db8::8888"
|
||
} ]</userinput>,
|
||
|
||
"subnet6": [
|
||
{
|
||
"subnet": "2001:db8:1::/48",
|
||
"pools": [ { "pool": "2001:db8:1::1 - 2001:db8:1::ffff" } ],
|
||
|
||
// This particular subnet uses different values.
|
||
<userinput>"valid-lifetime": 1200,
|
||
"option-data": [
|
||
{
|
||
"name": "dns-servers",
|
||
"data": "2001:db8::1:2"
|
||
},
|
||
{
|
||
"name": "unicast",
|
||
"data": "2001:abcd::1"
|
||
} ]</userinput>
|
||
},
|
||
{
|
||
"subnet": "2001:db8:2::/48",
|
||
"pools": [ { "pool": "2001:db8:2::1 - 2001:db8:2::ffff" } ],
|
||
|
||
// This subnet does not specify its own valid-lifetime value,
|
||
// so it is inherited from shared network scope.
|
||
<userinput>"option-data": [
|
||
{
|
||
"name": "dns-servers",
|
||
"data": "2001:db8:cafe::1"
|
||
} ]</userinput>
|
||
}
|
||
],
|
||
} ]</screen>
|
||
|
||
In this example, there is a dns-servers option defined that is available to
|
||
clients in both subnets in this shared network. Also, a valid lifetime is
|
||
set to 10 minutes (600s). However, the first subnet overrides some of the values
|
||
(valid lifetime is 20 minutes, different IP address for dns-servers), but
|
||
also adds its own option (unicast address). Assuming a client asking for a
|
||
server unicast and dns servers options is assigned a lease from this subnet,
|
||
he will get a lease for 20 minutes and dns-servers and be allowed to use
|
||
server unicast at address 2001:abcd::1. If the same client is assigned to
|
||
the second subnet, he will get a 10 minutes long lease, dns-servers value of
|
||
2001:db8:cafe::1 and no server unicast.
|
||
</para>
|
||
|
||
<para>Some parameters must be the same in all subnets in the same shared
|
||
network. This restriction applies to <command>interface</command> and
|
||
<command>rapid-commit</command> settings. The most convenient way is to
|
||
define them on shared network scope, but you may specify them for each
|
||
subnet. However, care should be taken for each subnet to have the same
|
||
value.</para>
|
||
|
||
<section>
|
||
<title>Local and relayed traffic in shared networks</title>
|
||
|
||
<para>It is possible to specify interface name in the shared network scope to
|
||
tell the server that this specific shared network is reachable directly (not
|
||
via relays) using local network interface. It is sufficient to specify
|
||
it once at the shared network level. As all subnets in a shared network are
|
||
expected to be used on the same physical link, it is a configuration error
|
||
to attempt to make a shared network out of subnets that are reachable over
|
||
different interfaces. It is allowed to specify interface parameter on each
|
||
subnet, although its value must be the same for each subnet. Thus it's
|
||
usually more convenient to specify it once at the shared network level.
|
||
<screen>
|
||
"shared-networks": [
|
||
{
|
||
"name": "office-floor-2",
|
||
|
||
// This tells Kea that the whole shared networks is reachable over
|
||
// local interface. This applies to all subnets in this network.
|
||
<userinput>"interface": "eth0"</userinput>,
|
||
|
||
"subnet6": [
|
||
{
|
||
"subnet": "2001:db8::/64",
|
||
"pools": [ { "pool": "2001:db8::1 - 2001:db8::ffff" } ],
|
||
<userinput>"interface": "eth0"</userinput>
|
||
},
|
||
{
|
||
"subnet": "3ffe:abcd::/64",
|
||
"pools": [ { "pool": "3ffe:abcd::1 - 3ffe:abcd::ffff" } ]
|
||
|
||
// Specifying a different interface name is configuration
|
||
// error:
|
||
// "interface": "eth1"
|
||
}
|
||
],
|
||
} ]
|
||
</screen>
|
||
</para>
|
||
|
||
<para>Somewhat similar to interface names, also relay IP addresses can be
|
||
specified for the whole shared network. However, depending on your relay
|
||
configuration, it may use different IP addresses depending on which subnet
|
||
is being used. Thus there is no requirement to use the same IP relay address
|
||
for each subnet. Here's an example:
|
||
|
||
<screen>
|
||
"shared-networks": [
|
||
{
|
||
"name": "kakapo",
|
||
<userinput>"relay": {
|
||
"ip-addresses": [ "2001:db8::abcd" ]
|
||
}</userinput>,
|
||
"subnet6": [
|
||
{
|
||
"subnet": "2001:db8::/64",
|
||
<userinput>"relay": {
|
||
"ip-addresses": [ "2001:db8::1234" ]
|
||
}</userinput>,
|
||
"pools": [ { "pool": "2001:db8::1 - 2001:db8::ffff" } ]
|
||
},
|
||
{
|
||
"subnet": "3ffe:abcd::/64",
|
||
"pools": [ { "pool": "3ffe:abcd::1 - 3ffe:abcd::ffff" } ],
|
||
<userinput>"relay": {
|
||
"ip-addresses": [ "3ffe:abcd::cafe" ]
|
||
}</userinput>
|
||
}
|
||
]
|
||
}
|
||
]</screen>
|
||
In this particular case the relay IP address specified at network level doesn't
|
||
have much sense, as it is overridden in both subnets, but it was left there
|
||
as an example of how one could be defined at network level. Note that the
|
||
relay agent IP address typically belongs to the subnet it relays packets from,
|
||
but this is not a strict requirement. Therefore Kea accepts any value here
|
||
as long as it is valid IPv6 address.</para>
|
||
|
||
</section>
|
||
<section>
|
||
<title>Client classification in shared networks</title>
|
||
|
||
<para>Sometimes it is desired to segregate clients into specific subnets
|
||
based on some properties. This mechanism is called client classification
|
||
and is described in <xref linkend="classify"/>. Client classification
|
||
can be applied to subnets belonging to shared networks in the same way
|
||
as it is used for subnets specified outside of shared networks.
|
||
It is important to understand how the server selects subnets for
|
||
the clients when client classification is in use, to assure that the
|
||
desired subnet is selected for a given client type.</para>
|
||
|
||
<para>If a subnet is associated with a class, only the clients
|
||
belonging to this class can use this subnet. If there are no
|
||
classes specified for a subnet, any client connected to a given shared
|
||
network can use this subnet. A common mistake is to assume that the
|
||
subnet including a client class is preferred over subnets without
|
||
client classes. Consider the following example:
|
||
|
||
<screen>
|
||
{
|
||
"client-classes": [
|
||
{
|
||
"name": "b-devices",
|
||
"test": "option[1234].hex == 0x0002"
|
||
}
|
||
],
|
||
"shared-networks": [
|
||
{
|
||
"name": "galah",
|
||
"relay": {
|
||
"ip-address": [ "2001:db8:2:34::1" ]
|
||
},
|
||
"subnet6": [
|
||
{
|
||
"subnet": "2001:db8:1::/64",
|
||
"pools": [ { "pool": "2001:db8:1::20 - 2001:db8:1::ff" } ],
|
||
},
|
||
{
|
||
"subnet": "2001:db8:3::/64",
|
||
"pools": [ { "pool": "2001:db8:3::20 - 2001:db8:3::ff" } ],
|
||
<userinput>"client-class": "b-devices"</userinput>
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
</screen>
|
||
|
||
If the client belongs to "b-devices" class (because it includes option
|
||
1234 with a value of 0x0002) it doesn't guarantee that the subnet 2001:db8:3::/64
|
||
will be used (or preferred) for this client. The server can use any of
|
||
the two subnets because the subnet 2001:db8:1::/64 is also allowed for
|
||
this client. The client classification used in this case should be pereceived
|
||
as a way to restrict access to certain subnets, rather than a way to express
|
||
subnet preference. For example, if the client doesn't belong to the
|
||
"b-devices" class it may only use the subnet 2001:db8:1::/64 and will
|
||
never use the subnet 2001:db8:3::/64.
|
||
</para>
|
||
|
||
<para>A typical use case for client classification is in the cable network,
|
||
where cable modems should use one subnet and other devices should use
|
||
another subnet within the same shared network. In this case it is required
|
||
to apply classification on all subnets. The following example defines two
|
||
classes of devices. The subnet selection is made based on option 1234 values.
|
||
<screen>
|
||
{
|
||
"client-classes": [
|
||
{
|
||
|
||
"name": "a-devices",
|
||
"test": "option[1234].hex == 0x0001"
|
||
},
|
||
{
|
||
"name": "b-devices",
|
||
"test": "option[1234].hex == 0x0002"
|
||
}
|
||
],
|
||
"shared-networks": [
|
||
{
|
||
"name": "galah",
|
||
"relay": {
|
||
"ip-addresses": [ "2001:db8:2:34::1" ]
|
||
},
|
||
"subnet6": [
|
||
{
|
||
"subnet": "2001:db8:1::/64",
|
||
"pools": [ { "pool": "2001:db8:1::20 - 2001:db8:1::ff" } ],
|
||
<userinput>"client-class": "a-devices"</userinput>
|
||
},
|
||
{
|
||
"subnet": "2001:db8:3::/64",
|
||
"pools": [ { "pool": "2001:db8:3::20 - 2001:db8:3::ff" } ],
|
||
<userinput>"client-class": "b-devices"</userinput>
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
</screen>
|
||
In this example each class has its own restriction. Only clients that belong to
|
||
class a-devices will be able to use subnet 2001:db8:1::/64 and only clients
|
||
belonging to b-devices will be able to use subnet 2001:db8:3::/64. Care should
|
||
be taken to not define too restrictive classification rules, as clients that are
|
||
unable to use any subnets will be refused service. Although, this may be
|
||
desired outcome if one desires to service only clients of known properties
|
||
(e.g. only VoIP phones allowed on a given link).</para>
|
||
|
||
<para>
|
||
Note that it is possible to achieve similar effect as presented in this
|
||
section without the use of shared networks. If the subnets are placed in
|
||
the global subnets scope, rather than in the shared network, the server
|
||
will still use classification rules to pick the right subnet for a given
|
||
class of devices. The major benefit of placing subnets within the
|
||
shared network is that common parameters for the logically grouped
|
||
subnets can be specified once, in the shared network scope, e.g.
|
||
"interface" or "relay" parameter. All subnets belonging to this shared
|
||
network will inherit those parameters.
|
||
</para>
|
||
|
||
</section>
|
||
|
||
<section>
|
||
<title>Host reservations in shared networks</title>
|
||
|
||
<para>
|
||
Subnets being part of a shared network allow host reservations, similar to
|
||
regular subnets:
|
||
<screen>
|
||
{
|
||
"shared-networks": [
|
||
{
|
||
"name": "frog",
|
||
"relay": {
|
||
"ip-addresses": [ "2001:db8:2:34::1" ]
|
||
},
|
||
"subnet6": [
|
||
{
|
||
"subnet": "2001:db8:1::/64",
|
||
"id": 100,
|
||
"pools": [ { "2001:db8:1::1 - 2001:db8:1::64" } ],
|
||
<userinput>"reservations": [
|
||
{
|
||
"duid": "00:03:00:01:11:22:33:44:55:66",
|
||
"ip-addresses": [ "2001:db8:1::28" ]
|
||
}
|
||
]</userinput>
|
||
},
|
||
{
|
||
"subnet": "2001:db8:3::/64",
|
||
"id": 101,
|
||
"pools": [ { "pool": "2001:db8:3::1 - 2001:db8:3::64" } ],
|
||
<userinput>"reservations": [
|
||
{
|
||
"duid": "00:03:00:01:aa:bb:cc:dd:ee:ff",
|
||
"ip-addresses": [ "2001:db8:2::28" ]
|
||
}
|
||
]</userinput>
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
</screen>
|
||
</para>
|
||
<para>It is worth noting that Kea conducts additional checks when processing a
|
||
packet if shared networks are defined. First, instead of simply checking if
|
||
there's a reservation for a given client in his initially selected subnet, it
|
||
goes through all subnets in a shared network looking for a reservation. This is
|
||
one of the reasons why defining a shared network may impact performance. If
|
||
there is a reservation for a client in any subnet, that particular subnet will
|
||
be picked for the client. Although it's technically not an error, it is
|
||
considered a bad practice to define reservations for the same host in multiple
|
||
subnets belonging to the same shared network.</para>
|
||
|
||
<para>While not strictly mandatory, it is strongly recommended to use explicit
|
||
"id" values for subnets if you plan to use database storage for host
|
||
reservations. If ID is not specified, the values for it be autogenerated,
|
||
i.e. it will assign increasing integer values starting from 1. Thus, the
|
||
autogenerated IDs are not stable across configuration changes.
|
||
</para>
|
||
</section>
|
||
|
||
</section>
|
||
|
||
<!-- end of shared networks -->
|
||
|
||
<section xml:id="dhcp6-serverid">
|
||
<title>Server Identifier in DHCPv6</title>
|
||
<para>The DHCPv6 protocol uses a "server identifier" (also known
|
||
as a DUID) for clients to be able to discriminate between several
|
||
servers present on the same link.
|
||
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc8415">RFC 8415</link>
|
||
defines four DUID types: DUID-LLT, DUID-EN, DUID-LL and DUID-UUID.
|
||
Future specifications may introduce new DUID types.</para>
|
||
|
||
<para>The Kea DHCPv6 server generates a server identifier once, upon
|
||
the first startup, and stores it in a file. This identifier isn't
|
||
modified across restarts of the server and so is a stable identifier.</para>
|
||
|
||
<para>Kea follows recommendation from
|
||
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc8415">RFC 8415</link>
|
||
to use DUID-LLT as the default server identifier. However, we have
|
||
received reports that some deployments require different DUID
|
||
types, and there is a need to administratively select both DUID
|
||
type and/or its contents.</para>
|
||
|
||
<para>The server identifier can be configured using parameters
|
||
within the <command>server-id</command> map element in the global
|
||
scope of the Kea configuration file. The following example
|
||
demonstrates how to select DUID-EN as a server identifier:
|
||
|
||
<screen>
|
||
"Dhcp6": {
|
||
"server-id": {
|
||
"type": "EN"
|
||
},
|
||
...
|
||
}
|
||
</screen>
|
||
|
||
</para>
|
||
|
||
<para>Currently supported values for <command>type</command>
|
||
parameter are: "LLT", "EN" and "LL", for DUID-LLT, DUID-EN and
|
||
DUID-LL respectively.</para>
|
||
|
||
<para>When a new DUID type is selected the server will generate its
|
||
value and replace any existing DUID in the file. The server will then
|
||
use the new server identifier in all future interactions with the
|
||
clients.</para>
|
||
|
||
<note><para>If the new server identifier is created after some clients
|
||
have obtained their leases, the clients using the old identifier will not
|
||
be able to renew the leases: the server will ignore messages
|
||
containing the old server identifier. Clients will continue sending
|
||
Renew until they transition to the rebinding state. In this state they
|
||
will start sending Rebind messages to multicast address without
|
||
a server identifier. The server will respond to the Rebind messages
|
||
with a new server identifier and the clients will associate the
|
||
new server identifier with their leases. Although the clients will
|
||
be able to keep their leases and will eventually learn the new server
|
||
identifier, this will be at the cost of increased number of renewals
|
||
and multicast traffic due to a need to rebind. Therefore it is
|
||
recommended that modification of the server identifier type
|
||
and value is avoided if the server has already assigned leases and these
|
||
leases are still valid.</para></note>
|
||
|
||
<para>There are cases when an administrator needs to explicitly
|
||
specify a DUID value rather than allow the server to generate it.
|
||
The following example demonstrates how to explicitly set all
|
||
components of a DUID-LLT.
|
||
|
||
<screen>
|
||
"Dhcp6": {
|
||
"server-id": {
|
||
"type": "LLT",
|
||
"htype": 8,
|
||
"identifier": "A65DC7410F05",
|
||
"time": 2518920166
|
||
},
|
||
...
|
||
}
|
||
</screen>
|
||
|
||
where:
|
||
<itemizedlist>
|
||
<listitem><simpara><command>htype</command> is a 16-bit unsigned value
|
||
specifying hardware type,</simpara></listitem>
|
||
<listitem><simpara><command>identifier</command> is a link layer
|
||
address, specified as a string of hexadecimal digits,</simpara>
|
||
</listitem>
|
||
<listitem><simpara><command>time</command> is a 32-bit unsigned
|
||
time value.</simpara></listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
|
||
<para>The hexadecimal representation of the DUID generated as a result
|
||
of the configuration specified above will be:
|
||
<screen>
|
||
00:01:00:08:96:23:AB:E6:A6:5D:C7:41:0F:05
|
||
|type |htype| time | identifier |
|
||
</screen>
|
||
</para>
|
||
|
||
<para>It is allowed to use special value of 0 for "htype" and "time",
|
||
which indicates that the server should use ANY value for these
|
||
components. If the server already uses a DUID-LLT it will use the
|
||
values from this DUID. If the server uses a DUID of a different type
|
||
or doesn't use any DUID yet, it will generate these values.
|
||
Similarly, if the "identifier" is assigned an empty string, the
|
||
value of the identifier will be generated. Omitting any of these
|
||
parameters is equivalent to setting them to those special values.
|
||
</para>
|
||
|
||
<para>For example, the following configuration:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"server-id": {
|
||
"type": "LLT",
|
||
"htype": 0,
|
||
"identifier": "",
|
||
"time": 2518920166
|
||
},
|
||
...
|
||
}
|
||
</screen>
|
||
|
||
indicates that the server should use ANY link layer address and
|
||
hardware type. If the server is already using DUID-LLT it will
|
||
use the link layer address and hardware type from the existing DUID.
|
||
If the server is not using any DUID yet, it will use link layer
|
||
address and hardware type from one of the available network
|
||
interfaces. The server will use an explicit value of time. If it
|
||
is different than a time value present in the currently used
|
||
DUID, that value will be replaced, effectively causing
|
||
modification of the current server identifier.
|
||
</para>
|
||
|
||
<para>
|
||
The following example demonstrates an explicit configuration of
|
||
a DUID-EN:
|
||
|
||
<screen>
|
||
"Dhcp6": {
|
||
"server-id": {
|
||
"type": "EN",
|
||
"enterprise-id": 2495,
|
||
"identifier": "87ABEF7A5BB545"
|
||
},
|
||
...
|
||
}
|
||
</screen>
|
||
|
||
where:
|
||
<itemizedlist>
|
||
<listitem><simpara><command>enterprise-id</command> is a 32-bit
|
||
unsigned value holding enterprise number,</simpara></listitem>
|
||
<listitem><simpara><command>identifier</command> is a variable
|
||
length identifier within DUID-EN.</simpara></listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
|
||
<para>
|
||
The hexadecimal representation of the DUID-EN created according to
|
||
the configuration above is:
|
||
<screen>
|
||
00:02:00:00:09:BF:87:AB:EF:7A:5B:B5:45
|
||
|type | ent-id | identifier |
|
||
</screen>
|
||
</para>
|
||
|
||
<para>As in the case of the DUID-LLT, special values can be used for the
|
||
configuration of the DUID-EN. If <command>enterprise-id</command> is 0, the server
|
||
will use a value from the existing DUID-EN. If the server is not using
|
||
any DUID or the existing DUID has a different type, the ISC enterprise
|
||
id will be used. When an empty string is used for <command>identifier</command>, the
|
||
identifier from the existing DUID-EN will be used. If the server is
|
||
not using any DUID-EN the new 6-bytes long identifier will be generated.
|
||
</para>
|
||
|
||
<para>DUID-LL is configured in the same way as DUID-LLT with an exception
|
||
that the <command>time</command> parameter has no effect for DUID-LL,
|
||
because this DUID type only comprises a hardware type and link layer
|
||
address. The following example demonstrates how to configure DUID-LL:
|
||
|
||
<screen>
|
||
"Dhcp6": {
|
||
"server-id": {
|
||
"type": "LL",
|
||
"htype": 8,
|
||
"identifier": "A65DC7410F05"
|
||
},
|
||
...
|
||
}
|
||
</screen>
|
||
|
||
</para>
|
||
|
||
<para>
|
||
which will result in the following server identifier:
|
||
|
||
<screen>
|
||
00:03:00:08:A6:5D:C7:41:0F:05
|
||
|type |htype| identifier |
|
||
</screen>
|
||
</para>
|
||
|
||
<para>The server stores the generated server identifier in the following
|
||
location: [kea-install-dir]/var/kea/kea-dhcp6-serverid.
|
||
</para>
|
||
|
||
<para>In some uncommon deployments where no stable storage is
|
||
available, the server should be configured not to try to
|
||
store the server identifier. This choice is controlled
|
||
by the value of <command>persist</command> boolean parameter:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"server-id": {
|
||
"type": "EN",
|
||
"enterprise-id": 2495,
|
||
"identifier": "87ABEF7A5BB545",
|
||
"persist": false
|
||
},
|
||
...
|
||
}
|
||
</screen>
|
||
</para>
|
||
<para>The default value of the "persist" parameter is
|
||
<command>true</command> which configures the server to store the
|
||
server identifier on a disk.</para>
|
||
|
||
<para>In the example above, the server is configured to not store
|
||
the generated server identifier on a disk. But, if the server
|
||
identifier is not modified in the configuration the same value
|
||
will be used after server restart, because entire server
|
||
identifier is explicitly specified in the configuration.</para>
|
||
</section>
|
||
|
||
<section xml:id="stateless-dhcp6">
|
||
<title>Stateless DHCPv6 (Information-Request Message)</title>
|
||
<para>Typically DHCPv6 is used to assign both addresses and options. These
|
||
assignments (leases) have state that changes over time, hence
|
||
their name, stateful. DHCPv6 also supports a stateless mode,
|
||
where clients request configuration options only. This mode is
|
||
considered lightweight from the server perspective as it does not require
|
||
any state tracking; hence its name.</para>
|
||
<para>The Kea server supports stateless mode. Clients can send
|
||
Information-Request messages and the server will send back
|
||
answers with the requested options (providing the options are
|
||
available in the server configuration). The server will attempt to
|
||
use per-subnet options first. If that fails - for whatever reason - it
|
||
will then try to provide options defined in the global scope.</para>
|
||
|
||
<para>Stateless and stateful mode can be used together. No special
|
||
configuration directives are required to handle this. Simply use the
|
||
configuration for stateful clients and the stateless clients will get
|
||
just options they requested.</para>
|
||
|
||
<para>This usage of global options allows for an interesting case.
|
||
It is possible to run a server that provides just options and no
|
||
addresses or prefixes. If the options have the same value in each
|
||
subnet, the configuration can define required options in the global
|
||
scope and skip subnet definitions altogether. Here's a simple example of
|
||
such a configuration:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"interfaces-config": {
|
||
"interfaces": [ "ethX" ]
|
||
},
|
||
<userinput>"option-data": [ {
|
||
"name": "dns-servers",
|
||
"data": "2001:db8::1, 2001:db8::2"
|
||
} ]</userinput>,
|
||
"lease-database": { "type": "memfile" }
|
||
}
|
||
</screen>
|
||
This very simple configuration will provide DNS server information
|
||
to all clients in the network, regardless of their location. Note the
|
||
specification of the memfile lease database: this is needed as
|
||
Kea requires a lease database to be specified
|
||
even if it is not used.</para>
|
||
</section>
|
||
|
||
<section xml:id="dhcp6-rfc7550">
|
||
<title>Support for RFC 7550 (being now part of RFC 8415)</title>
|
||
<para>The <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc7550">RFC 7550</link>
|
||
introduced some changes to the previous DHCPv6 specifications,
|
||
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc3315">RFC 3315</link>
|
||
and <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc3633">RFC 3633</link>,
|
||
to resolve a few issues with the coexistence of multiple stateful
|
||
options in the messages sent between the clients and servers. Those
|
||
changes were later included in the most recent DHCPv6 protocol specification,
|
||
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc8415">RFC 8415</link>,
|
||
which obsoleted <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc7550">RFC 7550</link>.
|
||
Kea supports <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc8415">RFC 8415</link>
|
||
along with these protocol changes, which are briefly described below.
|
||
</para>
|
||
|
||
<para>When a client, such as a requesting router, requests an allocation
|
||
of both addresses and prefixes during the 4-way (SARR) exchange with the
|
||
server, and the server is not configured to allocate any prefixes but it
|
||
can allocate some addresses, it will respond with the IA_NA(s) containing
|
||
allocated addresses and the IA_PD(s) containing the NoPrefixAvail status code.
|
||
According to the updated specifications, if the client can operate without
|
||
prefixes it should accept allocated addresses and transition to
|
||
the 'bound' state. When the client subsequently sends Renew/Rebind messages
|
||
to the server, according to the T1 and T2 times, to extend the lifetimes of
|
||
the allocated addresses, if the client is still interested in obtaining
|
||
prefixes from the server, it may also include an IA_PD in the Renew/Rebind
|
||
to request allocation of the prefixes. If the server still cannot
|
||
allocate the prefixes it will respond with the IA_PD(s) containing
|
||
NoPrefixAvail status code. However, if the server can allocate the
|
||
prefixes it will allocate and send them in the IA_PD(s) to the client.
|
||
Similar situation occurs when the server is unable to allocate addresses
|
||
for the client but can delegate prefixes. The client may request allocation
|
||
of the addresses while renewing the delegated prefixes. Allocating leases for
|
||
other IA types while renewing existing leases is by default supported by
|
||
the Kea DHCPv6 server, and the server provides no configuration mechanisms
|
||
to disable this behavior.</para>
|
||
|
||
<para>
|
||
The following are the other behaviors first introduced in the
|
||
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc7550">RFC 7550</link>
|
||
(now being part of the
|
||
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc8415">RFC 8415</link>)
|
||
and supported by the Kea DHCPv6 server:
|
||
<itemizedlist>
|
||
<listitem><simpara>Set T1/T2 timers to the same value for all
|
||
stateful (IA_NA and IA_PD) options to facilitate renewal of all
|
||
client's leases at the same time (in a single message exchange),
|
||
</simpara></listitem>
|
||
<listitem><simpara>NoAddrsAvail and NoPrefixAvail status codes
|
||
are placed in the IA_NA and IA_PD options in the Advertise message,
|
||
rather than as the top level options.</simpara></listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
</section>
|
||
|
||
<section xml:id="dhcp6-relay-override">
|
||
<title>Using Specific Relay Agent for a Subnet</title>
|
||
<para>
|
||
The relay has to have an interface connected to the link on which
|
||
the clients are being configured. Typically the relay has a global IPv6
|
||
address configured on the interface that belongs to the subnet from which
|
||
the server will assign addresses. In the typical case, the
|
||
server is able to use the IPv6 address inserted by the relay (in the link-addr
|
||
field in RELAY-FORW message) to select the appropriate subnet.
|
||
</para>
|
||
<para>
|
||
However, that is not always the case. The relay
|
||
address may not match the subnet in certain deployments. This
|
||
usually means that there is more than one subnet allocated for a given
|
||
link. The two most common examples where this is the case are long lasting
|
||
network renumbering (where both old and new address space is still being
|
||
used) and a cable network. In a cable network both cable modems and the
|
||
devices behind them are physically connected to the same link, yet
|
||
they use distinct addressing. In such case, the DHCPv6 server needs
|
||
additional information (like the value of interface-id option or IPv6
|
||
address inserted in the link-addr field in RELAY-FORW message) to
|
||
properly select an appropriate subnet.
|
||
</para>
|
||
<para>
|
||
The following example assumes that there is a subnet 2001:db8:1::/64
|
||
that is accessible via a relay that uses 3000::1 as its IPv6 address.
|
||
The server will be able to select this subnet for any incoming packets
|
||
that came from a relay with an address in 2001:db8:1::/64 subnet.
|
||
It will also select that subnet for a relay with address 3000::1.
|
||
<screen>
|
||
"Dhcp6": {
|
||
"subnet6": [
|
||
{
|
||
"subnet": "2001:db8:1::/64",
|
||
"pools": [
|
||
{
|
||
"pool": "2001:db8:1::1-2001:db8:1::ffff"
|
||
}
|
||
],
|
||
<userinput>"relay": {
|
||
"ip-addresses": [ "3000::1" ]
|
||
}</userinput>
|
||
}
|
||
]
|
||
}
|
||
</screen>
|
||
</para>
|
||
|
||
<para>If "relay" is specified, the "ip-addresses" parameter within
|
||
it is mandatory.</para>
|
||
|
||
<note>
|
||
<para>
|
||
As of Kea 1.4, the "ip-address" parameter in "relay" has been deprecated
|
||
in favor of "ip-addresses" which supports specifying a list of addresses.
|
||
Configuration parsing, will honor the singular form for now but users are
|
||
encouraged to migrate.
|
||
</para>
|
||
</note>
|
||
|
||
</section>
|
||
|
||
<section xml:id="dhcp6-client-class-relay">
|
||
<title>Segregating IPv6 Clients in a Cable Network</title>
|
||
<para>
|
||
In certain cases, it is useful to mix relay address information,
|
||
introduced in <xref linkend="dhcp6-relay-override"/> with client
|
||
classification, explained in <xref linkend="classify"/>.
|
||
One specific example is a cable network, where typically modems
|
||
get addresses from a different subnet than all devices connected
|
||
behind them.
|
||
</para>
|
||
<para>
|
||
Let's assume that there is one CMTS (Cable Modem Termination System)
|
||
with one CM MAC (a physical link that modems are connected to).
|
||
We want the modems to get addresses from the 3000::/64 subnet,
|
||
while everything connected behind modems should get addresses from
|
||
another subnet (2001:db8:1::/64). The CMTS that acts as a relay
|
||
an uses address 3000::1. The following configuration can serve
|
||
that configuration:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"subnet6": [
|
||
{
|
||
"subnet": "3000::/64",
|
||
"pools": [
|
||
{ "pool": "3000::2 - 3000::ffff" }
|
||
],
|
||
<userinput>"client-class": "VENDOR_CLASS_docsis3.0",
|
||
"relay": {
|
||
"ip-addresses": [ "3000::1" ]
|
||
}</userinput>
|
||
},
|
||
|
||
{
|
||
"subnet": "2001:db8:1::/64",
|
||
"pools": [
|
||
{
|
||
"pool": "2001:db8:1::1-2001:db8:1::ffff"
|
||
}
|
||
],
|
||
<userinput>"relay": {
|
||
"ip-addresses": [ "3000::1" ]
|
||
}</userinput>
|
||
}
|
||
]
|
||
}
|
||
</screen>
|
||
</para>
|
||
</section>
|
||
|
||
<section xml:id="mac-in-dhcpv6">
|
||
<title>MAC/Hardware Addresses in DHCPv6</title>
|
||
<para>MAC/hardware addresses are available in DHCPv4 messages
|
||
from the clients and administrators
|
||
frequently use that information to perform certain tasks, like per host
|
||
configuration, address reservation for specific MAC addresses and other.
|
||
Unfortunately, the DHCPv6 protocol does not provide any completely reliable way
|
||
to retrieve that information. To mitigate that issue a number of mechanisms
|
||
have been implemented in Kea that attempt to gather it. Each
|
||
of those mechanisms works in certain cases, but may fail in other cases.
|
||
Whether the mechanism works or not in the particular deployment is
|
||
somewhat dependent on the network topology and the technologies used.</para>
|
||
|
||
<para>Kea allows configuration of which of the supported methods should be
|
||
used and in what order. This configuration may be considered a fine tuning
|
||
of the DHCP deployment. In a typical deployment the default
|
||
value of <command>"any"</command> is sufficient and there is no
|
||
need to select specific methods. Changing the value of this parameter
|
||
is the most useful in cases when an administrator wants to disable
|
||
certain method, e.g. if the administrator trusts the network infrastructure
|
||
more than the information provided by the clients themselves, the
|
||
administrator may prefer information provided by the relays over that
|
||
provided by the clients.
|
||
</para>
|
||
<para>
|
||
The configuration is controlled by the <command>mac-sources</command>
|
||
parameter as follows:
|
||
<screen>
|
||
"Dhcp6": {
|
||
<userinput>"mac-sources": [ "method1", "method2", "method3", ... ]</userinput>,
|
||
|
||
"subnet6": [ ... ],
|
||
|
||
...
|
||
}
|
||
</screen>
|
||
|
||
When not specified, a special value of "any" is used, which
|
||
instructs the server to attempt to use all the methods in sequence and use
|
||
value returned by the first one that succeeds. If specified, it
|
||
has to have at least one value.</para>
|
||
|
||
<para>Supported methods are:
|
||
<itemizedlist>
|
||
<listitem>
|
||
<simpara><command>any</command> - Not an actual method, just a keyword that
|
||
instructs Kea to try all other methods and use the first one that succeeds.
|
||
This is the default operation if no <command>mac-sources</command> are defined.
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara><command>raw</command> - In principle, a DHCPv6 server could use raw
|
||
sockets to receive incoming traffic and extract MAC/hardware address
|
||
information. This is currently not implemented for DHCPv6 and this value has
|
||
no effect.
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara><command>duid</command> - DHCPv6 uses DUID identifiers instead of
|
||
MAC addresses. There are currently four DUID types defined, with two of them
|
||
(DUID-LLT, which is the default one and DUID-LL) convey MAC address information.
|
||
Although <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="" utl="http://tools.ietf.org/html/rfc8415">RFC 8415</link> forbids
|
||
it, it is possible to parse those DUIDs and extract
|
||
necessary information from them. This method is not completely reliable, as
|
||
clients may use other DUID types, namely DUID-EN or DUID-UUID.
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara><command>ipv6-link-local</command> - Another possible acquisition
|
||
method comes from the source IPv6 address. In typical usage, clients are
|
||
sending their packets from IPv6 link-local addresses. There is a good chance
|
||
that those addresses are based on EUI-64, which contains MAC address. This
|
||
method is not completely reliable, as clients may use other link-local address
|
||
types. In particular, privacy extensions, defined in
|
||
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc4941">RFC 4941</link>, do not use
|
||
MAC addresses. Also note that successful extraction requires that the
|
||
address's u-bit must be set to 1 and its g-bit set to 0, indicating that it
|
||
is an interface identifier as per
|
||
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc2373#section-2.5.1">
|
||
RFC 2373, section 2.5.1</link>.
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara><command>client-link-addr-option</command> - One extension defined
|
||
to alleviate missing MAC issues is client link-layer address option, defined
|
||
in <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc6939">RFC 6939</link>. This is
|
||
an option that is inserted by a relay and contains information about client's
|
||
MAC address. This method requires a relay agent that supports the option and
|
||
is configured to insert it. This method is useless for directly connected
|
||
clients. This parameter can also be specified as <command>rfc6939</command>,
|
||
which is an alias for <command>client-link-addr-option</command>.
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara><command>remote-id</command> -
|
||
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc4649">RFC 4649</link>
|
||
defines a remote-id option that is inserted by a relay agent. Depending
|
||
on the relay agent configuration, the inserted option may convey the client's
|
||
MAC address information. This parameter can also be specified as
|
||
<command>rfc4649</command>, which is an alias for <command>remote-id</command>.
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara><command>subscriber-id</command> - Another option
|
||
that is somewhat similar to the previous one is subscriber-id,
|
||
defined in <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc4580">RFC
|
||
4580</link>. It is, too, inserted by a relay agent that is
|
||
configured to insert it. This parameter can also be specified
|
||
as <command>rfc4580</command>, which is an alias for
|
||
<command>subscriber-id</command>. This method is currently not
|
||
implemented.
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara><command>docsis-cmts</command> - Yet another possible source of MAC
|
||
address information are the DOCSIS options inserted by a CMTS that acts
|
||
as a DHCPv6 relay agent in cable networks. This method attempts to extract
|
||
MAC address information from suboption 1026 (cm mac) of the vendor specific option
|
||
with vendor-id=4491. This vendor option is extracted from the relay-forward message,
|
||
not the original client's message.
|
||
</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara><command>docsis-modem</command> - Yet another possible source of MAC
|
||
address information are the DOCSIS options inserted by the cable modem itself.
|
||
This method attempts to extract MAC address information from suboption 36 (device id)
|
||
of the vendor specific option with vendor-id=4491. This vendor option is extracted from
|
||
the original client's message, not from any relay options.
|
||
</simpara>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</para>
|
||
|
||
<para>Empty mac-sources is not allowed. If you do not want to specify it,
|
||
either simply omit mac-sources definition or specify it with the "any" value
|
||
which is the default.</para>
|
||
</section>
|
||
|
||
<section xml:id="dhcp6-decline">
|
||
<title>Duplicate Addresses (DECLINE Support)</title>
|
||
|
||
<para>The DHCPv6 server is configured with a certain pool of
|
||
addresses that it is expected to hand out to the DHCPv6 clients.
|
||
It is assumed that the server is authoritative and has complete
|
||
jurisdiction over those addresses. However, due to various
|
||
reasons, such as misconfiguration or a faulty client implementation
|
||
that retains its address beyond the valid lifetime, there may be
|
||
devices connected that use those addresses without the server's
|
||
approval or knowledge.</para>
|
||
|
||
<para>Such an unwelcome event can be detected
|
||
by legitimate clients (using Duplicate Address Detection) and
|
||
reported to the DHCPv6 server using a DECLINE message. The server
|
||
will do a sanity check (if the client declining an address really
|
||
was supposed to use it), then will conduct a clean up operation
|
||
and confirm it by sending back a REPLY message. Any DNS entries
|
||
related to that address will be removed, the fact will be logged
|
||
and hooks will be triggered. After that is done, the address
|
||
will be marked as declined (which indicates that it is used by
|
||
an unknown entity and thus not available for assignment to
|
||
anyone) and a probation time will be set on it. Unless otherwise
|
||
configured, the probation period lasts 24 hours. After that
|
||
period, the server will recover the lease (i.e. put it back into
|
||
the available state) and the address will be available for assignment
|
||
again. It should be noted that if the underlying issue of a
|
||
misconfigured device is not resolved, the duplicate address
|
||
scenario will repeat. On the other hand, it provides an
|
||
opportunity to recover from such an event automatically, without
|
||
any sysadmin intervention.</para>
|
||
|
||
<para>To configure the decline probation period to a value other
|
||
than the default, the following syntax can be used:
|
||
<screen>
|
||
"Dhcp6": {
|
||
<userinput>"decline-probation-period": 3600</userinput>,
|
||
"subnet6": [ ... ],
|
||
...
|
||
}
|
||
</screen>
|
||
The parameter is expressed in seconds, so the example above will instruct
|
||
the server to recycle declined leases after an hour.</para>
|
||
|
||
<para>There are several statistics and hook points associated with the
|
||
Decline handling procedure. The lease6_decline hook is triggered after the
|
||
incoming Decline message has been sanitized and the server is about to decline
|
||
the lease. The declined-addresses statistic is increased after the
|
||
hook returns (both global and subnet specific variants). (See
|
||
<xref linkend="dhcp4-stats"/> and <xref linkend="hooks-libraries"/> for more details
|
||
on DHCPv4 statistics and Kea hook points.)</para>
|
||
|
||
<para>Once the probation time elapses, the declined lease is recovered
|
||
using the standard expired lease reclamation procedure, with several
|
||
additional steps. In particular, both declined-addresses statistics
|
||
(global and subnet specific) are decreased. At the same time,
|
||
reclaimed-declined-addresses statistics (again in two variants, global and
|
||
subnet specific) are increased.</para>
|
||
|
||
<para>Note about statistics: The server does not decrease the
|
||
assigned-addresses statistics when a DECLINE message is received and
|
||
processed successfully. While technically a declined address is no longer
|
||
assigned, the primary usage of the assigned-addresses statistic is to
|
||
monitor pool utilization. Most people would forget to include
|
||
declined-addresses in the calculation, and simply do
|
||
assigned-addresses/total-addresses. This would have a bias towards
|
||
under-representing pool utilization. As this has a potential for major
|
||
issues, we decided not to decrease assigned addresses immediately after
|
||
receiving Decline, but to do it later when we recover the address back to
|
||
the available pool.</para>
|
||
</section>
|
||
|
||
<section xml:id="dhcp6-stats">
|
||
<title>Statistics in the DHCPv6 Server</title>
|
||
<note>
|
||
<para>This section describes DHCPv6-specific statistics. For a general
|
||
overview and usage of statistics, see <xref linkend="stats"/>.</para>
|
||
</note>
|
||
|
||
<para>
|
||
The DHCPv6 server supports the following statistics:
|
||
</para>
|
||
<table frame="all" xml:id="dhcp6-statistics">
|
||
<title>DHCPv6 Statistics</title>
|
||
<tgroup cols="3">
|
||
<colspec colname="statistic" align="center"/>
|
||
<colspec colname="type" align="center"/>
|
||
<colspec colname="description" align="left"/>
|
||
<thead>
|
||
<row>
|
||
<entry>Statistic</entry>
|
||
<entry>Data Type</entry>
|
||
<entry>Description</entry>
|
||
</row>
|
||
</thead>
|
||
<tbody>
|
||
|
||
<row>
|
||
<entry>pkt6-received</entry>
|
||
<entry>integer</entry>
|
||
<entry>Number of DHCPv6 packets received. This includes all packets:
|
||
valid, bogus, corrupted, rejected etc. This statistic is expected
|
||
to grow rapidly.</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>pkt6-receive-drop</entry>
|
||
<entry>integer</entry>
|
||
<entry>Number of incoming packets that were dropped. The exact reason
|
||
for dropping packets is logged, but the most common reasons may
|
||
be: an unacceptable or not supported packet type, direct responses
|
||
are forbidden, the server-id sent by the client does not match the
|
||
server's server-id or the packet is malformed.</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>pkt6-parse-failed</entry>
|
||
<entry>integer</entry>
|
||
<entry>Number of incoming packets that could not be parsed.
|
||
A non-zero value of this statistic indicates that the server
|
||
received a malformed or truncated packet. This may indicate problems
|
||
in your network, faulty clients, faulty relay agents or a bug in the
|
||
server.</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>pkt6-solicit-received</entry>
|
||
<entry>integer</entry>
|
||
<entry>
|
||
Number of SOLICIT packets received. This statistic is expected
|
||
to grow. Its increase means that clients that just booted
|
||
started their configuration process and their initial packets
|
||
reached your server.
|
||
</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>pkt6-advertise-received</entry>
|
||
<entry>integer</entry>
|
||
<entry>
|
||
Number of ADVERTISE packets received. Advertise packets are sent
|
||
by the server and the server is never expected to receive them. A non-zero
|
||
value of this statistic indicates an error occurring in the network.
|
||
One likely cause would be a misbehaving relay agent that incorrectly
|
||
forwards ADVERTISE messages towards the server rather back to the
|
||
clients.
|
||
</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>pkt6-request-received</entry>
|
||
<entry>integer</entry>
|
||
<entry>Number of REQUEST packets received. This statistic
|
||
is expected to grow. Its increase means that clients that just booted
|
||
received the server's response (ADVERTISE), accepted it and are now
|
||
requesting an address (REQUEST).
|
||
</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>pkt6-reply-received</entry>
|
||
<entry>integer</entry>
|
||
<entry>Number of REPLY packets received. This statistic is
|
||
expected to remain zero at all times, as REPLY packets are sent by
|
||
the server and the server is never expected to receive
|
||
them. A non-zero value indicates an error. One likely cause would be
|
||
a misbehaving relay agent that incorrectly forwards REPLY messages
|
||
towards the server, rather back to the clients.
|
||
</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>pkt6-renew-received</entry>
|
||
<entry>integer</entry>
|
||
<entry>Number of RENEW packets received. This statistic
|
||
is expected to grow. Its increase means that clients received their
|
||
addresses and prefixes and are trying to renew them.
|
||
</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>pkt6-rebind-received</entry>
|
||
<entry>integer</entry>
|
||
<entry>Number of REBIND packets received. A non-zero value
|
||
indicates that clients didn't receive responses to their RENEW messages
|
||
(regular lease renewal mechanism) and are attempting to find any server
|
||
that is able to take over their leases. It may mean that some server's
|
||
REPLY messages never reached the clients.
|
||
</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>pkt6-release-received</entry>
|
||
<entry>integer</entry>
|
||
<entry>Number of RELEASE packets received. This statistic is expected
|
||
to grow when a device is being shut down in the network. It
|
||
indicates that the address or prefix assigned is reported as no longer
|
||
needed. Note that many devices, especially wireless, do not send RELEASE
|
||
packets either because of design choice or due to the client moving out
|
||
of range.
|
||
</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>pkt6-decline-received</entry>
|
||
<entry>integer</entry>
|
||
<entry>
|
||
Number of DECLINE packets received. This statistic is expected to
|
||
remain close to zero. Its increase means that a client leased an
|
||
address, but discovered that the address is currently used by an
|
||
unknown device in your network. If this statistic is growing, it
|
||
may indicate a misconfigured server or devices that have statically
|
||
assigned conflicting addresses.
|
||
</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>pkt6-infrequest-received</entry>
|
||
<entry>integer</entry>
|
||
<entry>
|
||
Number of INFORMATION-REQUEST packets received. This statistic
|
||
is expected to grow if there are devices that are using
|
||
stateless DHCPv6. INFORMATION-REQUEST messages are used by
|
||
clients that request stateless configuration, i.e. options
|
||
and parameters other than addresses or prefixes.
|
||
</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>pkt6-dhcpv4-query-received</entry>
|
||
<entry>integer</entry>
|
||
<entry>
|
||
Number of DHCPv4-QUERY packets received. This
|
||
statistic is expected to grow if there are devices
|
||
that are using DHCPv4-over-DHCPv6. DHCPv4-QUERY
|
||
messages are used by DHCPv4 clients on an IPv6 only
|
||
line which encapsulates the requests over DHCPv6.
|
||
</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>pkt6-dhcpv4-response-received</entry>
|
||
<entry>integer</entry>
|
||
<entry>
|
||
Number of DHCPv4-RESPONSE packets received. This
|
||
statistic is expected to remain zero at all times, as
|
||
DHCPv4-RESPONSE packets are sent by the server and the
|
||
server is never expected to receive them. A non-zero
|
||
value indicates an error. One likely cause would be a
|
||
misbehaving relay agent that incorrectly forwards
|
||
DHCPv4-RESPONSE message towards the server rather
|
||
back to the clients.
|
||
</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>pkt6-unknown-received</entry>
|
||
<entry>integer</entry>
|
||
<entry>Number of packets received of an unknown type. A non-zero
|
||
value of this statistic indicates that the server received a
|
||
packet that it wasn't able to recognize: either it had an unsupported
|
||
type or was possibly malformed.</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>pkt6-sent</entry>
|
||
<entry>integer</entry>
|
||
<entry>Number of DHCPv6 packets sent. This statistic is expected
|
||
to grow every time the server transmits a packet. In general, it
|
||
should roughly match pkt6-received, as most incoming packets cause
|
||
the server to respond. There are exceptions (e.g. server receiving a
|
||
REQUEST with server-id matching other server), so do not worry, if
|
||
it is lesser than pkt6-received.</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>pkt6-advertise-sent</entry>
|
||
<entry>integer</entry>
|
||
<entry>Number of ADVERTISE packets sent. This statistic is
|
||
expected to grow in most cases after a SOLICIT is processed. There
|
||
are certain uncommon, but valid cases where incoming SOLICIT is
|
||
dropped, but in general this statistic is expected to be close to
|
||
pkt6-solicit-received.</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>pkt6-reply-sent</entry>
|
||
<entry>integer</entry>
|
||
<entry>Number of REPLY packets sent. This statistic is expected to
|
||
grow in most cases after a SOLICIT (with rapid-commit), REQUEST,
|
||
RENEW, REBIND, RELEASE, DECLINE or INFORMATION-REQUEST is
|
||
processed. There are certain cases where there is no response.
|
||
</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>pkt6-dhcpv4-response-sent</entry>
|
||
<entry>integer</entry>
|
||
<entry>Number of DHCPv4-RESPONSE packets sent. This
|
||
statistic is expected to grow in most cases after a
|
||
DHCPv4-QUERY is processed. There are certain cases where
|
||
there is no response.
|
||
</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>subnet[id].total-nas</entry>
|
||
<entry>integer</entry>
|
||
<entry>
|
||
This statistic shows the total number of NA addresses available for
|
||
DHCPv6 management for a given subnet. In other words, this is the sum
|
||
of all addresses in all configured pools. This statistic changes only
|
||
during configuration changes. Note that it does not take into account any
|
||
addresses that may be reserved due to host reservation. The
|
||
<emphasis>id</emphasis> is the subnet-id of a given subnet. This
|
||
statistic is exposed for each subnet separately and is
|
||
reset during a reconfiguration event.
|
||
</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>subnet[id].assigned-nas</entry>
|
||
<entry>integer</entry>
|
||
<entry>
|
||
This statistic shows the number of NA addresses in a given subnet that
|
||
are assigned. This statistic increases every time a new lease is allocated
|
||
(as a result of receiving a REQUEST message) and is decreased every time a
|
||
lease is released (a RELEASE message is received) or expires. The
|
||
<emphasis>id</emphasis> is the subnet-id of a given subnet. This
|
||
statistic is exposed for each subnet separately and is
|
||
reset during a reconfiguration event.
|
||
</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>subnet[id].total-pds</entry>
|
||
<entry>integer</entry>
|
||
<entry>
|
||
This statistic shows the total number of PD prefixes available for
|
||
DHCPv6 management for a given subnet. In other words, this is the sum
|
||
of all prefixes in all configured pools. This statistic changes only
|
||
during configuration changes. Note it does not take into account any
|
||
prefixes that may be reserved due to host reservation. The
|
||
<emphasis>id</emphasis> is the subnet-id of a given subnet. This
|
||
statistic is exposed for each subnet separately and is
|
||
reset during a reconfiguration event.
|
||
</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>subnet[id].assigned-pds</entry>
|
||
<entry>integer</entry>
|
||
<entry>
|
||
This statistic shows the number of PD prefixes in a given subnet that
|
||
are assigned. This statistic increases every time a new lease is allocated
|
||
(as a result of receiving a REQUEST message) and is decreased every time a
|
||
lease is released (a RELEASE message is received) or expires. The
|
||
<emphasis>id</emphasis> is the subnet-id of a given subnet. This statistic
|
||
is exposed for each subnet separately and is reset during a
|
||
reconfiguration event.
|
||
</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>reclaimed-leases</entry>
|
||
<entry>integer</entry>
|
||
<entry> This statistic is the number of expired leases that have been
|
||
reclaimed since server startup. It is incremented each time an expired
|
||
lease is reclaimed (it counts both NA and PD reclamations) and is reset
|
||
when the server is reconfigured.
|
||
</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>subnet[id].reclaimed-leases</entry>
|
||
<entry>integer</entry>
|
||
<entry>This statistic is the number of expired leases associated with
|
||
a given subnet (<emphasis>"id"</emphasis> is the subnet-id) that have
|
||
been reclaimed since server startup. It is incremented each time an expired
|
||
lease is reclaimed (it counts both NA and PD reclamations) and is reset
|
||
when the server is reconfigured.
|
||
</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>declined-addresses</entry>
|
||
<entry>integer</entry>
|
||
<entry>
|
||
This statistic shows the number of IPv6 addresses that are
|
||
currently declined and so counts the number of leases
|
||
currently unavailable. Once a lease is recovered, this
|
||
statistic will be decreased. Ideally, this statistic should be
|
||
zero. If this statistic is non-zero (or worse, increasing),
|
||
the network administrator should investigate if there is
|
||
a misbehaving device in the network. This is a global statistic
|
||
that covers all subnets.
|
||
</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>subnet[id].declined-addresses</entry>
|
||
<entry>integer</entry>
|
||
<entry>
|
||
This statistic shows the number of IPv6 addresses that are
|
||
currently declined in a given subnet. This statistic counts the
|
||
number of leases currently unavailable. Once a lease is
|
||
recovered, this statistic will be decreased. Ideally, this
|
||
statistic should be zero. If this statistic is
|
||
non-zero (or worse, increasing), a network administrator should
|
||
investigate if there is a misbehaving device in the network. The
|
||
<emphasis>id</emphasis> is the subnet-id of a given subnet. This
|
||
statistic is exposed for each subnet separately.
|
||
</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>reclaimed-declined-addresses</entry>
|
||
<entry>integer</entry>
|
||
<entry>
|
||
This statistic shows the number of IPv6 addresses that were
|
||
declined, but have now been recovered. Unlike
|
||
declined-addresses, this statistic never decreases. It can be used
|
||
as a long term indicator of how many actual valid Declines were
|
||
processed and recovered from. This is a global statistic that
|
||
covers all subnets.
|
||
</entry>
|
||
</row>
|
||
|
||
<row>
|
||
<entry>subnet[id].reclaimed-declined-addresses</entry>
|
||
<entry>integer</entry>
|
||
<entry>
|
||
This statistic shows the number of IPv6 addresses that were
|
||
declined, but have now been recovered. Unlike
|
||
declined-addresses, this statistic never decreases. It can be used
|
||
as a long term indicator of how many actual valid Declines were
|
||
processed and recovered from. The
|
||
<emphasis>id</emphasis> is the subnet-id of a given subnet. This
|
||
statistic is exposed for each subnet separately.
|
||
</entry>
|
||
</row>
|
||
|
||
</tbody>
|
||
</tgroup>
|
||
</table>
|
||
</section>
|
||
|
||
<section xml:id="dhcp6-ctrl-channel">
|
||
<title>Management API for the DHCPv6 Server</title>
|
||
<para>
|
||
The management API allows the issuing of specific
|
||
management commands, such as statistics retrieval, reconfiguration or shutdown.
|
||
For more details, see <xref linkend="ctrl-channel"/>. Currently the only
|
||
supported communication channel type is UNIX stream socket. By default there
|
||
are no sockets open. To instruct Kea to open a socket, the following entry
|
||
in the configuration file can be used:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"control-socket": {
|
||
"socket-type": "unix",
|
||
"socket-name": <userinput>"/path/to/the/unix/socket"</userinput>
|
||
},
|
||
|
||
"subnet6": [
|
||
...
|
||
],
|
||
...
|
||
}
|
||
</screen>
|
||
</para>
|
||
|
||
<para>
|
||
The length of the path specified by the <command>socket-name</command>
|
||
parameter is restricted by the maximum length for the unix socket name
|
||
on your operating system, i.e. the size of the <command>sun_path</command>
|
||
field in the <command>sockaddr_un</command> structure, decreased by 1.
|
||
This value varies on different operating systems between 91 and 107
|
||
characters. Typical values are 107 on Linux and 103 on FreeBSD.
|
||
</para>
|
||
|
||
<para>
|
||
Communication over control channel is conducted using JSON structures.
|
||
See the Control Channel section in the Kea Developer's Guide for more details.
|
||
</para>
|
||
|
||
<para>The DHCPv6 server supports the following operational commands:
|
||
<itemizedlist>
|
||
<listitem>build-report</listitem>
|
||
<listitem>config-get</listitem>
|
||
<listitem>config-reload</listitem>
|
||
<listitem>config-set</listitem>
|
||
<listitem>config-test</listitem>
|
||
<listitem>config-write</listitem>
|
||
<listitem>dhcp-disable</listitem>
|
||
<listitem>dhcp-enable</listitem>
|
||
<listitem>leases-reclaim</listitem>
|
||
<listitem>list-commands</listitem>
|
||
<listitem>shutdown</listitem>
|
||
<listitem>version-get</listitem>
|
||
</itemizedlist>
|
||
as described in <xref linkend="commands-common"/>. In addition,
|
||
it supports the following statistics related commands:
|
||
<itemizedlist>
|
||
<listitem>statistic-get</listitem>
|
||
<listitem>statistic-reset</listitem>
|
||
<listitem>statistic-remove</listitem>
|
||
<listitem>statistic-get-all</listitem>
|
||
<listitem>statistic-reset-all</listitem>
|
||
<listitem>statistic-remove-all</listitem>
|
||
</itemizedlist>
|
||
as described here <xref linkend="command-stats"/>.
|
||
</para>
|
||
|
||
</section>
|
||
|
||
<section id="dhcp6-user-contexts">
|
||
<title>User contexts in IPv6</title>
|
||
<para>
|
||
Kea allows loading hook libraries that sometimes could benefit from
|
||
additional parameters. If such a parameter is specific to the whole
|
||
library, it is typically defined as a parameter for the hook library.
|
||
However, sometimes there is a need to specify parameters that are
|
||
different for each pool.
|
||
</para>
|
||
|
||
<para>
|
||
User contexts can store arbitrary data as long as it is valid JSON
|
||
syntax and its top level element is a map (i.e. the data must be
|
||
enclosed in curly brackets). Some hook libraries may expect specific
|
||
formatting, though. Please consult specific hook library
|
||
documentation for details.
|
||
</para>
|
||
|
||
<para>
|
||
User contexts can be specified at either global scope,
|
||
shared network, subnet, pool, client class, option data or
|
||
definition level, and host reservation. One other useful
|
||
usage is the ability to store comments or descriptions.
|
||
</para>
|
||
|
||
<para>
|
||
Let's consider a lightweight 4over6 deployment as an example. It is an
|
||
IPv6 transition technology that allows mapping IPv6 prefix into full
|
||
or parts of IPv4 addresses. In DHCP context, these are certain
|
||
parameters that are supposed to be delivered to clients in form of
|
||
additional options. Values of those options are correlated to
|
||
delegated prefixes, so it is reasonable to keep those parameters
|
||
together with the PD pool. On the other hand, lightweight 4over6 is
|
||
not a commonly used feature, so it is not a part of the base Kea
|
||
code. The solution to this problem is to use user context. For each PD
|
||
pool that is expected to be used for lightweight 4over6, user context
|
||
with extra parameters is defined. Those extra parameters will be used
|
||
by hook library that would be loaded only when dynamic calculation of
|
||
the lightweight 4over6 option is actually needed. An example
|
||
configuration looks as follows:
|
||
<screen>
|
||
"Dhcp6": {
|
||
"subnet6": [ {
|
||
"pd-pools": [
|
||
{
|
||
"prefix": "2001:db8::",
|
||
"prefix-len": 56,
|
||
"delegated-len": 64,
|
||
|
||
// This is a pool specific context.
|
||
<userinput>"user-context": {
|
||
"threshold-percent": 85,
|
||
"v4-network": "192.168.0.0/16",
|
||
"v4-overflow": "10.0.0.0/16",
|
||
"lw4over6-sharing-ratio": 64,
|
||
"lw4over6-v4-pool": "192.0.2.0/24",
|
||
"lw4over6-sysports-exclude": true,
|
||
"lw4over6-bind-prefix-len": 56
|
||
}</userinput>
|
||
} ],
|
||
"subnet": "2001:db8::/32",
|
||
|
||
// This is a subnet specific context. You can put any type of
|
||
// information here as long as it is a valid JSON.
|
||
<userinput>"user-context": {
|
||
"comment": "Those v4-v6 migration technologies are tricky.",
|
||
"experimental": true,
|
||
"billing-department": 42,
|
||
"contact-points": [ "Alice", "Bob" ]
|
||
}</userinput>
|
||
} ],
|
||
...
|
||
}</screen>
|
||
</para>
|
||
|
||
<para>
|
||
Kea does not interpret or use the content of the user context:
|
||
it just stores it, making it available to the hook
|
||
libraries. It is up to each hook library to extract the information
|
||
and make use of it.
|
||
The parser translates a "comment" entry into a user-context
|
||
with the entry, this allows to attach a comment inside the
|
||
configuration itself.
|
||
</para>
|
||
<para>
|
||
For more background information, see <xref linkend="user-context"/>.
|
||
</para>
|
||
</section>
|
||
|
||
<section xml:id="dhcp6-std">
|
||
<title>Supported DHCPv6 Standards</title>
|
||
<para>The following standards are currently
|
||
supported:</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<simpara><emphasis>Dynamic Host Configuration Protocol for IPv6</emphasis>,
|
||
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc3315">RFC 3315</link>:
|
||
Supported messages are SOLICIT,
|
||
ADVERTISE, REQUEST, RELEASE, RENEW, REBIND, INFORMATION-REQUEST,
|
||
CONFIRM and REPLY.</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara><emphasis>IPv6 Prefix Options for
|
||
Dynamic Host Configuration Protocol (DHCP) version 6</emphasis>,
|
||
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc3633">RFC 3633</link>:
|
||
Supported options are IA_PD and
|
||
IA_PREFIX. Also supported is the status code NoPrefixAvail.</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara><emphasis>DNS Configuration options for Dynamic Host
|
||
Configuration Protocol for IPv6 (DHCPv6)</emphasis>,
|
||
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc3646">RFC 3646</link>:
|
||
Supported option is DNS_SERVERS.</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara><emphasis>The Dynamic Host Configuration Protocol for IPv6 (DHCPv6)
|
||
Relay Agent Remote-ID Option</emphasis>,
|
||
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc4649">RFC 4649</link>:
|
||
REMOTE-ID option is supported.</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara><emphasis>The Dynamic Host Configuration Protocol for IPv6 (DHCPv6) Client
|
||
Fully Qualified Domain Name (FQDN) Option</emphasis>,
|
||
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc4704">RFC 4704</link>:
|
||
Supported option is CLIENT_FQDN.</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara><emphasis>Dynamic Host Configuration Protocol for IPv6 (DHCPv6)
|
||
Option for Dual-Stack Lite</emphasis>,
|
||
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc6334">RFC 6334</link>:
|
||
the AFTR-Name DHCPv6 Option is supported.</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara><emphasis>Relay-Supplied DHCP Options</emphasis>,
|
||
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc6422">RFC 6422</link>:
|
||
Full functionality is supported: OPTION_RSOO, ability of the server
|
||
to echo back the options, checks whether an option is RSOO-enabled,
|
||
ability to mark additional options as RSOO-enabled.</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara><emphasis>Prefix Exclude Option for DHCPv6-based Prefix
|
||
Delegation</emphasis>,
|
||
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc6603">RFC
|
||
6603</link>: Prefix Exclude option is supported.</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara><emphasis>Client Link-Layer Address Option in
|
||
DHCPv6</emphasis>,
|
||
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc6939">RFC
|
||
6939</link>: Supported option is client link-layer
|
||
address option.</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara><emphasis>Issues and Recommendations with Multiple
|
||
Stateful DHCPv6 Options</emphasis>,
|
||
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc7550">RFC
|
||
7550</link>: All recommendations related to the DHCPv6 server
|
||
operation are supported.</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara><emphasis>DHCPv6 Options for Configuration of Softwire
|
||
Address and Port-Mapped Clients</emphasis>,
|
||
<ulink url="http://tools.ietf.org/html/rfc7598">RFC
|
||
7598</ulink>: All options specified in this specification are
|
||
supported by the DHCPv6 server.</simpara>
|
||
</listitem>
|
||
<listitem>
|
||
<simpara><emphasis>Dynamic Host Configuration Protocol for IPv6 (DHCPv6)</emphasis>,
|
||
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc8415">RFC 8415</link>:
|
||
New DHCPv6 protocol specification which obsoletes RFC 3315, RFC 3633, RFC 3736, RFC 4242, RFC 7083,
|
||
RFC 7283 and RFC 7550</simpara>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</section>
|
||
|
||
<section xml:id="dhcp6-limit">
|
||
<title>DHCPv6 Server Limitations</title>
|
||
<para> These are the current limitations of the DHCPv6 server
|
||
software. Most of them are reflections of the early stage of
|
||
development and should be treated as <quote>not implemented
|
||
yet</quote>, rather than actual limitations.</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<simpara>
|
||
The server will allocate, renew or rebind a maximum of one lease
|
||
for a particular IA option (IA_NA or IA_PD) sent by a client.
|
||
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://tools.ietf.org/html/rfc8415">RFC 8415</link>
|
||
allows for multiple addresses or prefixes to be allocated for a single IA.
|
||
</simpara>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<simpara>Temporary addresses are not supported.</simpara>
|
||
</listitem>
|
||
|
||
<listitem>
|
||
<simpara>
|
||
Client reconfiguration (RECONFIGURE) is not yet supported.
|
||
</simpara>
|
||
</listitem>
|
||
</itemizedlist>
|
||
</section>
|
||
|
||
<section id="dhcp6-srv-examples">
|
||
<title>Kea DHCPv6 server examples</title>
|
||
|
||
<para>
|
||
A collection of simple to use examples for DHCPv6 component of Kea is
|
||
available with the sources. It is located in doc/examples/kea6
|
||
directory. At the time of writing this text there were 18 examples,
|
||
but the number is growing slowly with each release.
|
||
</para>
|
||
|
||
</section>
|
||
|
||
</chapter>
|