From af754e596a8dbb05ed8580c342e7fe02e08b28e0 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 13 Apr 2024 16:11:00 +0200 Subject: Adding upstream version 3.2.3+dfsg. Signed-off-by: Daniel Baumann --- .../protocols/dhcp/policy_device_options.adoc | 310 +++++++++++++++++++++ 1 file changed, 310 insertions(+) create mode 100644 doc/antora/modules/howto/pages/protocols/dhcp/policy_device_options.adoc (limited to 'doc/antora/modules/howto/pages/protocols/dhcp/policy_device_options.adoc') diff --git a/doc/antora/modules/howto/pages/protocols/dhcp/policy_device_options.adoc b/doc/antora/modules/howto/pages/protocols/dhcp/policy_device_options.adoc new file mode 100644 index 0000000..05845ea --- /dev/null +++ b/doc/antora/modules/howto/pages/protocols/dhcp/policy_device_options.adoc @@ -0,0 +1,310 @@ +== Configure "device", "class" and "group" options + +Beyond the global, network and subnet options already described, most sites +will have a number of group or class based options, and have a requirement for +setting reply parameters against individual devices. + +In general, FreeRADIUS does not differentiate between "classes" (memberships +defined by some attribute of the DHCP request) and "groups" (memberships +defined by some manually aggregation related devices, typically based on lists +of MAC address). + +The sample DHCP configuration provided with FreeRADIUS makes use of an internal +attribute `DHCP-Group-Name` to support the setting of different options for +different groups of devices. + +In general the groups to which a device belongs is determined during the +processing of a request and these are added as instances of the +`DHCP-Group-Name` attribute. This may be by performing a test on one or more +request parameters (akin to a "class"), hash-based lookup of up all of part of +an attribute in a local list (akin to a "subclass"), or doing the same using a +remote datastore (SQL, LDAP, REST API, etc). + +FreeRADIUS can then iterate over `DHCP-Group-Name` to set group-specific +options. + +We describe some of these options in more detail. + +=== Directly in Policy + +Simple class options can be written directly into policy. This is most +suited to those options that rarely change and are based on attributes in the +request such as the `User-Class`. + +Consider the ISC DHCP configuration snippet: + +[source,iscdhcp] +---- +filename "undionly.kpxe"; +class "pxeclient" { + match option substring(user-class,0,4); +} +subclass "pxeclient" "iPXE" { + filename "http://my.web.server/boot_script.php"; +} +---- + +Or the equivalent Kea configuration: + +[source,isckea] +---- +"Dhcp4": { + "option-data": [ + { "name": "boot-file-name", "data": "undionly.kpxe" } + ], + "client-classes": [ + { + "name": "pxeclient", + "test": "substring(option[77],0,4) == 'iPXE'", + "option-data": [ + { + "name": "boot-file-name", + "data": "http://my.web.server/boot_script.php" + } + ] + } + ] + ... +} +---- + +These define the "filename" DHCP option differently based on whether or not the +supplied "user-class" option begins with "iPXE". + +FreeRADIUS provides multiple ways for this to be configured. + +For example, the following "unlang" policy implements the class options defined +above: + +[source,unlang] +---- +if (&DHCP-User-Class && "%{substring:&DHCP-User-Class 0 4}" == "iPXE") { + update reply { + &DHCP-Boot-Filename := "http://my.web.server/boot_script.php" + } +} else { + update reply { + &DHCP-Boot-Filename := "undionly.kpxe" + } +} +---- + +Policy-based configuration of DHCP options is also useful for complex matching. +For example, the following Unlang sets the DHCP-Boot-Filename parameter based +on the request's DHCP-Client-Identifier using regular expression captures, +provided that it matches the given format: + +[source,unlang] +---- +if (&DHCP-Client-Identifier && \ + "%{string:DHCP-Client-Identifier}" =~ /^RAS([0-9])-site([A-Z])$/) { + update reply { + &DHCP-Boot-Filename := "rasboot-%{1}-%{2}.kpxe" + } +} +---- + +=== In Text Files + +The `files` module that has already been described for global, network and +subnet options can also be used to apply options to groups of clients. + +Firstly we must defined a mapping from a set of clients clients to their +respective groups. One option for this is to use the `passwd` module, for +which a sample configuration is included. + +Firstly symlink or copy the module configuration +`/mods-available/dhcp_passwd` into `/mods-enabled/`. The +suggested configuration expects the group membership file to be in +`/mods-config/files/dhcp_groups` and take the form of: + +[source,config] +---- +|,, +|, +---- + +i.e. one line for each group starting with the group name followed by a pipe +character and then a comma-separated list of hardware addresses. + +The `allow_multiple_keys` option allows for a host to be a member of +more than one group. + +Sample configuration for looking up group options is contained in +`/policy.d/dhcp` in the `dhcp_group_options` policy and in +`/mods-available/dhcp_files` as the `dhcp_set_group_options` instance. + +The same data file `/mods-config/files/dhcp` is used to lookup +group options as was used for global and network options. In this instance, +add entries with the group name as the key such as: + +[source,config] +---- +group1 + DHCP-Log-Server := 10.10.0.100, + DHCP-LPR-Server := 10.10.0.200 + +group2 + DHCP-LPR-Server := 192.168.20.200 +---- + +=== In the SQL Database + +Policy and files are both read during startup and editing them while +FreeRADIUS is running will not result in any changes in behaviour. If +you require regular changes to DHCP options, then storing them in +an SQL database provides greater flexibility since the queries will be run in +response to each DHCP packet rather than requiring the server to be restarted. + +DHCP reply options for devices (including network-specific options) can be +fetched from SQL using an arbitrary lookup key. This can be performed multiple +times as necessary using different contexts, for example to first set +subnet-specific options and then to set group-specific options. + +The default schema contains three tables to support this: + +"dhcpreply" contains reply options for a given identifier (e.g. MAC Address): + +.dhcpreply table +|=== +|Identifier |Attribute |Op |Value |Context + +|`02:01:aa:bb:cc:dd` |`DHCP-Log-Server` |`:=` |`192.0.2.10` |`by-mac` +|`02:01:aa:bb:cc:dd` |`DHCP-LPR-Server` |`:=` |`192.0.2.11` |`by-mac` +|`02:01:aa:bb:cc:dd` |`Fall-Through` |`:=` |`Yes` |`by-mac` +|=== + +"dhcpgroup" maps identifiers to a group of options that can be shared: + +.dhcpgroup table +|=== +|Identifier |GroupName |Priority |Context + +|`02:01:aa:bb:cc:dd` |`salesdept` |`10` |`by-mac` +|=== + +"dhcpgroupreply" contains reply options for each group: + +.dhcpgroupreply table +|=== +|GroupName |Attribute |Op |Value |Context + +|`salesdept` |`DHCP-NTP-Servers` |`:=` |`192.0.2.20` |`by-mac` +|`salesdept` |`DHCP-Log-Server` |`+=` |`192.0.2.21` |`by-mac` +|`salesdept` |`DHCP-LPR-Server` |`^=` |`192.0.2.22` |`by-mac` +|=== + +Within the context of assigning options directly to devices, as well as to +manually-curated groups of devices keyed by their MAC address: + + - Place device-specific options in the "dhcpreply" table. + - Add `Fall-Through := Yes` to the options in the "dhcpreply" table in order + to trigger group lookups, which are disabled by default. + - Place entries in the "dhcpgroup" `identifier = , groupname = , priority = + ` in the "dhcpgroup" table to map a device to its groups by + priority. + - Place the grouped options in the "dhcpgroupreply" table. + - For each of the above, set `Context` to something by which the option + lookup is referred to in the policy, for example `Context = 'by-mac'`. + +For the above example you would add the following to the DHCP virtual server to +perform reply option lookup using the device's MAC address against the `by-mac` +context: + +[source,unlang] +---- +update control { + &DHCP-SQL-Option-Context := "by-mac" + &DHCP-SQL-Option-Identifier := &request:DHCP-Client-Hardware-Address +} +dhcp_sql.authorize +---- + +In the above, the DHCP reply options would be assigned to a device with MAC +address 02:01:aa:bb:cc:dd as follows: + + - Firstly, the `DHCP-Log-Server` option would be set to `192.0.2.10` and the + `DHCP-LPR-Server` option set to `192.0.2.11`. + - `Fall-Through` is set, so the group mapping is then queried which + determines that the device belongs to a single `salesdept` group. + - Finally, the options for the `salesdept` group are now merged, setting a + `DHCP-NTP-Servers` option to `192.0.2.20`, appending an additional + `DHCP-Log-Server` option set to `192.0.2.21`, and prepending an additional + `DHCP-LPR-Server` option set to `192.0.2.22`. + +If instead you wanted to perform a "subclass" lookup based on the first three +octets of the device's MAC address then with tables containing the following +sample data you could invoke an SQL lookup as shown: + +."dhcpreply" table: +|=== +|Identifier |Attribute |Op |Value |Context + +|`000393` |`Fall-Through` |`:=` |`Yes` |`class-vendor` +|`000a27` |`Fall-Through` |`:=` |`Yes` |`class-vendor` +|`f40304` |`Fall-Through` |`:=` |`Yes` |`class-vendor` +|=== + +."dhcpgroup" table: +|=== +|Identifier |GroupName |Priority |Context + +|`000393` |`apple` |`10` |`class-vendor` +|`000a27` |`apple` |`10` |`class-vendor` +|`f40304` |`google` |`10` |`class-vendor` +|=== + +."dhcpgroupreply" table: +|=== +|GroupName |Attribute |Op |Value |Context + +|`apple` |`DHCP-Boot-Filename` |`:=` |`apple.efi` |`class-vendor` +|`google` |`DHCP-Boot-Filename` |`:=` |`google.efi` |`class-vendor` +|=== + + +[source,unlang] +---- +update control { + &DHCP-SQL-Option-Context := "class-vendor" + &DHCP-SQL-Option-Identifier := \ + "%{substring:%{hex:&DHCP-Client-Hardware-Address} 0 6}" +} +dhcp_sql.authorize +---- + +The file `policy.d/dhcp` contains a policy named `dhcp_policy_sql` which +provides further worked examples for different types of option lookups. + +=== Testing "device", "class" and "group" options + +You should now test that any device-related options that you have configured +using the various methods available are applied successfully by generating +packets containing those parameters based upon which the reply options are set. + +For example, to test the iPXE user class example above you might want to +generate a request as follows: + +[source,shell] +---- +cat < dhcp-packet-ipxe-boot.txt +DHCP-Message-Type := DHCP-Discover +DHCP-Client-Hardware-Address := 02:01:aa:bb:cc:dd +DHCP-User-Class := "iPXE-class-abc" +EOF +---- + +To which you would expect to see a response such as: + +.Example output from dhcpclient +=============================== + dhcpclient: ... + ---------------------------------------------------------------------- + Waiting for DHCP replies for: 5.000000 + ---------------------------------------------------------------------- + ... + DHCP-Message-Type = DHCP-Offer + DHCP-Your-IP-Address = 1.2.3.4 + DHCP-Boot-Filename := "http://my.web.server/boot_script.php" + ... +=============================== -- cgit v1.2.3