summaryrefslogtreecommitdiffstats
path: root/src/hooks/dhcp/user_chk/libdhcp_user_chk.dox
diff options
context:
space:
mode:
Diffstat (limited to 'src/hooks/dhcp/user_chk/libdhcp_user_chk.dox')
-rw-r--r--src/hooks/dhcp/user_chk/libdhcp_user_chk.dox227
1 files changed, 227 insertions, 0 deletions
diff --git a/src/hooks/dhcp/user_chk/libdhcp_user_chk.dox b/src/hooks/dhcp/user_chk/libdhcp_user_chk.dox
new file mode 100644
index 0000000..ad2be18
--- /dev/null
+++ b/src/hooks/dhcp/user_chk/libdhcp_user_chk.dox
@@ -0,0 +1,227 @@
+// Copyright (C) 2013-2021 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/.
+
+/**
+@page libdhcp_user_chk DHCP User Check Hooks Library
+
+@section libdhcp_user_chkIntro user_chk: An Example Hooks Library
+## Introduction
+user_chk is an example hooks library which customizes the DHCP query
+processing provided by Kea DHCP server modules (kea-dhcp4 and kea-dhcp6).
+Specifically it allows subnet selection and DHCP response option customization
+based upon a registry of DHCP clients. Note that the words "client" and "user"
+are used interchangeably herein. The intent of the custom behavior is three
+fold:
+
+1. To assign "new" or "unregistered" users to a restricted subnet, while "known"
+or "registered" users are assigned to unrestricted subnets.
+
+2. To allow DHCP response options or vendor option values to be customized
+based upon user identity.
+
+3. To provide a real time record of the user registration activity which can be
+sampled by an external consumer.
+
+The source code is provided in the src/hooks/dhcp/use_chk directory.
+
+## User Registry Classes
+At the heart of the library is a class hierarchy centered around the class,
+@c user_chk::UserRegistry. This class represents a maintainable, searchable
+registry of "known" users and their attributes. It provides services to load,
+clear, and refresh the registry as well as to add, find, and remove users.
+
+Each entry in the registry is an instance of the class, @c user_chk::User. Users
+are uniquely identified by their @c user_chk::UserId. UserIds are comprised of
+data taken from the DHCP request. IPv4 users have a type of "HW_ADDR" and
+their id is the hardware address from the request. IPv6 users have a type of
+"DUID" and their id is the DUID from the request.
+
+The registry may be manually populated or loaded from a source of data which
+implements the @c UserDataSource interface. Currently, a single implementation has
+been implemented, @c user_chk::UserFile. UserFile supports reading the registry
+from a text file in which each line is a user entry in JSON format. Each entry
+contains the id type and user id along with optional attributes. Attributes are
+essentially name/value pairs whose significance is left up to the calling layer.
+UserFile does not enforce any specific content beyond id type and id.
+(See user_file.h for more details on file content).
+
+## Callout Processing
+The library implements callouts for packet receive, subnet select, and packet
+send for both IPv4 and IPv6. Regardless of the protocol type, the process
+flow upon receipt of an inbound request is the same and is as follows:
+
+-# "pkt_receive" callout is invoked
+ -# Refresh the user registry
+ -# Extract user id from DHCP request and store it to context
+ -# Look up user id in registry and store resultant user pointer to context
+
+ Note that each time a packet is received, the user registry is refreshed.
+ This ensures that the registry content always has the latest external
+ updates. The primary goal at this stage is check the registry for the
+ user and push the result to the context making it available to subsequent
+ callouts.
+
+-# "subnet_select" callout is invoked
+ -# Retrieve the user pointer from context
+ -# If pointer is null (i.e. user is not registered), replace subnet
+ selection with restricted subnet
+
+ By convention, the last subnet in the collection of subnets available is
+ assumed to be the "restricted access" subnet. A more sophisticated mechanism
+ is likely to be needed.
+
+-# "pkt_send" callout is invoked:
+ -# Retrieve the user id and user pointer from context
+ -# If user is not null add the options based on user's attributes,
+ otherwise use default user's attributes
+ -# Generate user check outcome
+
+ This final step is what produces the real time record, referred to as the
+ "user check outcome" file.
+
+In case any other library sets the SKIP flag before pkt4_send or pkt6_send, an
+exception with the message "the packet pack already handled" will be thrown, to
+indicate that the action can not be properly performed.
+To fix this, all other libraries which might set the SKIP flag must appear in the
+server configuration after this library.
+
+## Using the library
+Two steps are required in order to use the library:
+-# The user registry file must be created and deployed
+-# The Kea DHCP module(s) must be configured to load the library
+
+### Creating the Registry File
+Currently, the library uses a hard coded pathname for the user registry defined
+in load_unload.cc:
+
+@code
+ const char* registry_fname = "/tmp/user_chk_registry.txt";
+@endcode
+
+Each line in the file is a self-contained JSON snippet which must have the
+following two entries:
+
+ - "type" whose value is "HW_ADDR" for IPv4 users or "DUID" for IPv6 users
+ - "id" whose value is either the hardware address or the DUID from the
+ request formatted as a string of hex digits, with or without ":" delimiters.
+
+and may have the zero or more of the following entries:
+
+ - "bootfile" whose value is the pathname of the desired file
+ - "tftp_server" whose value is the hostname or IP address of the desired
+ server
+
+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: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:06", "tftp_server" : "tftp.v6.example.com" }
+@endcode
+
+It is possible to specify additional attributes. They will be loaded and stored with the user's entry in the registry.
+This allows the library to be extended to perform additional actions based on these attributes.
+
+Upon start up the library will attempt to load this file. If it does not exist
+the library will unload.
+
+### Configuring the DHCP Modules
+
+It must be configured as a hook library for the desired DHCP server modules.
+Note that the user_chk library is installed alongside the Kea libraries in
+"<install-dir>/lib" where <install-dir> is determined by the --prefix option of
+the configure script. It defaults to "/usr/local". Assuming the default value
+then, configuring kea-dhcp4 to load the user_chk library could be done with the
+following Kea4 configuration:
+
+@code
+"Dhcp4": {
+ "hooks-libraries": [ "/usr/local/lib/libdhcp_user_chk.so" ],
+ ...
+}
+@endcode
+
+To configure it for kea-dhcp6, the commands are simply as shown below:
+
+@code
+"Dhcp6": {
+ "hooks-libraries": [ "/usr/local/lib/libdhcp_user_chk.so" ],
+ ...
+}
+@endcode
+
+## User Check Outcome
+Once up and running, the library should begin adding entries to the outcome
+file. Currently, the library uses a hard coded pathname for the user registry
+defined in load_unload.cc:
+
+@code
+ const char* user_chk_output_fname = "/tmp/user_chk_outcome.txt";
+@endcode
+
+If the file cannot be created (or opened), the library will unload.
+
+For each lease granted, the library will add the following information to the
+end of the file: the id type, the user id, the lease or prefix granted, and
+whether or not the user was found in the registry. This information is written
+in the form of "name=value" with one value per line. (See subnet_callout.cc for
+details.)
+
+A sample outcome file is shown below:
+
+@code
+id_type=HW_ADDR
+client=hwtype=1 0c:0e:0a:01:ff:04
+addr=175.16.1.100
+registered=yes
+
+id_type=HW_ADDR
+client=hwtype=1 0c:0e:0a:01:ff:05
+addr=152.0.2.10
+registered=no
+
+id_type=HW_ADDR
+client=hwtype=1 0c:0e:0a:01:ff:06
+addr=175.16.1.101
+registered=yes
+
+id_type=HW_ADDR
+client=hwtype=1 0c:0e:0a:01:ff:04
+addr=175.16.1.102
+registered=yes
+
+id_type=DUID
+client=00:01:00:01:19:ef:e6:3b:00:0c:01:02:03:04
+addr=2001:db8:2::1:0:0/96
+registered=yes
+
+id_type=DUID
+client=00:01:00:01:19:ef:e6:3b:00:0c:01:02:03:04
+addr=2001:db8:2::
+registered=yes
+
+id_type=DUID
+client=00:01:00:01:19:ef:e6:3b:00:0c:01:02:03:05
+addr=5005:778:2::
+registered=no
+
+id_type=DUID
+client=00:01:00:01:19:ef:e6:3b:00:0c:01:02:03:06
+addr=2001:db8:2::1
+registered=yes
+
+@endcode
+
+Note the library always opens this file in append mode and does not limit its size.
+
+@section libdhcp_user_chkMTCompatibility Multi-Threading Compatibility
+
+The user_chk hooks library does not define a multi_threading_compatible()
+C function so is considered as not compatible with multi-threading
+(and the current code should be in fact really not compatible).
+
+*/