summaryrefslogtreecommitdiffstats
path: root/doc/sphinx/arm/hooks-flex-id.rst
diff options
context:
space:
mode:
Diffstat (limited to 'doc/sphinx/arm/hooks-flex-id.rst')
-rw-r--r--doc/sphinx/arm/hooks-flex-id.rst286
1 files changed, 286 insertions, 0 deletions
diff --git a/doc/sphinx/arm/hooks-flex-id.rst b/doc/sphinx/arm/hooks-flex-id.rst
new file mode 100644
index 0000000..d485f0b
--- /dev/null
+++ b/doc/sphinx/arm/hooks-flex-id.rst
@@ -0,0 +1,286 @@
+.. ischooklib:: libdhcp_flex_id.so
+.. _hooks-flex-id:
+
+``libdhcp_flex_id.so``: Flexible Identifier for Host Reservations
+=================================================================
+
+The Kea software provides a way to handle
+host reservations that include addresses, prefixes, options, client
+classes, and other features. The reservation can be based on hardware
+address, DUID, circuit-id, or client-id in DHCPv4 and on hardware
+address or DUID in DHCPv6. However, there are sometimes scenarios where
+the reservation is more complex; it may use options other than those mentioned
+above, use parts of specific options, or perhaps even use a combination of
+several options and fields to uniquely identify a client. Those
+scenarios are addressed by the Flexible Identifiers hook application.
+
+.. note::
+
+ :ischooklib:`libdhcp_flex_id.so` is available as a premium
+ hook library from ISC. Please visit https://www.isc.org/shop/ to purchase
+ the premium hook libraries, or contact us at https://www.isc.org/contact for
+ more information.
+
+.. note::
+
+ This library can only be loaded by the :iscman:`kea-dhcp4` or :iscman:`kea-dhcp6`
+ process.
+
+:ischooklib:`libdhcp_flex_id.so` allows the definition of an expression, using notation initially
+used only for client classification. (See
+:ref:`classification-using-expressions` for a detailed description of
+the syntax available.) One notable difference is that for client
+classification, the expression currently has to evaluate to either ``true``
+or ``false``, while the flexible identifier expression is expected to
+evaluate to a string that will be used as an identifier. It is a valid case
+for the expression to evaluate to an empty string (e.g. in cases where a
+client does not send specific options). This expression is then
+evaluated for each incoming packet, and this evaluation generates an
+identifier that is used to identify the client. In particular, there may
+be host reservations that are tied to specific values of the flexible
+identifier.
+
+The library can be loaded similarly to other hook libraries. It
+takes a mandatory parameter ``identifier-expression`` and some optional boolean
+parameters like ``replace-client-id`` and ``ignore-iaid``:
+
+::
+
+ "Dhcp6": {
+ "hooks-libraries": [
+ {
+ "library": "/path/libdhcp_flex_id.so",
+ "parameters": {
+ "identifier-expression": "expression",
+ "replace-client-id": false,
+ "ignore-iaid": false
+ }
+ },
+ ...
+ ]
+ }
+
+The flexible identifier library supports both DHCPv4 and DHCPv6.
+
+Let's consider a case of an IPv6 network that has an
+independent interface for each of its connected customers. Customers are
+able to plug in whatever device they want, so any type of identifier
+(e.g. a client-id) is unreliable. Therefore, the operator may decide to
+use an option inserted by a relay agent to differentiate between
+clients. In this particular deployment, the operator has verified that the
+interface-id is unique for each customer-facing interface, so it
+is suitable for usage as a reservation. However, only the first six bytes of
+the interface-id are interesting, because the remaining bytes are either
+randomly changed or not unique between devices. Therefore, the customer
+decides to use the first six bytes of the interface-id option inserted by the
+relay agent. After adding ``flex-id``, the ``host-reservation-identifiers`` goal
+can be achieved by using the following configuration:
+
+::
+
+ "Dhcp6": {
+ "subnet6": [{
+ # subnet definition starts here
+ "reservations": [{
+ "flex-id": "'port1234'",
+ # value of the first 8 bytes of the interface-id
+ "ip-addresses": [ "2001:db8::1" ]
+ },
+ ...
+ ],
+ ...
+ },
+ ...
+ ],
+ # end of subnet definitions
+ "host-reservation-identifiers": ["duid", "flex-id"],
+ # add "flex-id" to reservation identifiers
+ "hooks-libraries": [
+ {
+ "library": "/path/libdhcp_flex_id.so",
+ "parameters": {
+ "identifier-expression": "substring(relay6[0].option[18].hex,0,8)"
+ }
+ },
+ ...
+ ],
+ ...
+ }
+
+.. note::
+
+ Care should be taken when adjusting the expression. If the expression
+ changes, then all the ``flex-id`` values may change, possibly rendering
+ all reservations based on ``flex-id`` unusable until they are manually updated.
+ It is strongly recommended that administrators start with the expression and a
+ handful of reservations, and then adjust the expression as needed. Once
+ the desired result is obtained with the expression, host reservations
+ can be deployed on a broader scale.
+
+``flex-id`` values in host reservations can be specified in two ways. First,
+they can be expressed as a hex string, e.g. the string "bar" can be represented
+as 626174. Alternatively, it can be expressed as a quoted value (using
+double and single quotes), e.g. "'bar'". The former is more convenient
+for printable characters, while hex string values are more convenient
+for non-printable characters and do not require the use of the
+``hexstring`` operator.
+
+::
+
+ "Dhcp6": {
+ "subnet6": [{
+ # subnet definition starts here
+ "reservations": [{
+ "flex-id": "01:02:03:04:05:06",
+ # value of the first 8 bytes of the interface-id
+ "ip-addresses": [ "2001:db8::1" ]
+ },
+ ...
+ ],
+ ...
+ },
+ ...
+ ],
+ # end of subnet definitions
+ "host-reservation-identifiers": ["duid", "flex-id"],
+ # add "flex-id" to reservation identifiers
+ "hooks-libraries": [
+ {
+ "library": "/path/libdhcp_flex_id.so",
+ "parameters": {
+ "identifier-expression": "vendor[4491].option[1026].hex"
+ }
+ },
+ ...
+ ],
+ ...
+ }
+
+.. note::
+
+ One less common scenario where the examples above may prove useful is for
+ DHCPv6 clients that change their DUIDs between exchanges. Certain PXE
+ clients are known to behave this way.
+
+The ``replace-client-id`` Flag
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When ``replace-client-id`` is set to ``false`` (which is the default setting),
+:ischooklib:`libdhcp_flex_id.so` uses the evaluated flexible identifier solely for
+identifying host reservations, i.e. searching for reservations within a
+database. This is the functional equivalent of other identifiers, similar
+to hardware address or circuit-id. However, this mode of operation
+implies that if a client device is replaced, it may cause a
+conflict between an existing lease (allocated to the old device) and the
+new lease being allocated to the new device. The conflict arises
+because the same flexible identifier is computed for the replaced device,
+so the server will try to allocate the same lease. The mismatch between
+client identifiers sent by the new device and the old device causes the server
+to refuse this new allocation until the old lease expires. A
+manifestation of this problem is dependent on the specific expression used
+as the flexible identifier, and is likely to appear if only options
+and other parameters are used that identify where the device is connected
+(e.g. circuit-id), rather than the device identification itself (e.g.
+MAC address).
+
+:ischooklib:`libdhcp_flex_id.so` offers a way to overcome the problem with lease
+conflicts by dynamically replacing the client identifier (or DUID in DHCPv6)
+with a value derived from the flexible identifier. The server
+processes the client's query as if the flexible identifier were sent in the
+client identifier (or DUID) option. This guarantees that a returning
+client (for which the same flexible identifier is evaluated) will be
+assigned the same lease, despite the client identifier and/or MAC address
+change.
+
+The following is a stub configuration that enables this behavior:
+
+::
+
+ "Dhcp4": {
+ "hooks-libraries": [
+ {
+ "library": "/path/libdhcp_flex_id.so",
+ "parameters": {
+ "identifier-expression": "expression",
+ "replace-client-id": true
+ }
+ },
+ ...
+ ]
+ }
+
+In the DHCPv4 case, the value derived from the flexible identifier is
+formed by prepending one byte with a value of zero to the flexible identifier.
+In the DHCPv6 case, it is formed by prepending two zero bytes before the
+flexible identifier.
+
+Note that for this mechanism to take effect, the DHCPv4 server must be
+configured to respect the client identifier option value during lease
+allocation, i.e. ``match-client-id`` must be set to ``true``. See
+:ref:`dhcp4-match-client-id` for details. No additional settings are
+required for DHCPv6.
+
+If the ``replace-client-id`` option is set to ``true``, the value of the
+``echo-client-id`` parameter (which governs whether to send back a
+client-id option) is ignored.
+
+The :ref:`hooks-lease-cmds` section describes commands used to retrieve,
+update, and delete leases using various identifiers, such as ``hw-address`` and
+``client-id``. :ischooklib:`libdhcp_lease_cmds.so` does not natively support querying
+for leases by flexible identifier. However, when ``replace-client-id`` is
+set to ``true``, it makes it possible to query for leases using a value
+derived from the flexible identifier. In DHCPv4, the query
+looks similar to this:
+
+::
+
+ {
+ "command": "lease4-get",
+ "arguments": {
+ "identifier-type": "client-id",
+ "identifier": "00:54:64:45:66",
+ "subnet-id": 44
+ }
+ }
+
+where the hexadecimal value of "54:64:45:66" is a flexible identifier
+computed for the client.
+
+In DHCPv6, the corresponding query looks something like this:
+
+::
+
+ {
+ "command": "lease6-get",
+ "arguments": {
+ "identifier-type": "duid",
+ "identifier": "00:00:54:64:45:66",
+ "subnet-id": 10
+ }
+ }
+
+The ``ignore-iaid`` Flag
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+When ``ignore-iaid`` is set to ``true`` (the default value is ``false``),
+:ischooklib:`libdhcp_flex_id.so` causes the Kea DHCPv6 server to ignore the IAID value
+from incoming IPv6 packets. This parameter is ignored by the Kea DHCPv4 server.
+
+If the packet contains only one IA_NA, the IAID value will be changed to ``0``
+and stored as such in the lease storage. Similarly, if the packet contains only
+one IA_PD, the IAID value will be changed to ``0`` and stored as such in the
+lease storage. The IAID is restored to its initial value in the response back
+to the client. The change is visible in the identifier expression if the IAID is
+part of the expression.
+
+.. note::
+
+ To avoid lease conflicts, if the incoming packet contains more than one
+ IA_NA, the IAID value is not changed on any of the IA_NAs. Similarly,
+ if the incoming packet contains more than one IA_PD, the IAID value is not
+ changed on any of the IA_PDs.
+
+.. warning::
+
+ This functionality breaks RFC compliance and should be enabled only if
+ required. When enabled, a warning message is issued at configure time.