OUR SITES NetworkRADIUS FreeRADIUS

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:

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:

"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.

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.

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 <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.

A template configuration file <raddb>/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):

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 <Attribute> <op> <Value>. In the case of the second block we match the DHCP-Network-Subnet to an enclosing subnet with DHCP-Network-Subnet < <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 <Attribute> := <Value>. 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 <raddb>/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.

cat <<EOF > dhcp-packet-1.txt
DHCP-Message-Type := DHCP-Discover
DHCP-Client-Hardware-Address := 02:01:11:11:11:11
DHCP-Client-Identifier := device1
EOF
cat <<EOF > 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:

cat <<EOF > 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.