== Configure network-specific options and IP pool selection In an environment where multiple networks (often VLANs) are in use, it is necessary to identify which network a client belongs to in order to assign an address from the correct pool. Consider the ISC DHCP configuration snippet: [source,iscdhcp] ---- option domain-name "example.org"; subnet 10.10.0.0 netmask 255.255.0.0 { range 10.10.1.10 10.10.10.254; range 10.10.100.10 10.10.110.254; option routers 10.10.0.1; option domain-name-servers 10.10.0.2, 10.10.0.3; default-lease-time 7200; } ---- Or the equivalent Kea configuration: [source,isckea] ---- "Dhcp4": { "option-data": [ { "name": "domain-name", "data": "example.org" } ], "subnet4": [{ "subnet": "10.10.0.0/16", "pools": [ { "pool": "10.10.1.10 - 10.10.10.254" }, { "pool": "10.10.100.10 - 10.10.110.254" } ], "option-data": [ { "name": "routers", "data": "10.10.0.1" }, { "name": "domain-name-servers", "data": "10.10.0.2, 10.10.0.3" } ], "valid-lifetime": 7200 }], ... } ---- These define a network consisting of a single subnet 10.10.0.0/16 containing two IP address pools 10.10.1.10 - 10.10.10.254 and 10.10.100.10 - 10.10.110.254. Requests that are determined to have originated from this network (e.g. because their `giaddr` belongs within the subnet) will be assigned the specified DHCP parameters and allocated an address from one of its ranges. To provide equivalent functionality, FreeRADIUS must identify the correct DHCP reply parameters as well as the name of the pool to be used for IP address assignment, based on the originating network of the request. The definition for this pool (the addresses contained within it, corresponding to the `range` statement in ISC DHCP and Kea) is specified entirely in the database: It is precisely the rows in the `dhcpippool` table with a particular `pool_name`. [TIP] ==== As described previously, in FreeRADIUS a pool is a set of IP addresses that are equally valid with respect to the network policy; therefore, unlike ISC DHCP and ISC Kea, FreeRADIUS does not differentiate between the two `range`s. 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 honours the standard DHCP process for designating the choice of network, in order of preference: 1. Link Selection Suboption of Option 82 2. IPv4 Subnet Selection Option 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 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 membership, setting the appropriate options to return to clients. It can also set the global options. [TIP] ==== In the case where an instance of the `files` module is used to get global default parameters, the `dhcp_common` policy becomes redundant so the statement calling the policy (by name) can be commented out in `/sites-enabled/dhcp`. ==== To use the provided example `files` module instance for DHCP, symlink or copy `/mods-available/dhcp_files` into `/mods-enabled/` and then uncomment the calls to `dhcp_network` in `/sites-enabled/dhcp`. A template configuration file `/mods-config/files/dhcp` is also provided which should be adapted to suit your network topology. For the configuration above you may deduce the following configuration, which has been extended to include an initial default section for requests originating from directly-connected clients on the local LAN (192.168.20/24): [source,config] ---- network Pool-Name := "local" DHCP-Domain-Name := "example.org", DHCP-Subnet-Mask := 255.255.255.0, DHCP-Router-Address := 192.168.20.1, DHCP-Domain-Name-Server := 192.168.20.2, Fall-Through := yes network DHCP-Network-Subnet < 10.10.0.0/16, Pool-Name := "remote" DHCP-Subnet-Mask := 255.0.0.0, DHCP-Router-Address := 10.10.0.1, DHCP-Domain-Name-Server := 10.10.0.2, DHCP-Domain-Name-Server += 10.10.0.3, DHCP-IP-Address-Lease-Time := 7200 ---- 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. There may be further filtering of the candidates in the form of ` `. In the case of the second block we match the `DHCP-Network-Subnet` to an enclosing subnet with `DHCP-Network-Subnet < `. Additional filters could be added as required, comma separated. Following the filters on the first line, attributes in the `control` list can be set using the syntax of ` := `. In this example this is used to specify the `Pool-Name` for choosing the appropriate IP pool to allocate an address from. Subsequent indented lines are attribute assignments for values in the `reply` list. Note that, apart from the last line, they are all terminated with a 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` is set on that record in order that the other records will be tested to find subnet matches. === Example packet processing 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 relay's IP address, say 10.10.0.1. The request is matched against the first block, setting an initial pool name to "local", domain name to "example.org" and setting some additional global default parameters. By virtue of `Fall-Through` being set, the next block is considered. Since the network identifier is within the specified subnet (i.e. `10.10.0.1 < 10.10.0.0/16`) this second block is matched. This block overrides the pool name 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 `/sites-enabled/dhcp`) the `remote` pool will be used for IP address allocation. The assigned IP address and network parameters will subsequently be returned in the DHCP reply. === Testing the pool operation and network-specific options Before proceeding further, you should test the operation of the IP pools and ensure that any network-specific reply attributes that you have configured are correctly set in replies. For example, if you have a single, flat pool you should test using sample packets for devices with different MAC addresses and/or Client Identifiers. [source,shell] ---- cat < dhcp-packet-1.txt DHCP-Message-Type := DHCP-Discover DHCP-Client-Hardware-Address := 02:01:11:11:11:11 DHCP-Client-Identifier := device1 EOF ---- [source,shell] ---- cat < dhcp-packet-2.txt DHCP-Message-Type := DHCP-Discover DHCP-Client-Hardware-Address := 02:01:22:22:22:22 DHCP-Client-Identifier := device2 EOF ---- Generate these packets as show previously using the dhcpclient tool and look for `DHCP-Your-IP-Address` in the DHCP responses to determine the IP address that has been offered. Ensure that the DHCP Offer responses contain unique IP addresses. Ensure that when these requests are resent within the lifetime of the initial offer that the reponses to the subsequent replies contain the original IP address that was in the initial offer to the device. Additionally, ensure that the DHCP Offers contain any network-specific parameters that you have specified. In the case that the policy contains multiple IP pools and network definitions for clients belonging to different Layer 2 networks (or indeed belonging to the same network but segregated according to some local policy) you should ensure that the devices are being mapped to the correct definition. For a typical policy that selects the IP pool and network options based on the originating network for the DHCP packet, explicitly specifying a network by including a `DHCP-Subnet-Selection-Option` parameter may avoid the need to test from a host within each individual network: [source,shell] ---- cat < dhcp-packet-network-10.10.10.0.txt DHCP-Message-Type := DHCP-Discover DHCP-Client-Hardware-Address := 02:01:aa:bb:cc:dd DHCP-Client-Identifier := abc123 DHCP-Subnet-Selection-Option := 10.10.10.0 EOF ---- For policies where the IP pool and network option selection is based on some custom criteria it is necessary to include different variations for the parameters on which the policy makes the decision. The testing example for the class-specific options later in this document provides such an example.