summaryrefslogtreecommitdiffstats
path: root/doc/sphinx/arm/ext-radius.rst
diff options
context:
space:
mode:
Diffstat (limited to 'doc/sphinx/arm/ext-radius.rst')
-rw-r--r--doc/sphinx/arm/ext-radius.rst559
1 files changed, 559 insertions, 0 deletions
diff --git a/doc/sphinx/arm/ext-radius.rst b/doc/sphinx/arm/ext-radius.rst
new file mode 100644
index 0000000..08ca631
--- /dev/null
+++ b/doc/sphinx/arm/ext-radius.rst
@@ -0,0 +1,559 @@
+.. _radius:
+
+RADIUS
+======
+
+.. _radius-overview:
+
+RADIUS Overview
+---------------
+
+This hook library allows Kea to interact with two types of RADIUS
+services: access and accounting. Although the most common DHCP and RADIUS
+integration is done on the DHCP relay-agent level (DHCP clients send
+DHCP packets to DHCP relays; those relays contact the RADIUS server and
+depending on the response either send the packet to the DHCP server or
+drop it), it does require DHCP relay hardware to support RADIUS
+communication. Also, even if the relay has the necessary support, it is
+often not flexible enough to send and receive additional RADIUS
+attributes. As such, the alternative looks more appealing: to extend the
+DHCP server to talk to RADIUS directly. That is the goal of this library.
+
+.. note::
+
+ This library can only be loaded by the :iscman:`kea-dhcp4` or the
+ :iscman:`kea-dhcp6` process.
+
+The major feature of this hook library is the ability to use RADIUS
+authorization. When a DHCP packet is received, the Kea server sends an
+Access-Request to the RADIUS server and waits for a response. The server
+then sends back either an Access-Accept with specific client attributes,
+or an Access-Reject. There are two cases supported here: first, the
+Access-Accept includes a Framed-IP-Address attribute (for DHCPv4) or a
+Framed-IPv6-Address attribute (for DHCPv6), which are interpreted by Kea as
+instructions to assign the specified IPv4 or IPv6 address. This
+effectively means RADIUS can act as an address-reservation database.
+
+The second supported case is the ability to assign clients to specific
+pools based on a RADIUS response. In this case, the RADIUS server sends
+back an Access-Accept with a Framed-Pool attribute.
+For both DHCPv4 and DHCPv6, Kea interprets this attribute as a client class.
+With the addition of the ability to limit access to pools to
+specific classes (see :ref:`classification-pools`), RADIUS can be
+used to force the client to be assigned a dynamic address from a
+specific pool. Furthermore, the same mechanism can be used to control
+what kind of options the client gets if there are DHCP options
+specified for a particular class.
+
+.. _radius-config:
+
+RADIUS Hook Library Configuration
+---------------------------------
+
+The RADIUS hook is a library that must be loaded by either :iscman:`kea-dhcp4` or
+:iscman:`kea-dhcp6` servers. Unlike some other available hook libraries, this one
+takes many parameters. For example, this configuration can be used:
+
+.. parsed-literal::
+
+ {
+ "Dhcp4": {
+
+ // Your regular DHCPv4 configuration parameters goes here.
+
+ "hooks-libraries": [
+ {
+ // Note that RADIUS requires host-cache for proper operation,
+ // so that library is loaded as well.
+ "library": "/usr/local/lib/kea/hooks/libdhcp_host_cache.so"
+ },
+ {
+ "library": "/usr/local/lib/kea/hooks/libdhcp_radius.so",
+ "parameters": {
+
+ // Specify where the dictionary is located.
+ "dictionary": "/etc/kea/radius/dictionary",
+
+ // Specify which address to use to communicate with RADIUS servers
+ "bindaddr": "*"
+
+ // More RADIUS parameters go here.
+ }
+ }
+ ]
+ }
+ }
+
+RADIUS is a complicated environment. As such, it is not feasible
+to provide a default configuration that works for everyone.
+However, we do have an example that showcases some of the more common
+features. Please see ``doc/examples/kea4/hooks-radius.json`` in the Kea
+sources.
+
+The RADIUS hook library supports the following global configuration
+flags:
+
+- ``bindaddr`` (default ``"*"``) - specifies the address to be used by the
+ hook library in communication with RADIUS servers. The ``"*"`` special
+ value tells the kernel to choose the address at hook library load time.
+
+- ``canonical-mac-address`` (default ``false``) - specifies whether MAC
+ addresses in attributes follow the canonical RADIUS format (lowercase
+ pairs of hexadecimal digits separated by ``-``).
+
+- ``client-id-pop0`` (default ``false``) - is used with
+ :ischooklib:`libdhcp_flex_id.so`. Removes the leading zero (or pair of zeroes
+ in DHCPv6) type in the client id (duid in DHCPv6). See
+ ``client-id-printable`` for any value implications when used in conjunction
+ with it.
+
+- ``client-id-printable`` (default ``false``) - checks whether the
+ ``client-id``/``duid`` content is printable and uses it as is instead of in
+ hexadecimal. Implies ``client-id-pop0`` and ``extract-duid`` as 0 and 255 are
+ not printable.
+
+- ``deadtime`` (default ``0``) - is a mechanism that helps in sorting the
+ servers such that the servers that have proved responsive so far are inquired
+ first, and the servers that have proved unresponsive are left at the end. The
+ deadtime value specifies the number of seconds after which a server is
+ considered unresponsive. 0 disables the mechanism.
+
+- ``dictionary`` (default ``"/etc/kea/radius/dictionary"``) - is the
+ attribute and value dictionary. Note that it is a critical parameter.
+ A dictionary is provided by Kea and is set by default.
+
+- ``extract-duid`` (default ``true``) - extracts the embedded duid from an
+ RFC-4361-compliant DHCPv4 client id. See ``client-id-printable`` for any
+ value implications when used in conjunction with it.
+
+- ``identifier-type4`` (default ``"client-id"``) - specifies the identifier
+ type to build the User-Name attribute. It should be the same as the
+ host identifier. When :ischooklib:`libdhcp_flex_id.so` is used, then
+ ``replace-client-id`` must be set to ``true`` and ``client-id`` must be used
+ with ``client-id-pop0`` enabled.
+
+- ``identifier-type6`` (default ``"duid"``) - specifies the identifier type to
+ build the User-Name attribute. It should be the same as the host
+ identifier. When :ischooklib:`libdhcp_flex_id.so` is used, then
+ ``replace-client-id`` must be set to ``true`` and ``duid`` must be used with
+ ``client-id-pop0`` enabled.
+
+- ``nas-ports`` (default ``[]``), specifies the NAS port to use in place of
+ a subnet ID (default behavior). It is an array of maps, each map having two
+ elements at most: the mandatory NAS port value, and, optionally, a selector
+ consisting of either a subnet id, a subnet prefix, or a shared-network name.
+ If the selector is applied to the packet, the NAS port is used instead of the
+ subnet id. When the subnet id is 0 or missing, the specified NAS port acts as
+ a default. Its substition happens for all packets that did not match a
+ selector.
+
+- ``realm`` (default ``""``) - is the default realm.
+
+- ``reselect-subnet-address`` (default ``false``) - enables subnet reselection
+ according to the value of the Framed-IP-Address or, respectively,
+ the Framed-IPv6-Address attribute from the RADIUS access response. With this
+ flag enabled, if the IP address is not in range of the currently selected
+ subnet, but is in range of another subnet that is selectable with regards to
+ other criteria, the latter subnet is selected and used further in the lease
+ assignment process.
+
+- ``reselect-subnet-pool`` (default ``false``) - enables subnet reselection
+ according to the value of the Framed-Pool attribute from the RADIUS access
+ response. With this flag enabled, if the currently selected subnet is not
+ guarded by the client class represented by the attribute value, but there is
+ another selectable subnet that is guarded by it, the latter subnet is
+ selected and used further in the lease assignment process.
+ This reselection is attempted first, and if successful, it prevents the
+ function of reselect-subnet-address from coming into effect.
+
+- ``retries`` (default ``3``) - is the number of retries before trying the
+ next server.
+
+- ``session-history`` (default ``""``) - is the name of the file providing
+ persistent storage for accounting session history.
+
+ - ``thread-pool-size`` (default ``0``) indicates the number of threads that
+ is used for sending RADIUS requests and processing RADIUS responses for both
+ access and accounting services before passing it to the core thread pool. A
+ value of ``0`` instructs the RADIUS hook library to use the same number of
+ threads used for core DHCP processing. This value is only relevant if Kea
+ core is configured as multi-threaded. Single-threaded Kea core results in
+ single-threaded RADIUS processing.
+
+- ``timeout`` (default ``10``) - is the number of seconds during which a
+ response is awaited.
+
+Two services are supported:
+
+- ``access`` - the authorization service.
+
+- ``accounting`` - the accounting service.
+
+At the service level, three sections can be configured:
+
+- Servers that define RADIUS services that the library is expected to
+ contact. Each server may have the following items specified:
+
+ - ``name`` - specifies the IP address of the server. A domain name may be
+ used and will be resolved at hook library load time.
+
+ - ``port`` - specifies the UDP port of the server. By default, it is 1812
+ for access and 1813 for accounting.
+
+ - ``secret`` - authenticates messages.
+
+ When no server is specified, the service is disabled.
+
+- Attributes which define additional information that the Kea server
+ sends to a RADIUS server. The parameter must be identified either
+ by a name or type. Its value can be specified in one of three
+ possible ways: ``data`` (which defines a plain text value), ``raw`` (which
+ defines the value in hex), or ``expr`` (which defines an expression
+ that is evaluated for each incoming packet independently).
+
+ - ``name`` - the name of the attribute.
+
+ - ``type`` - the type of the attribute. Either the type or the name must be
+ provided, and the attribute must be defined in the dictionary.
+
+ - ``data`` - the first of three ways to specify the attribute content.
+ It specifies the textual representation of the attribute content.
+
+ - ``raw`` - the second of three ways to specify the attribute content.
+ It specifies the content in hexadecimal.
+
+ - ``expr`` - the last of the three ways to specify the attribute content.
+ It specifies an evaluation expression on the DHCP query packet.
+ Currently this is restricted to the access service.
+
+ Attributes are supported only for the access service.
+
+- The ``peer-updates`` boolean flag (default ``true``) controls whether lease
+ updates coming from an active High-Availability (HA) partner should result in
+ an accounting request. This may be desirable to remove duplicates if HA
+ partners are configured to send request to the same RADIUS server. The flag is
+ only supported by the accounting service. The lease synchronization process at
+ the startup of an HA node does not trigger a RADIUS accounting request,
+ regardless of the value of this flag.
+
+- The ``max-pending-requests`` positive integer (default ``0``) limits the
+ number of pending RADIUS requests. The value ``0`` means no limit. It is
+ supported only by the access service. ``64`` can be a good value to set it to.
+
+For example, to specify a single access server available on localhost
+that uses ``"xyz123"`` as a secret, and tell Kea to send three additional
+attributes (``User-Password``, ``Connect-Info``, and ``Configuration-Token``),
+the following snippet could be used:
+
+.. parsed-literal::
+
+ {
+ "parameters": {
+
+ // Other RADIUS parameters here
+
+ "access": {
+
+ // This starts the list of access servers.
+ "servers": [
+ {
+ // These are parameters for the first (and only) access server
+ "name": "127.0.0.1",
+ "port": 1812,
+ "secret": "xyz123"
+ }
+ // Additional access servers could be specified here.
+ ],
+
+ // This defines a list of additional attributes Kea will send to each
+ // access server in Access-Request.
+ "attributes": [
+ {
+ // This attribute is identified by name (must be present in the
+ // dictionary) and has static value (i.e. the same value will be
+ // sent to every server for every packet).
+ "name": "User-Password",
+ "data": "mysecretpassword"
+ },
+ {
+ // It is also possible to specify an attribute using its type,
+ // rather than a name. 77 is Connect-Info. The value is specified
+ // using hex. Again, this is a static value. It will be sent the
+ // same for every packet and to every server.
+ "type": 77,
+ "raw": "65666a6a71"
+ },
+ {
+ // This example shows how an expression can be used to send dynamic value.
+ // The expression (see :ref:`classification-using-expressions`) may take any
+ // value from the incoming packet or even its metadata e.g. the
+ // interface it was received over from.
+ "name": "Configuration-Token",
+ "expr": "hexstring(pkt4.mac,':')"
+ }
+ ] // End of attributes
+ }, // End of access
+
+ // Accounting parameters.
+ "accounting": {
+ // This starts the list of accounting servers.
+ "servers": [
+ {
+ // These are parameters for the first (and only) accounting server
+ "name": "127.0.0.1",
+ "port": 1813,
+ "secret": "sekret"
+ }
+ // Additional accounting servers could be specified here.
+ ]
+ }
+ }
+ }
+
+Customization is sometimes required for certain attributes by devices belonging
+to various vendors. This is a great way to leverage the expression evaluation
+mechanism. For example, MAC addresses which might be used as a convenience
+value for the ``User-Password`` attribute are most likely to appear in colon-hexadecimal
+notation (``de:ad:be:ef:ca:fe``), but they might need to be expressed in
+hyphen-hexadecimal notation (``de-ad-be-ef-ca-fe``). Here's how to specify that:
+
+.. code-block:: json
+
+ {
+ "parameters": {
+ "access": {
+ "attributes": [
+ {
+ "name": "User-Password",
+ "expr": "hexstring(pkt4.mac, '-')"
+ }
+ ]
+ }
+ }
+ }
+
+And here's how to specify period-separated hexadecimal notation (``dead.beef.cafe``), preferred by Cisco devices:
+
+.. code-block:: json
+
+ {
+ "parameters": {
+ "access": {
+ "attributes": [
+ {
+ "name": "User-Password",
+ "expr": "substring(hexstring(pkt4.mac, ''), 0, 4) + '.' + substring(hexstring(pkt4.mac, ''), 4, 4) + '.' + substring(hexstring(pkt4.mac, ''), 8, 4)"
+ }
+ ]
+ }
+ }
+ }
+
+
+For :ischooklib:`libdhcp_radius.so` to operate properly in DHCPv4,
+:ischooklib:`libdhcp_host_cache.so` must also be loaded. The reason for this
+is somewhat complex. In a typical deployment, the DHCP clients send
+their packets via DHCP relay, which inserts certain Relay Agent
+Information options, such as ``circuit-id`` or ``remote-id``. The values of
+those options are then used by the Kea DHCP server to formulate the
+necessary attributes in the Access-Request message sent to the RADIUS
+server. However, once the DHCP client gets its address, it then renews
+by sending packets directly to the DHCP server. As a result, the relays
+are not able to insert their RAI options, and the DHCP server cannot send
+the Access-Request queries to the RADIUS server by using just the
+information from incoming packets. Kea needs to keep the information
+received during the initial Discover/Offer exchanges and use it again
+later when sending accounting messages.
+
+This mechanism is implemented based on user context in host
+reservations. (See :ref:`user-context` and :ref:`user-context-hooks` for
+details.) The host-cache mechanism allows the information retrieved by
+RADIUS to be stored and later used for sending access and accounting
+queries to the RADIUS server. In other words, the host-cache mechanism
+is mandatory, unless administrators do not want RADIUS communication for messages
+other than Discover and the first Request from each client.
+
+.. note::
+
+ Currently the RADIUS hook library is incompatible with the
+ ``early-global-reservations-lookup`` global parameter i.e.
+ setting the parameter to ``true`` raises an error when the
+ hook library is loaded.
+
+.. note::
+
+ Currently the RADIUS hook library is incompatible with the
+ multi-subnet shared networks that have host reservations other
+ than global. Loading the RADIUS hook library in a Kea DHCP server
+ that has this configuration raises an error.
+
+.. _radius-server-example:
+
+RADIUS Server Setup Example
+---------------------------
+
+The RADIUS hook library requires at least one RADIUS server to function. One
+popular open-source implementation is FreeRADIUS. This is how it can be
+set up to enable basic functionality in Kea.
+
+1. Install FreeRADIUS through the package manager or from the tarballs available
+ on [the freeradius.org download page](https://freeradius.org/releases/).
+
+2. Establish the FreeRADIUS configuration directory. It's commonly
+ ``/etc/freeradius``, but it may be ``/etc/raddb``.
+
+3. Generate certificates. Go to ``/etc/freeradius/certs``.
+ Run ``./bootstrap`` or ``make``.
+ Wait until finished. It should take a few seconds.
+
+4. Check that the server is able to start.
+ Running with the ``-X`` flag is a good way to display potential errors.
+ Run ``radiusd -X`` or ``freeradius -X``, whichever is available.
+ It should display ``Ready to process requests`` on the final line.
+
+5. If the Kea DHCP server and the RADIUS server are on different machines,
+ edit ``/etc/freeradius/clients.conf`` with the proper address under
+ ``ipadddr``. This file is also where the secret is set, which needs to match
+ the one set in the hook library's configuration.
+
+6. If RADIUS is used for the purpose of authorizing DHCP clients, each DHCP
+ client needs to have an entry in the authorize file, which can be commonly
+ found at:
+
+ - ``/etc/raddb/mods-config/files/authorize``
+ - ``/etc/freeradius/3.0/mods-config/files/authorize``
+ - ``/etc/freeradius/users`` (for RADIUS 2.x series)
+
+ Entries need to have the password set which needs to match the password
+ configured in the configuration of the RADIUS hook library under the
+ ``User-Password`` attribute. Each entry can have zero, one or multiple
+ attributes.
+
+ In the following example, there are 6 entries with the password set to the
+ client ID, which would need to be dynamically set in the hook library's
+ configuration. Here's how the entries can look like:
+
+ ::
+
+ 01:00:0c:01:02:03:04 Cleartext-password := "00:0c:01:02:03:04"
+
+ 01:00:0c:01:02:03:05 Cleartext-password := "00:0c:01:02:03:05"
+ Framed-IP-Address = "192.0.2.5"
+
+ 01:00:0c:01:02:03:06 Cleartext-password := "00:0c:01:02:03:06"
+ Framed-IP-Address = "192.0.2.6",
+ Framed-Pool = "classical"
+
+ 00:03:00:01:00:0c:01:02:03:07 Cleartext-password := "00:0c:01:02:03:07"
+
+ 00:03:00:01:00:0c:01:02:03:08 Cleartext-password := "00:0c:01:02:03:08"
+ Framed-IPv6-Address = "2001:db8::8"
+
+ 00:03:00:01:00:0c:01:02:03:09 Cleartext-password := "00:0c:01:02:03:09"
+ Framed-IPv6-Address = "2001:db8::9",
+ Framed-Pool = "classroom"
+
+7. Accounting should work out of the box with Kea, but customizations are
+ possible in the accounting file, which can be commonly found at:
+
+ - ``/etc/radius-config/mods-config/files/accounting``
+ - ``/etc/freeradius/3.0/mods-config/files/accounting``
+
+.. _radius-lease-allocation:
+
+RADIUS Workflows for Lease Allocation
+-------------------------------------
+
+The following diagrams show a high level view of how RADIUS assists with the
+lease allocation process in :iscman:`kea-dhcp4` and :iscman:`kea-dhcp6`.
+
+.. figure:: ../uml/radius.*
+
+Somewhat tangential to lease allocation, and not shown in the diagrams above,
+is the ``command_processed`` callout, which sends Accounting-Request messages
+when a lease command is received.
+
+.. _radius-differences:
+
+Differences Between RADIUS Hook Libraries Prior To 2.4.0 and As Of 2.6.0
+------------------------------------------------------------------------
+
+The RADIUS hook library in 2.4.0 and prior versions relied on the FreeRADIUS
+client library to function. Starting with 2.6.0 and onwards, the RADIUS hook
+library is standalone with its own RADIUS client implementation and its own
+RADIUS dictionary. There are differences:
+
+.. list-table::
+ :header-rows: 1
+
+ * - Feature
+
+ - Old
+
+ - New
+
+ * - Support for Attribute Data Types
+
+ - string, ipaddr, ipv4prefix, integer, integer64, date, ifid, ipv6addr, ipv6prefix, tlv, abinary, byte, ether, short, signed, octets
+
+ - string (can simulate any other unsupported data type too), ipaddr, integer, date (interpreted as integer), ipv6addr, ipv6prefix
+
+ * - Names of Standard Attributes
+
+ - Taken from the FreeRADIUS dictionary.
+
+ - Taken from the Kea RADIUS dictionary and the IANA registry. There is an aliasing mechanism built into the library that ensures backward compatibility e.g. ``Password`` translates to the standard name of the attribute ``User-Password``.
+
+ * - Resolution of RADIUS Server Domain Names
+
+ - At run time.
+
+ - At hook library load time.
+
+ * - Automatic Deduction of Source Address for Reaching RADIUS Servers (configured with ``bindaddr: "*"``)
+
+ - At run time.
+
+ - At hook library load time.
+
+ * - RADIUS Server Limit per Service
+
+ - 8
+
+ - Unlimited
+
+ * - Support for Including Dictionaries Inside Dictionaries
+
+ - Yes
+
+ - No
+
+ * - Support for Vendor Attributes
+
+ - Yes
+
+ - No
+
+ * - Attribute Names and Attribute Values
+
+ - Case-insensitive
+
+ - Case-sensitive
+
+ * - Integer Values
+
+ - Do not require an attribute definition.
+
+ - Must have an associated attribute definition in the dictionary.
+
+ * - Reply-Message Presence in the Kea Logs
+
+ - Only as part of the aggregated list of attributes in ``RADIUS_AUTHENTICATION_ACCEPTED``, ``RADIUS_ACCESS_CACHE_INSERT``, ``RADIUS_ACCESS_CACHE_GET`` log messages.
+
+ - Also has a dedicated ``RADIUS_REPLY_MESSAGE_ATTRIBUTE`` message per each Reply-Message attribute logged after a valid RADIUS reply is received.
+
+ * - Behavior of Multiple Attributes of the Same Type (except Reply-Message)
+
+ - Experimentally, only the **first** attribute on the wire from an Access-Accept message is considered.
+
+ - Experimentally, only the **last** attribute on the wire from an Access-Accept message is considered.