]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Rework DHCP docs with v4 attribute names and improved rlm_files capabilities
authorNick Porter <nick@portercomputing.co.uk>
Mon, 27 Oct 2025 09:32:32 +0000 (09:32 +0000)
committerNick Porter <nick@portercomputing.co.uk>
Mon, 27 Oct 2025 09:35:21 +0000 (09:35 +0000)
doc/antora/modules/howto/pages/protocols/dhcp/enable.adoc
doc/antora/modules/howto/pages/protocols/dhcp/policy_device_options.adoc
doc/antora/modules/howto/pages/protocols/dhcp/policy_ippool_access.adoc
doc/antora/modules/howto/pages/protocols/dhcp/policy_ippool_creation.adoc
doc/antora/modules/howto/pages/protocols/dhcp/policy_network_options.adoc
doc/antora/modules/howto/pages/protocols/dhcp/policy_subnet_options.adoc

index 8d152dc5f8cdabfe15edf16edb90f62e873b01c9..de74acea95cee3ec016b2cf4552e1ad80bae40e5 100644 (file)
@@ -63,7 +63,7 @@ modify the following configuration items:
 
 Below the `listen` section, there are sections that define how to respond to
 each of the DHCP packet types.  Most installations will require that you review
-the settings for `DHCP-Discover` and `DHCP-Request`.
+the settings for `recv Discover` and `recv Request`.
 
 Their contents contain directives in the FreeRADIUS policy language, "unlang".
 Many examples are provided which have been carefully described.
@@ -73,21 +73,21 @@ Many examples are provided which have been carefully described.
 
 FreeRADIUS has many modules to support different aspects of the functionality
 required for the network protocols it can process. The two of most significance
-for DHCP are `dhcp_sql` and `dhcp_sqlippool`.  As with virtual servers, a
+for DHCP are `sql` and `sqlippool`.  As with virtual servers, a
 number of example module configurations are available in
 `<raddb>/mods-available`.
 These should be symlinked or copied into `<raddb>/mods-enabled` in order to
 enable them.
 
 
-=== Configure the `dhcp_sql` module
+=== Configure the `sql` module
 
-Add the `dhcp_sql` module to the active configuration:
+Add the `sql` module to the active configuration:
 
 [source,shell]
 ----
 cd <raddb>/mods-enabled
-ln -s ../mods-available/dhcp_sql .
+ln -s ../mods-available/sql .
 ----
 
 or:
@@ -95,10 +95,10 @@ or:
 [source,shell]
 ----
 cd <raddb>/mods-enabled
-cp ../mods-available/dhcp_sql .
+cp ../mods-available/sql .
 ----
 
-The `dhcp_sql` module should be configured with the connection parameters for
+The `sql` module should be configured with the connection parameters for
 whichever database is to be used.  The key configuration items are:
 
 `dialect`:: Which SQL dialect is in use.
@@ -118,19 +118,19 @@ including connection details.  For most databases these are:
 [NOTE]
 ====
 SQLite does not use these connection options, rather the `filename`
-option within the `sqlite` section is used to determine where the database
-will be stored.
+option in the `sqlite` driver options found in `<raddb>/mods-config/sql/driver/sqlite`
+is used to determine where the database will be stored.
 ====
 
 
-=== Configure the `dhcp_sqlippool` module
+=== Configure the `sqlippool` module
 
-Add the `dhcp_sqlippool` module to the active configuration:
+Add the `sqlippool` module to the active configuration:
 
 [source,shell]
 ----
 cd <raddb>/mods-enabled
-ln -s ../mods-available/dhcp_sqlippool .
+ln -s ../mods-available/sqlippool .
 ----
 
 or
@@ -138,15 +138,19 @@ or
 [source,shell]
 ----
 cd <raddb>/mods-enabled
-cp ../mods-available/dhcp_sqlippool .
+cp ../mods-available/sqlippool .
 ----
 
-The `dhcp_sqlippool` module must be configured. The key configuration
+The `sqlippool` module must be configured. The key configuration
 items are:
 
 `dialect`:: Set this to the same SQL dialect as in the `sql` module.
 `offer_duration`:: How long an IP is offered to the client in a DHCP OFFER.
 `lease_duration`:: How long an IP is leased to the client in a DHCP ACK.
+`allocated_address_attr`:: Which attribute should be populated with the allocated IP address - usually `reply.Your-IP-Address` for DHCPv4.
+`owner`:: How is a client device uniquely defined.  For DHCPv4 this will typically either be "%{Client-Hardware-Address}" or "%{Client-Identifier || Client-Hardware-Address".
+`requested_address`:: Which attribute contains an address the client is asking for.  For DHCPv4 this should be "%{Requested-IP-Address || Client-IP-Address}".
+`gateway`:: Which attribute identifies the gateway a request is coming via.  This should be "%{Gateway-IP-Address}".
 
 
 == Provision the database
index 80de9a0a4ae7876bb23f30e97e26292978c63ff6..cc4ed330963fd2f3b293bad07ce2f2eb379e78a9 100644 (file)
@@ -10,17 +10,17 @@ 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
+attribute `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
+`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
+FreeRADIUS can then iterate over `Group-Name` to set group-specific
 options.
 
 We describe some of these options in more detail.
@@ -107,13 +107,22 @@ 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.
+respective groups.  One option for this is to use the `passwd` module.
 
-Firstly symlink or copy the module configuration
-`<raddb>/mods-available/dhcp_passwd` into `<raddb>/mods-enabled/`.  The
-suggested configuration expects the group membership file to be in
-`<raddb>/mods-config/files/dhcp_groups` and take the form of:
+Create `<raddb>/mods-enabled/dhcp_groups`:
+
+[source,config]
+----
+passwd dhcp_groups {
+       filename = ${modconfdir}/files/dhcp_groups
+       format = "~Group-Name:*,Client-Hardware-Address"
+       hash_size = 100
+       allow_multiple_keys = yes
+       delimiter = '|'
+}
+----
+
+Then create `<raddb>/mods-config/files/dhcp_groups`
 
 [source,config]
 ----
@@ -127,13 +136,21 @@ 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
-`<raddb>/policy.d/dhcp` in the `dhcp_group_options` policy and in
-`<raddb>/mods-available/dhcp_files` as the `dhcp_set_group_options` instance.
+Having mapped the client to a group, an instance of `files` can be used to
+add reply options.
+
+Create an instance of `files` - `<raddb>/mods-enabled/dhcp_group_options`:
+
+[source,config]
+----
+files dhcp_group_options {
+       filename = ${modconfdir}/files/dhcp_group_options
+       key = Group-Name
+}
+----
 
-The same data file `<raddb>/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:
+Then create the data file '<raddb>/mods-config/files/dhcp_group_options'
+containing entries with the group name as the key such as:
 
 [source,config]
 ----
index 300a956220a62163bf315147685493d9095ded00..7b6aa26f9ede35637fa632ffb2be01726b0c6968 100644 (file)
@@ -41,12 +41,11 @@ These define a subnet containing a single pool that is restricted to members of
 the "printers" class. (The definition for this class is omitted.)
 
 In FreeRADIUS, to filter access to this pool entries such as the following
-should included in the `<raddb>/mods-config/files/dhcp` configuration file:
+should included in the `<raddb>/mods-config/files/dhcp_subnet` configuration file:
 
 [source,config]
 ----
-network Network-Subnet < 10.99.99.0/24, \
-           Group-Name == "printers", IP-Pool.Name := "printers-pool"
+10.99.99.0/24 Group-Name == "printers", IP-Pool.Name := "printers-pool"
        Router-Address := 10.99.99.1
 ----
 
index 2ade9eb963ef485b8753336fcc2481e0362ce92d..86d4459e15060ecaf89d87bdbfb18960b02f4f23 100644 (file)
@@ -108,5 +108,5 @@ FreeRADIUS database, using the mac as the identifier:
 
 [source,shell]
 ----
-rlm_iscfixed2ippool -c /etc/dhcp/dhcpd.conf -t fr_ippool -k mac -f /usr/local/etc/raddb
+rlm_iscfixed2ippool -c /etc/dhcp/dhcpd.conf -t fr_ippool -k mac -f /etc/raddb
 ----
index bc47eef2944e5a866c1009063c9e857760916e33..66a5f6c17603d9850714b0925cc00c53cdf9f5b6 100644 (file)
@@ -66,7 +66,7 @@ Instead we should have previously populated a single pool containing all of the
 IP addresses from both ranges.
 ====
 
-FreeRADIUS derives a request attribute called `DHCP-Network-Subnet` which
+FreeRADIUS derives a request attribute called `Network-Subnet` which
 honours the standard DHCP process for designating the choice of network, in
 order of preference:
 
@@ -75,13 +75,13 @@ order of preference:
   3. Gateway IP Address ("giaddr")
   4. Client IP Address ("ciaddr", only set for unicast packets)
 
-If `DHCP-Network-Subnet` contains an IP address then this should be used as
+If `Network-Subnet` contains an IP address then this should be used as
 the basis of choosing a network.  When there is no address in this attribute it
 can be assumed that the packet has been received from a client on the local
 LAN.
 
 The `files` module in FreeRADIUS provides a simple method to map
-`DHCP-Network-Subnet` to the corresponding pool based on its network
+`Network-Subnet` to the corresponding pool based on its network
 membership, setting the appropriate options to return to clients.  It can also
 set the global options.
 
@@ -93,12 +93,19 @@ statement calling the policy (by name) can be commented out in
 `<raddb>/sites-enabled/dhcp`.
 ====
 
-To use the provided example `files` module instance for DHCP, symlink or copy
-`<raddb>/mods-available/dhcp_files` into `<raddb>/mods-enabled/` and then
-uncomment the calls to `dhcp_network` in `<raddb>/sites-enabled/dhcp`.
+To use an instance of `files` to map `Network-Subnet` to reply options
+and the pool name create `<raddb>/mods-enabled/dhcp_network` containing
 
-A template configuration file `<raddb>/mods-config/files/dhcp` is also
-provided which should be adapted to suit your network topology.
+[source,config]
+----
+files dhcp_network {
+       key = Network-Subnet
+       filename = ${modconfdir}/files/dhcp_network
+}
+----
+
+Then create `<raddb>/mods-config/files/dhcp_network` with the mapping between
+subnets and options.
 
 For the configuration above you may deduce the following configuration, which
 has been extended to include an initial default section for requests originating
@@ -106,14 +113,14 @@ from directly-connected clients on the local LAN (192.168.20/24):
 
 [source,config]
 ----
-network IP-Pool.Name := "local"
+DEFAULT IP-Pool.Name := "local"
         Domain-Name := "example.org",
         Subnet-Mask := 255.255.255.0,
         Router-Address := 192.168.20.1,
         Domain-Name-Server := 192.168.20.2,
         Fall-Through := yes
 
-network Network-Subnet < 10.10.0.0/16, IP-Pool.Name := "remote"
+10.10.0.0/16 IP-Pool.Name := "remote"
         Subnet-Mask := 255.0.0.0,
         Router-Address := 10.10.0.1,
         Domain-Name-Server := 10.10.0.2,
@@ -122,15 +129,14 @@ network Network-Subnet < 10.10.0.0/16, IP-Pool.Name := "remote"
 ----
 
 Each block in the file starts with a line beginning with the key to be matched.
-In this case the keyword of `network` (defined earlier in `dhcp_networks`
-configuration) is used for each block, so each of the above blocks is a
-candidate during the search.
+In this case the subnet which Network-Subnet will be matched into.  When the
+attribute being used as a key is an IPv4 prefix (as with `Network-Subnet`)
+then the matching is done using a closest containing matches.  So, in this
+case, if `Network-Subnet` contains `10.10.3.5/32` it will match the entry with
+the key value `10.10.0.0/16`.
 
 There may be further filtering of the candidates in the form of `<Attribute>
-<op> <Value>`.  In the case of the second block we match the
-`Network-Subnet` to an enclosing subnet with
-`Network-Subnet < <subnet>`.  Additional filters could be added as
-required, comma separated.
+<op> <Value>`.
 
 Following the filters on the first line, attributes in the `control` list can
 be set using the syntax of `<Attribute> := <Value>`.  In this example this is
@@ -143,7 +149,7 @@ comma.
 
 The special option `Fall-Through` determines whether, following a match,
 other records are checked for a match.  All lookups will match the entry
-with a key of `network` and no further filtering, so `Fall-Through`
+with a key of `DEFAULT` and no further filtering, so `Fall-Through`
 is set on that record in order that the other records will be tested
 to find subnet matches.
 
@@ -151,7 +157,7 @@ to find subnet matches.
 
 For our example, we consider a request arriving from a DHCP relay within
 10.10.0.0/16. In the absence of any specific DHCP subnet selection options in
-the request, the `DHCP-Network-Subnet` attribute is calculated to be the
+the request, the `Network-Subnet` attribute is calculated to be the
 relay's IP address, say 10.10.0.1.
 
 The request is matched against the first block, setting an initial pool name to
@@ -165,7 +171,7 @@ setting it to "remote", overrides some other global defaults and sets the lease
 time to 7200 seconds. `Fall-Through` is not set, so we are now done with
 deriving the pool name and network options.
 
-When the `dhcp_sqlippool` module is called during DHCP DISCOVER processing (in
+When the `sqlippool` module is called during `recv Discover` processing (in
 `<raddb>/sites-enabled/dhcp`) the `remote` pool will be used for IP address
 allocation.
 
index a0faf0c77faeb9944141d339bdd7908213388f01..9f5e86bd00affc964362ca7f9c85e1a9562f1ef2 100644 (file)
@@ -2,8 +2,8 @@
 
 In the case that shared-networks are in use, with the pool containing
 equally-valid IP addresses from multiple subnets, it is necessary to set the
-subnet-specific parameters such as `DHCP-Router-Address`, `DHCP-Subnet-Mask`
-and `DHCP-Broadcast-Address` based on the IP address that has been allocated.
+subnet-specific parameters such as `Router-Address`, `Subnet-Mask`
+and `Broadcast-Address` based on the IP address that has been allocated.
 
 Consider the ISC DHCP configuration snippet:
 
@@ -65,39 +65,41 @@ As with the network to pool lookup, an instance of the `files` modules can be
 employed (this time after the allocation of an IP address) to set the correct
 reply parameters based on the subnet membership of the assigned address.
 
-To do this, we can use this section of `<raddb>/mods-available/dhcp_files`:
+To do this, we can create an instance of `files` - `<raddb>/mods-enabled/dhcp_subnets`:
 
 [source,config]
 ----
 files dhcp_subnets {
-    filename = ${modconfdir}/files/dhcp
-    key = "subnet"
+    filename = ${modconfdir}/files/dhcp_subnets
+    key = Network-Subnet
 }
 ----
 
-Additionally, uncomment the `dhcp_subnets` policy in `<raddb>/policy.d/dhcp`.
-This policy wraps the call to the `dhcp_subnets` files module with code that
-"tightens" the `DHCP-Network-Subnet` attribute by setting it to the
-just-allocated IP address.
+Additionally, following the call to `sqlippool` add
 
-The relevant entries in the `<raddb>/mods-config/files/dhcp` configuration
+[source,config]
+----
+Network-Subnet := reply.Your-IP-Address
+----
+
+The relevant entries in the `<raddb>/mods-config/files/dhcp_subnets` configuration
 file might then look something like this:
 
 [source,config]
 ----
-network
+DEFAULT
         Domain-Name := "example.org",
         Fall-Through := yes
 
-network Network-Subnet < 10.30.0.0/16, IP-Pool.Name := "bigdept"
+10.30.0.0/16, IP-Pool.Name := "bigdept"
         Domain-Name-Server := 10.10.0.2,
         Domain-Name-Server += 10.10.0.3,
         IP-Address-Lease-Time := 7200
 
-subnet Network-Subnet < 10.30.10.0/24
+10.30.10.0/24
        Router-Address := 10.30.10.1
 
-subnet Network-Subnet < 10.30.20.0/24
+10.30.20.0/24
        Router-Address := 10.30.20.1
 ----
 
@@ -105,26 +107,25 @@ subnet Network-Subnet < 10.30.20.0/24
 
 For our example, we consider a request arriving from a DHCP relay within
 10.30.10.0/24. In the absence of any specific DHCP subnet selection options in
-the request, the `DHCP-Network-Subnet` attribute is calculated to be the
+the request, the `Network-Subnet` attribute is calculated to be the
 relay's IP address, say 10.30.10.1.
 
-The request is matched against the first "network" block, setting the domain
-name to "example.org". By virtue of `Fall-Through` being set, the next "network"
+The request is matched against the first "DEFAULT" block, setting the domain
+name to "example.org". By virtue of `Fall-Through` being set, the next
 block is considered.
 
 Since the network identifier is within the specified subnet (i.e.  `10.30.10.1 <
-10.30.0.0/16`) this second "network" block is matched. This block sets the pool
+10.30.0.0/16`) this second block is matched. This block sets the pool
 name to "bigdept", sets some network-specific DNS resolvers and sets the lease
 time to 7200 seconds. `Fall-Through` is not set, so we are now done with
 deriving the pool name and network options.
 
-When the `dhcp_sqlippool` module is called during DHCP DISCOVER processing (in
+When the `sqlippool` module is called during `recv Discover` processing (in
 `<raddb>/sites-enabled/dhcp`) the `bigdept` pool will be used for IP address
 allocation.
 
-After IP allocation the `dhcp_subnet` policy and files instance are called.
-Before the subnet options are looked up the `DHCP-Network-Subnet`
-attribute is tightened to match the assigned IP address, say 10.30.20.123.
+After IP allocation `Network-Subnet` is set to be the assigned IP address,
+say 10.30.20.123 and then the files instance `dhcp_subnet` is called.
 
 The request does not match the first subnet block since 10.30.20.123 is not
 within 10.30.10.0/24. However, the request does match the second subnet block