// This optional parameter can be used to specify a common
// prefix for files handling client credentials.
- "directory": "/tmp/kea-creds",
+ "directory": "/usr/local/share/kea/kea-creds",
// This list specifies the user ids and passwords to use for
// basic HTTP authentication. If empty or not present any client
"password": "1234"
},
- // This specifies a hiddent client.
+ // This specifies a hidden client.
{
- // The user id is the content of the file /tmp/kea-creds/hiddenu.
+ // The user id is the content of the file /usr/local/share/kea/kea-creds/hiddenu.
"user-file": "hiddenu",
- // The password is the content of the file /tmp/kea-creds/hiddenp.
+ // The password is the content of the file /usr/local/share/kea/kea-creds/hiddenp.
"password-file": "hiddenp"
},
// This specifies a hidden client using a secret in a file.
{
- // The secret is the content of the file /tmp/kea-creds/hiddens
+ // The secret is the content of the file /usr/local/share/kea/kea-creds/hiddens
// which must be in the <user-id>:<password> format.
"password-file": "hiddens"
}
"name": "kea-ctrl-agent",
"output-options": [
{
- "output": "/var/log/kea-ctrl-agent.log",
+ "output": "/var/log/kea/kea-ctrl-agent.log",
// Several additional parameters are possible in addition
// to the typical output. Flush determines whether logger
// flushes output to a file. Maxsize determines maximum
// An alternative to secret: specify a file where the secret
// can be found. i.e. the secret is the content of the file.
- "secret-file": "/tmp/d2-sha1-secret"
+ "secret-file": "/usr/local/share/kea/d2-sha1-secret"
}
],
{
"name": "d2.sha256.key",
"algorithm": "HMAC-SHA256",
- "secret-file": "/tmp/d2-sha256-secret"
+ "secret-file": "/usr/local/share/kea/d2-sha256-secret"
},
{
"name": "d2.sha512.key",
"client-classes": [
{
// Class-specific bootfile name to be set in the 'file' field.
- "boot-file-name": "/tmp/bootfile.efi",
+ "boot-file-name": "/usr/local/share/kea/bootfile.efi",
// Class name.
"name": "phones_server1",
"client-classes": [
{
// Class-specific bootfile name to be set in the 'file' field.
- "boot-file-name": "/tmp/bootfile.efi",
+ "boot-file-name": "/usr/local/share/kea/bootfile.efi",
// Class name.
"name": "phones_server1",
<interfaces>eth1</interfaces>
</interfaces-config>
<control-socket>
- <socket-name>/tmp/kea6-ctrl-socket</socket-name>
+ <socket-name>kea6-ctrl-socket</socket-name>
<socket-type>unix</socket-type>
</control-socket>
</config>
<interfaces>eth1</interfaces>
</interfaces-config>
<control-socket>
- <socket-name>/tmp/kea6-ctrl-socket</socket-name>
+ <socket-name>kea6-ctrl-socket</socket-name>
<socket-type>unix</socket-type>
</control-socket>
</config>
<interfaces>eth1</interfaces>
</interfaces-config>
<control-socket>
- <socket-name>/tmp/kea6-ctrl-socket</socket-name>
+ <socket-name>kea6-ctrl-socket</socket-name>
<socket-type>unix</socket-type>
</control-socket>
<user-context>bad</user-context>
"Dhcp6": {
"control-socket": {
"socket-type": "unix",
- "socket-name": "/tmp/kea6-ctrl-socket"
+ "socket-name": "kea6-ctrl-socket"
}
}
}
<subnet>2001:db8::/64</subnet>
</subnet6>
<control-socket>
- <socket-name>/tmp/kea6-ctrl-socket</socket-name>
+ <socket-name>kea6-ctrl-socket</socket-name>
<socket-type>unix</socket-type>
</control-socket>
<logger>
"control-socket":
{
"socket-type": "unix",
- "socket-name": "/tmp/kea6-ctrl-socket"
+ "socket-name": "kea6-ctrl-socket"
}
}
},
<interfaces>eth1</interfaces>
</interfaces-config>
<control-socket>
- <socket-name>/tmp/kea6-ctrl-socket</socket-name>
+ <socket-name>kea6-ctrl-socket</socket-name>
<socket-type>unix</socket-type>
</control-socket>
</config>
<interfaces>eth1</interfaces>
</interfaces-config>
<control-socket>
- <socket-name>/tmp/kea6-ctrl-socket</socket-name>
+ <socket-name>kea6-ctrl-socket</socket-name>
<socket-type>unix</socket-type>
</control-socket>
</config>
<interfaces>eth1</interfaces>
</interfaces-config>
<control-socket>
- <socket-name>/tmp/kea6-ctrl-socket</socket-name>
+ <socket-name>kea6-ctrl-socket</socket-name>
<socket-type>unix</socket-type>
</control-socket>
</config>
{
"comment": "socket to DHCPv4 server",
"socket-type": "unix",
- "socket-name": "/tmp/kea4-ctrl-socket"
+ "socket-name": "kea4-ctrl-socket"
},
// Location of the DHCPv6 command channel socket.
"dhcp6":
{
"socket-type": "unix",
- "socket-name": "/tmp/kea6-ctrl-socket"
+ "socket-name": "kea6-ctrl-socket"
},
// Location of the D2 command channel socket.
"d2":
{
"socket-type": "unix",
- "socket-name": "/tmp/kea-ddns-ctrl-socket",
+ "socket-name": "kea-ddns-ctrl-socket",
"user-context": { "in-use": false }
}
},
{
"comment": "socket to DHCPv4 server",
"socket-type": "unix",
- "socket-name": "/tmp/kea4-ctrl-socket"
+ "socket-name": "kea4-ctrl-socket"
},
// Location of the DHCPv6 command channel socket.
"dhcp6":
{
"socket-type": "unix",
- "socket-name": "/tmp/kea6-ctrl-socket"
+ "socket-name": "kea6-ctrl-socket"
},
// Location of the D2 command channel socket.
"d2":
{
"socket-type": "unix",
- "socket-name": "/tmp/kea-ddns-ctrl-socket",
+ "socket-name": "kea-ddns-ctrl-socket",
"user-context": { "in-use": false }
}
},
// API between the HA peers.
"control-socket": {
"socket-type": "unix",
- "socket-name": "/tmp/kea4-ctrl-socket"
+ "socket-name": "kea4-ctrl-socket"
},
// Multi-threading parameters.
// API between the HA peers.
"control-socket": {
"socket-type": "unix",
- "socket-name": "/tmp/kea4-ctrl-socket"
+ "socket-name": "kea4-ctrl-socket"
},
// Multi-threading parameters.
{
"comment": "socket to DHCPv4 server",
"socket-type": "unix",
- "socket-name": "/tmp/kea4-ctrl-socket"
+ "socket-name": "kea4-ctrl-socket"
},
// Location of the DHCPv6 command channel socket.
"dhcp6":
{
"socket-type": "unix",
- "socket-name": "/tmp/kea6-ctrl-socket"
+ "socket-name": "kea6-ctrl-socket"
},
// Location of the D2 command channel socket.
"d2":
{
"socket-type": "unix",
- "socket-name": "/tmp/kea-ddns-ctrl-socket",
+ "socket-name": "kea-ddns-ctrl-socket",
"user-context": { "in-use": false }
}
},
{
"comment": "socket to DHCPv4 server",
"socket-type": "unix",
- "socket-name": "/tmp/kea4-ctrl-socket"
+ "socket-name": "kea4-ctrl-socket"
},
// Location of the DHCPv6 command channel socket.
"dhcp6":
{
"socket-type": "unix",
- "socket-name": "/tmp/kea6-ctrl-socket"
+ "socket-name": "kea6-ctrl-socket"
},
// Location of the D2 command channel socket.
"d2":
{
"socket-type": "unix",
- "socket-name": "/tmp/kea-ddns-ctrl-socket",
+ "socket-name": "kea-ddns-ctrl-socket",
"user-context": { "in-use": false }
}
},
// API between the HA peers.
"control-socket": {
"socket-type": "unix",
- "socket-name": "/tmp/kea4-ctrl-socket"
+ "socket-name": "kea4-ctrl-socket"
},
// Use Memfile lease database backend to store leases in a CSV file.
// API between the HA peers.
"control-socket": {
"socket-type": "unix",
- "socket-name": "/tmp/kea4-ctrl-socket"
+ "socket-name": "kea4-ctrl-socket"
},
// Use Memfile lease database backend to store leases in a CSV file.
.. note::
As of Kea 2.6.3, control sockets may only reside in the directory
- determined during compilation as ``"[kea-install-dir]/var/run/kea"``. This
- path may be overridden at startup by setting the environment variable
- ``KEA_CONTROL_SOCKET_DIR`` to the desired path. If a path other than
- this value is used in ``socket-name``, Kea will emit an error and refuse to
- start or, if already running, log an unrecoverable error. For ease of use in
- simply omit the path component from ``socket-name``.
+ determined during compilation as ``"[kea-install-dir]/var/run/kea"``,
+ which must also have ``0750`` access rights. This path may be overridden
+ at startup by setting the environment variable ``KEA_CONTROL_SOCKET_DIR``
+ to the desired path. If a path other than this value is used in
+ ``socket-name``, Kea will emit an error and refuse to start or, if already
+ running, log an unrecoverable error. For ease of use in simply omit the
+ path component from ``socket-name``.
User contexts can store arbitrary data as long as they are in valid JSON
syntax and their top-level element is a map (i.e. the data must be
When the ``clients`` authentication list is configured and not empty,
basic HTTP authentication is required. Each element of the list
specifies a user ID and a password. The user ID is mandatory, must
-be not empty, and must not contain the colon (:) character. The
+not be empty, and must not contain the colon (:) character. The
password is optional; when it is not specified an empty password
is used.
Secure Connections
==================
-The Kea Control Agent natively supports secure
-HTTP connections using TLS. This allows protection against users from
-the node where the agent runs, something that a reverse proxy cannot
-provide. More about TLS/HTTPS support in Kea can be found in :ref:`tls`.
-
-TLS is configured using three string parameters with file names, and
-a boolean parameter:
-
-- The ``trust-anchor`` specifies the Certification Authority file name or
- directory path.
-
-- The ``cert-file`` specifies the server certificate file name.
-
-- The ``key-file`` specifies the private key file name. The file must not
- be encrypted.
-
-- The ``cert-required`` specifies whether client certificates are required
- or optional. The default is to require them and to perform mutual
- authentication.
-
-The file format is PEM. Either all the string parameters are specified and
-HTTP over TLS (HTTPS) is used, or none is specified and plain HTTP is used.
-Configuring only one or two string parameters results in an error.
-
-.. note::
-
- When client certificates are not required, only the server side is
- authenticated, i.e. the communication is encrypted with an unknown
- client. This protects only against passive attacks; active
- attacks, such as "man-in-the-middle," are still possible.
-
-.. note::
-
- No standard HTTP authentication scheme cryptographically binds its end
- entity with TLS. This means that the TLS client and server can be
- mutually authenticated, but there is no proof they are the same as
- for the HTTP authentication.
-
-The :iscman:`kea-shell` tool also supports TLS.
+Configuration options related to Kea Control Agent security can be found in the
+:ref:`secure-control-agent` section.
.. _agent-launch:
.. note::
As of Kea 2.6.3, control sockets may only reside in the directory
- determined during compilation as ``"[kea-install-dir]/var/run/kea"``. This
- path may be overridden at startup by setting the environment variable
- ``KEA_CONTROL_SOCKET_DIR`` to the desired path. If a path other than
- this value is used in ``socket-name``, Kea will emit an error and refuse to
- start or, if already running, log an unrecoverable error. For ease of use in
- simply omit the path component from ``socket-name``.
+ determined during compilation as ``"[kea-install-dir]/var/run/kea"``,
+ which must also have ``0750`` access rights. This path may be overridden
+ at startup by setting the environment variable ``KEA_CONTROL_SOCKET_DIR``
+ to the desired path. If a path other than this value is used in
+ ``socket-name``, Kea will emit an error and refuse to start or, if already
+ running, log an unrecoverable error. For ease of use in simply omit the
+ path component from ``socket-name``.
Communication over the control channel is conducted using JSON structures.
See the `Control Channel section in the Kea Developer's
"lease-database": {
"type": "memfile",
"persist": true,
- "name": "/tmp/kea-leases4.csv",
+ "name": "kea-leases4.csv",
"lfc-interval": 1800,
"max-row-errors": 100
}
}
-This configuration selects ``/tmp/kea-leases4.csv`` as the storage
+This configuration selects ``kea-leases4.csv`` as the storage
for lease information and enables persistence (writing lease updates to
this file). It also configures the backend to perform a periodic cleanup
of the lease file every 1800 seconds (30 minutes) and sets the maximum number of
"name": "kea-dhcp4",
"output-options": [
{
- "output": "/tmp/kea-dhcp4.log"
+ "output": "kea-dhcp4.log"
}
],
"severity": "DEBUG",
"hw-address": "aa:bb:cc:dd:ee:ff",
"next-server": "10.1.1.2",
"server-hostname": "server-hostname.example.org",
- "boot-file-name": "/tmp/bootfile.efi"
+ "boot-file-name": "/usr/local/share/kea/bootfile.efi"
}
],
...
.. note::
As of Kea 2.6.3, control sockets may only reside in the directory
- determined during compilation as ``"[kea-install-dir]/var/run/kea"``. This
- path may be overridden at startup by setting the environment variable
- ``KEA_CONTROL_SOCKET_DIR`` to the desired path. If a path other than
- this value is used in ``socket-name``, Kea will emit an error and refuse to
- start or, if already running, log an unrecoverable error. For ease of use in
- simply omit the path component from ``socket-name``.
+ determined during compilation as ``"[kea-install-dir]/var/run/kea"``,
+ which must also have ``0750`` access rights. This path may be overridden
+ at startup by setting the environment variable ``KEA_CONTROL_SOCKET_DIR``
+ to the desired path. If a path other than this value is used in
+ ``socket-name``, Kea will emit an error and refuse to start or, if already
+ running, log an unrecoverable error. For ease of use in simply omit the
+ path component from ``socket-name``.
Communication over the control channel is conducted using JSON
structures. See the
"lease-database": {
"type": "memfile",
"persist": true,
- "name": "/tmp/kea-leases6.csv",
+ "name": "kea-leases6.csv",
"lfc-interval": 1800,
"max-row-errors": 100
}
}
-This configuration selects ``/tmp/kea-leases6.csv`` as the storage file
+This configuration selects ``kea-leases6.csv`` as the storage file
for lease information and enables persistence (writing lease updates to
this file). It also configures the backend to perform a periodic cleanup
of the lease file every 1800 seconds (30 minutes) and sets the maximum number of
"loggers": [ {
"name": "kea-dhcp6",
"output-options": [ {
- "output": "/tmp/kea-dhcp6.log"
+ "output": "kea-dhcp6.log"
} ],
"severity": "DEBUG",
"debuglevel": 0
::
"Dhcp6": {
- "data-directory": "/var/tmp/kea-server6",
+ "data-directory": "/var/lib/kea/kea-server6",
...
}
.. note::
As of Kea 2.6.3, control sockets may only reside in the directory
- determined during compilation as ``"[kea-install-dir]/var/run/kea"``. This
- path may be overridden at startup by setting the environment variable
- ``KEA_CONTROL_SOCKET_DIR`` to the desired path. If a path other than
- this value is used in ``socket-name``, Kea will emit an error and refuse to
- start or, if already running, log an unrecoverable error. For ease of use in
- simply omit the path component from ``socket-name``.
+ determined during compilation as ``"[kea-install-dir]/var/run/kea"``,
+ which must also have ``0750`` access rights. This path may be overridden
+ at startup by setting the environment variable ``KEA_CONTROL_SOCKET_DIR``
+ to the desired path. If a path other than this value is used in
+ ``socket-name``, Kea will emit an error and refuse to start or, if already
+ running, log an unrecoverable error. For ease of use in simply omit the
+ path component from ``socket-name``.
Communication over the control channel is conducted using JSON
structures. See the
.. code-block:: console
- kadmin.local -q "ktadd -k /tmp/dns.keytab DNS/server.example.org"
+ kadmin.local -q "ktadd -k /usr/local/share/kea/dns.keytab DNS/server.example.org"
If successfully exported, the following message is displayed:
.. code-block:: console
Authenticating as principal root/admin@EXAMPLE.ORG with password.
- Entry for principal DNS/server.example.org with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/tmp/dns.keytab.
- Entry for principal DNS/server.example.org with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:/tmp/dns.keytab.
+ Entry for principal DNS/server.example.org with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/usr/local/share/kea/dns.keytab.
+ Entry for principal DNS/server.example.org with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:/usr/local/share/kea/dns.keytab.
The DHCP client principal (used by the Kea DHCP-DDNS server) is created the
following way:
.. code-block:: console
- kadmin.local -q "ktadd -k /tmp/dhcp.keytab DHCP/admin.example.org"
+ kadmin.local -q "ktadd -k /usr/local/share/kea/dhcp.keytab DHCP/admin.example.org"
Finally, the ``krb5-admin-server`` must be restarted:
.. code-block:: console
- kinit -k -t /tmp/dhcp.keytab DHCP/admin.example.org
+ kinit -k -t /usr/local/share/kea/dhcp.keytab DHCP/admin.example.org
or, when using AD:
.. code-block:: console
- kinit -k -t /tmp/dhcp.keytab DHCP/kea.<domain>
+ kinit -k -t /usr/local/share/kea/dhcp.keytab DHCP/kea.<domain>
The credential cache can be displayed using ``klist``.
{
"Dhcp4": {
"control-socket": {
- "socket-name": "/tmp/kea-dhcp4-ctrl.sock",
+ "socket-name": "kea-dhcp4-ctrl.sock",
"socket-type": "unix"
}
}
"control-socket":
{
"socket-type": "unix",
- "socket-name": "/tmp/kea4-ctrl-socket"
+ "socket-name": "kea4-ctrl-socket"
}
},
"control-socket":
{
"socket-type": "unix",
- "socket-name": "/tmp/kea6-ctrl-socket"
+ "socket-name": "kea6-ctrl-socket"
}
},
{
"Dhcp6": {
"control-socket": {
- "socket-name": "/tmp/kea-dhcp6-ctrl.sock",
+ "socket-name": "kea-dhcp6-ctrl.sock",
"socket-type": "unix"
}
}
.. code-block:: console
- # echo '{ "command": "config-get" }' | socat UNIX:/tmp/kea-dhcp6-ctrl.sock '-,ignoreeof'
+ # echo '{ "command": "config-get" }' | socat UNIX:/opt/kea/var/run/kea/kea-dhcp6-ctrl.sock '-,ignoreeof'
The following is the example ``netconf.json`` configuration for
:iscman:`kea-netconf`, to manage the Kea DHCPv6 server:
"managed-servers": {
"dhcp6": {
"control-socket": {
- "socket-name": "/tmp/kea-dhcp6-ctrl.sock",
+ "socket-name": "kea-dhcp6-ctrl.sock",
"socket-type": "unix"
}
}
<interfaces>eth1</interfaces>
</interfaces-config>
<control-socket>
- <socket-name>/tmp/kea-dhcp6-ctrl.sock</socket-name>
+ <socket-name>kea-dhcp6-ctrl.sock</socket-name>
<socket-type>unix</socket-type>
</control-socket>
</config>
<interfaces>eth1</interfaces>
</interfaces-config>
<control-socket>
- <socket-name>/tmp/kea-dhcp6-ctrl.sock</socket-name>
+ <socket-name>kea-dhcp6-ctrl.sock</socket-name>
<socket-type>unix</socket-type>
</control-socket>
</config>
<interfaces>eth1</interfaces>
</interfaces-config>
<control-socket>
- <socket-name>/tmp/kea-dhcp6-ctrl.sock</socket-name>
+ <socket-name>kea-dhcp6-ctrl.sock</socket-name>
<socket-type>unix</socket-type>
</control-socket>
<user-context>bad</user-context>
<interfaces>eth1</interfaces>
</interfaces-config>
<control-socket>
- <socket-name>/tmp/kea-dhcp6-ctrl.sock</socket-name>
+ <socket-name>kea-dhcp6-ctrl.sock</socket-name>
<socket-type>unix</socket-type>
</control-socket>
</config>
<interfaces>eth1</interfaces>
</interfaces-config>
<control-socket>
- <socket-name>/tmp/kea-dhcp6-ctrl.sock</socket-name>
+ <socket-name>kea-dhcp6-ctrl.sock</socket-name>
<socket-type>unix</socket-type>
</control-socket>
</config>
<interfaces>eth1</interfaces>
</interfaces-config>
<control-socket>
- <socket-name>/tmp/kea-dhcp6-ctrl.sock</socket-name>
+ <socket-name>kea-dhcp6-ctrl.sock</socket-name>
<socket-type>unix</socket-type>
</control-socket>
</config>
<subnet>2001:db8::/64</subnet>
</subnet6>
<control-socket>
- <socket-name>/tmp/kea-dhcp6-ctrl.sock</socket-name>
+ <socket-name>kea-dhcp6-ctrl.sock</socket-name>
<socket-type>unix</socket-type>
</control-socket>
<logger>
{
"Dhcp6": {
"control-socket": {
- "socket-name": "/tmp/kea-dhcp6-ctrl.sock",
+ "socket-name": "kea-dhcp6-ctrl.sock",
"socket-type": "unix"
},
"interfaces-config": {
"control-sockets": {
"dhcp4": {
"socket-type": "unix",
- "socket-name": "/tmp/kea-dhcp4-ctrl.sock"
+ "socket-name": "kea-dhcp4-ctrl.sock"
},
"dhcp6": {
"socket-type": "unix",
- "socket-name": "/tmp/kea-dhcp6-ctrl.sock"
+ "socket-name": "kea-dhcp6-ctrl.sock"
}
}
}
{
"command": "cache-load",
- "arguments": "/tmp/kea-host-cache.json"
+ "arguments": "/usr/local/share/kea/kea-host-cache.json"
}
-This command stores the contents to the ``/tmp/kea-host-cache.json``
+This command stores the contents to the ``/usr/local/share/kea/kea-host-cache.json``
file. That file can then be loaded with the :isccmd:`cache-load` command or
processed by any other tool that is able to understand JSON format.
determined during compilation: ``"[kea-install-dir]/var/lib/kea"``. This
path may be overridden at startup by setting the environment variable
``KEA_DHCP_DATA_DIRECTORY`` to the desired path. If a path other than
- this value is used in ``name``, Kea will emit an error and refuse to start
+ this value is used in ``filename``, Kea will emit an error and refuse to start
or, if already running, log an unrecoverable error. For ease of use in
specifying a custom file name simply omit the path portion from ``filename``.
to consult an external source of information about clients and alter
Kea's behavior remains useful and of educational value.
-The library reads the ``/tmp/user_chk_registry.txt`` file while being loaded
+The library reads the ``/usr/local/share/kea/user_chk_registry.txt`` file while being loaded
and each time an incoming packet is processed. Each line of the file is expected to
contain a self-contained JSON snippet which must have the
following two entries:
::
- { "type" : "HW_ADDR", "id" : "0c:0e:0a:01:ff:04", "bootfile" : "/tmp/v4bootfile" }
+ { "type" : "HW_ADDR", "id" : "0c:0e:0a:01:ff:04", "bootfile" : "/usr/local/share/kea/v4bootfile" }
{ "type" : "HW_ADDR", "id" : "0c:0e:0a:01:ff:06", "tftp_server" : "tftp.v4.example.com" }
- { "type" : "DUID", "id" : "00:01:00:01:19:ef:e6:3b:00:0c:01:02:03:04", "bootfile" : "/tmp/v6bootfile" }
+ { "type" : "DUID", "id" : "00:01:00:01:19:ef:e6:3b:00:0c:01:02:03:04", "bootfile" : "/usr/local/share/kea/v6bootfile" }
{ "type" : "DUID", "id" : "00:01:00:01:19:ef:e6:3b:00:0c:01:02:03:06", "tftp_server" : "tftp.v6.example.com" }
As with any other hook libraries provided by ISC, internals of the
the two security mechanisms, and therefore no proof that the TLS client and server
are the same as the HTTP authentication client and server.
+.. note::
+
+ It is recommend to use privileged ports for HTTP/HTTPS against local attacks
+ (by users which are connected to the box where Kea servers/agents run). This
+ measure also prevents against impersonation with HTTP, and Denial of
+ Service in general.
+
.. _tls_config:
Building Kea with TLS/HTTPS Support
It is highly recommended to read the ``openssl.cnf`` manual page,
normally called ``config.5ssl`` and displayed using ``man config``.
+.. _secure-control-agent:
+
+Secure Kea Control Agent
+========================
+
+The Kea Control Agent natively supports secure
+HTTP connections using TLS. This allows protection against users from
+the node where the agent runs, something that a reverse proxy cannot
+provide. More about TLS/HTTPS support in Kea can be found in :ref:`tls`.
+
+TLS is configured using three string parameters with file names, and
+a boolean parameter:
+
+- The ``trust-anchor`` specifies the Certification Authority file name or
+ directory path.
+
+- The ``cert-file`` specifies the server certificate file name.
+
+- The ``key-file`` specifies the private key file name. The file must not
+ be encrypted.
+
+- The ``cert-required`` specifies whether client certificates are required
+ or optional. The default is to require them and to perform mutual
+ authentication.
+
+The file format is PEM. Either all the string parameters are specified and
+HTTP over TLS (HTTPS) is used, or none is specified and plain HTTP is used.
+Configuring only one or two string parameters results in an error.
+
+.. note::
+
+ When client certificates are not required, only the server side is
+ authenticated, i.e. the communication is encrypted with an unknown
+ client. This protects only against passive attacks; active
+ attacks, such as "man-in-the-middle," are still possible.
+
+.. note::
+
+ No standard HTTP authentication scheme cryptographically binds its end
+ entity with TLS. This means that the TLS client and server can be
+ mutually authenticated, but there is no proof they are the same as
+ for the HTTP authentication.
+
+The :iscman:`kea-shell` tool also supports TLS.
+
Securing a Kea Deployment
=========================
A Kea deployment may include DHCPv4, DHCPv6, and Dynamic DNS daemons; a Control Agent
daemon run on each application server; the ``kea-lfc utility`` for doing periodic lease
file cleanup; MySQL and or PostgreSQL databases, run either locally on the application
-servers or accessed over the internal network; and a Stork monitoring system.
+servers or accessed over the internal network; a Netconf daemon to perform config and stats
+monitoring of Kea servers; and a Stork monitoring system.
This modular architecture allows the administrator to minimize the attack surface
by minimizing the code that is loaded and running.
For example, :iscman:`kea-dhcp-ddns` should not be run unless DNS updates are required.
Similarly, :iscman:`kea-lfc` is never triggered (and can be safely removed or never installed) if memfile is not used.
Potential Kea security issues can be minimized by running only those processes required in the local environment.
+.. note::
+
+ As of Kea 2.6.3, the lease files (DHCPv4 and DHCPv6) and duid file (DHCPv6 only)
+ may only be loaded from the directory determined at compilation:
+ ``"[kea-install-dir]/var/lib/kea"``.
+ This path may be overridden at startup by setting the environment variable
+ ``KEA_DHCP_DATA_DIRECTORY`` to the desired path. If a path other than
+ this value is used in ``name`` or ``data-directory``, Kea will emit an error and
+ refuse to start or, if already running, log an unrecoverable error.
+ This restriction applies to writing lease file using ``lease4-write`` and
+ ``lease6-write`` commands. If a path other than this value is used in ``filename``,
+ Kea will emit an error and refuse to start or, if already running, log an
+ unrecoverable error. For ease of use in specifying a custom file name simply
+ omit the path portion from ``filename``.
+
Limiting Application Permissions
--------------------------------
to run as non-root, the owner of the process can write to it. Access can be controlled using normal
file-access control on POSIX systems (owner, group, others, read/write).
+.. note::
+
+ As of Kea 2.6.3, control sockets may only reside in the directory
+ determined during compilation as ``"[kea-install-dir]/var/run/kea"``,
+ which must also have ``0750`` access rights. This path may be overridden
+ at startup by setting the environment variable ``KEA_CONTROL_SOCKET_DIR``
+ to the desired path. If a path other than this value is used in
+ ``socket-name``, Kea will emit an error and refuse to start or, if already
+ running, log an unrecoverable error. For ease of use in simply omit the
+ path component from ``socket-name``.
+
Kea configuration is controlled by a JSON file on the Kea server. This file can be viewed or edited
by anyone with file permissions (which are controlled by the operating system). Note that
passwords are stored in clear text in the configuration file, so anyone with access to read the
the configuration file has control over Kea.
Limiting user permission to read or write the Kea configuration file is an important security step.
+.. note::
+
+ As of Kea 2.6.3, the config file may only be written (using the
+ ``config-write`` command) to the same directory as the config file used
+ when starting Kea (passed as a ``-c`` argument).
+
Securing Database Connections
-----------------------------
Depending on the database configuration, it is also possible to verify whether the system user matches the
database username. Consult the MySQL or PostgreSQL manual for details.
+Kea supports client TLS settings for MySQL database and it must be
+configured explicitly for all used connections (configuration,
+reservations, leases, forensic logging).
+
Information Leakage Through Logging
-----------------------------------
Logs are sent to stdout, stderr, files, or syslog; system file permissions system apply to
stdout/stderr and files. Syslog may export the logs over the network, exposing them further to possible snooping.
+.. note::
+
+ As of Kea 2.7.9, log files may only be written to the output directory
+ determined during compilation as: ``"[kea-install-dir]/var/log/kea"``. This
+ path may be overridden at startup by setting the environment variable
+ ``KEA_LOG_FILE_DIR`` to the desired path. If a path other than
+ this value is used in ``output``, Kea will emit an error and refuse to start
+ or, if already running, log an unrecoverable error. For ease of use simply
+ omit the path component from ``output`` and specify only the file name.
+
+Summary of Path Restrictions
+----------------------------
+
+Path restrictions mentioned through this section can be summarized according to
+the following table:
+
++-------------------------------------+---------------------------------------+----------------------------------+
+| Restricted Element | Default Value | Environment Variable Override |
++=====================================+=======================================+==================================+
+| Config Files (``config-write``) | Same Directory as Initial Config File | N/A |
++-------------------------------------+---------------------------------------+----------------------------------+
+| Lease Files | ``var/lib/kea`` | ``KEA_DHCP_DATA_DIRECTORY`` |
++-------------------------------------+---------------------------------------+----------------------------------+
+| Log Files | ``var/log/kea`` | ``KEA_LOG_FILE_DIR`` |
++-------------------------------------+---------------------------------------+----------------------------------+
+| Unix Sockets | ``var/run/kea`` | ``KEA_CONTROL_SOCKET_DIR`` |
++-------------------------------------+---------------------------------------+----------------------------------+
+
+
+
Cryptography Components
-----------------------
hook library to extend the access controls, integrate with another authentication authority, or add role-based
access control to the Control Agent.
+.. note:
+
+ As of Kea 2.6.3, hook libraries may only be loaded from the default installation
+ directory determined during compilation and shown in the config report as
+ "Hooks directory". This value may be overridden at startup by setting the
+ environment variable ``KEA_HOOKS_PATH`` to the desired path. If a path other
+ than this value is used in a ``library`` element Kea will emit an error and refuse
+ to load the library. For ease of use ``library`` elements may simply omit path
+ components.
+
Kea Security Processes
======================
- Each line of code goes through a formal review before it is accepted. The review process is
documented and available publicly.
-- Roughly 50% of the source code is dedicated to unit tests. As of December 2020, there were over 6000
+- Roughly 50% of the source code is dedicated to unit tests. As of May 2024, there were over 12000
unit tests and the number is increasing with time. Unit tests are required to commit any new feature.
-- There are around 1500 system tests for Kea. These simulate both correct and invalid
+- There are around 2000 system tests for Kea. These simulate both correct and invalid
situations, covering network packets (mostly DHCP, but also DNS, HTTP, HTTPS and others),
command-line usage, API calls, database interactions, scripts, and more.
- There are performance tests with over 80 scenarios that test Kea overall performance and
packets in an invalid order) and more.
- The Kea development team uses many tools that perform automatic code quality checks, such as danger, as well as
internally developed sanity checkers.
-- The Kea team uses the following static code analyzers: Coverity Scan, shellcheck, and danger.
-- The Kea team uses the following dynamic code analyzers: Valgrind and Thread Sanitizer (TSAN).
+- The Kea team uses the following static code analyzers: Coverity Scan, cppcheck, clang-static-analyzer, shellcheck,
+ flawfinder, semgrep and danger.
+- The Kea team uses the following dynamic code analyzers: Valgrind, Thread Sanitizer (TSAN), Address Sanitizer (ASAN),
+ Undefined Behavior Sanitizer (UBSAN).
Fuzz Testing
------------
arm/quickstart
arm/install
arm/admin
+ arm/security
arm/config
arm/keactrl
arm/agent
arm/shell
arm/integrations
arm/stork
- arm/security
.. toctree::
:caption: Appendices
/// "control-socket":
/// {
/// "socket-type": "unix",
-/// "socket-name": "/tmp/server-v4.sock"
+/// "socket-name": "server-v4.sock"
/// }
/// }
/// }
in load_unload.cc:
@code
- const char* registry_fname = "/tmp/user_chk_registry.txt";
+ const char* registry_fname = "/usr/local/share/kea/user_chk_registry.txt";
@endcode
Each line in the file is a self-contained JSON snippet which must have the
Sample user registry file is shown below:
@code
-{ "type" : "HW_ADDR", "id" : "0c:0e:0a:01:ff:04", "bootfile" : "/tmp/v4bootfile" }
+{ "type" : "HW_ADDR", "id" : "0c:0e:0a:01:ff:04", "bootfile" : "/usr/local/share/kea/v4bootfile" }
{ "type" : "HW_ADDR", "id" : "0c:0e:0a:01:ff:06", "tftp_server" : "tftp.v4.example.com" }
-{ "type" : "DUID", "id" : "00:01:00:01:19:ef:e6:3b:00:0c:01:02:03:04", "bootfile" : "/tmp/v6bootfile" }
+{ "type" : "DUID", "id" : "00:01:00:01:19:ef:e6:3b:00:0c:01:02:03:04", "bootfile" : "/usr/local/share/kea/v6bootfile" }
{ "type" : "DUID", "id" : "00:01:00:01:19:ef:e6:3b:00:0c:01:02:03:06", "tftp_server" : "tftp.v6.example.com" }
@endcode
defined in load_unload.cc:
@code
- const char* user_chk_output_fname = "/tmp/user_chk_outcome.txt";
+ const char* user_chk_output_fname = "/usr/local/share/kea/user_chk_outcome.txt";
@endcode
If the file cannot be created (or opened), the library will unload.
/// @brief User registry input file name.
/// @todo Hard-coded for now, this should be configurable.
-const char* registry_fname = "/tmp/user_chk_registry.txt";
+const char* registry_fname = "/usr/local/share/kea/user_chk_registry.txt";
/// @brief User check outcome file name.
/// @todo Hard-coded for now, this should be configurable.
-const char* user_chk_output_fname = "/tmp/user_chk_outcome.txt";
+const char* user_chk_output_fname = "/usr/local/share/kea/user_chk_outcome.txt";
/// @brief Text label of user id in the inbound query in callout context
const char* query_user_id_label = "query_user_id";
/// IOService io_service;
/// ClientConnection conn(io_service);
/// bool cb_invoked = false;
-/// conn.start(ClientConnection::SocketPath("/tmp/kea.sock"),
+/// conn.start(ClientConnection::SocketPath("/opt/kea/var/run/kea/kea.sock"),
/// ClientConnection::ControlCommand(command),
/// [this, &cb_invoked](const boost::system::error_code& ec,
/// const ConstJSONFeedPtr& feed) {
/// "control-socket":
/// {
/// "socket-type": "unix" ,
-/// "socket-name": "/tmp/kea-ddns-ctrl-socket"
+/// "socket-name": "kea-ddns-ctrl-socket"
//// },
/// "tsig-keys":
//// [
/// "control-socket":
/// {
/// "socket-type": "unix",
- /// "socket-name": "/tmp/kea4-ctrl-socket"
+ /// "socket-name": "kea4-ctrl-socket"
/// }
/// }
/// }
/// },
/// "control-socket": {
/// "socket-type": "unix",
-/// "socket-name": "/tmp/kea4-sock"
+/// "socket-name": "kea4-sock"
/// },
/// "subnet4":
/// [
/// <interfaces>eth1</interfaces>
/// </interfaces-config>
/// <control-socket>
-/// <socket-name>/tmp/kea4-sock</socket-name>
+/// <socket-name>kea4-sock</socket-name>
/// <socket-type>unix</socket-type>
/// </control-socket>
/// </config>
/// },
/// "control-socket": {
/// "socket-type": "unix",
-/// "socket-name": "/tmp/kea6-sock"
+/// "socket-name": "kea6-sock"
/// },
/// "subnet6":
/// [
/// <interfaces>eth1</interfaces>
/// </interfaces-config>
/// <control-socket>
-/// <socket-name>/tmp/kea6-sock</socket-name>
+/// <socket-name>kea6-sock</socket-name>
/// <socket-type>unix</socket-type>
/// </control-socket>
/// </config>
/// An example in JSON and YANG formats:
/// @code
/// {
-/// "socket-name": "/tmp/kea.sock",
+/// "socket-name": "kea.sock",
/// "socket-type": "unix",
/// "user-context": { "foo": 1 }
/// }
/// /kea-ctrl-agent:config/control-sockets/socket[server-type='dhcp4']/
/// control-socket (container)
/// /kea-ctrl-agent:config/control-sockets/socket[server-type='dhcp4']/
-/// control-socket/socket-name = /tmp/kea.sock
+/// control-socket/socket-name = kea.sock
/// /kea-ctrl-agent:config/control-sockets/socket[server-type='dhcp4']/
/// control-socket/socket-type = unix
/// /kea-ctrl-agent:config/control-sockets/socket[server-type='dhcp4']/
"cmd-syntax": [
"{",
" \"command\": \"cache-load\",",
- " \"arguments\": \"/tmp/kea-host-cache.json\"",
+ " \"arguments\": \"/usr/local/share/kea/kea-host-cache.json\"",
"}"
],
"description": "See <xref linkend=\"command-cache-load\"/>",