diff options
Diffstat (limited to 'doc/sphinx/arm/hooks-flex-id.rst')
-rw-r--r-- | doc/sphinx/arm/hooks-flex-id.rst | 286 |
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. |