Chapter 35. Setting up an 802.1x network authentication service for LAN clients by using hostapd with FreeRADIUS backend
The IEEE 802.1X standard defines secure authentication and authorization methods to protect networks from unauthorized clients. By using the hostapd
service and FreeRADIUS, you can provide network access control (NAC) in your network.
Red Hat supports only FreeRADIUS with Red Hat Identity Management (IdM) as the backend source of authentication.
In this documentation, the RHEL host acts as a bridge to connect different clients with an existing network. However, the RHEL host grants only authenticated clients access to the network.
35.1. Prerequisites
A clean installation of the
freeradius
andfreeradius-ldap
packages.If the packages are already installed, remove the
/etc/raddb/
directory, uninstall and then install the packages again. Do not reinstall the packages by using thednf reinstall
command, because the permissions and symbolic links in the/etc/raddb/
directory are then different.- The host on which you want to configure FreeRADIUS is a client in an IdM domain.
35.2. Setting up the bridge on the authenticator
A network bridge is a link-layer device which forwards traffic between hosts and networks based on a table of MAC addresses. If you set up RHEL as an 802.1X authenticator, add both the interfaces on which to perform authentication and the LAN interface to the bridge.
Prerequisites
- The server has multiple Ethernet interfaces.
Procedure
If the bridge interface does not exist, create it:
# nmcli connection add type bridge con-name br0 ifname br0
Assign the Ethernet interfaces to the bridge:
# nmcli connection add type ethernet port-type bridge con-name br0-port1 ifname enp1s0 controller br0 # nmcli connection add type ethernet port-type bridge con-name br0-port2 ifname enp7s0 controller br0 # nmcli connection add type ethernet port-type bridge con-name br0-port3 ifname enp8s0 controller br0 # nmcli connection add type ethernet port-type bridge con-name br0-port4 ifname enp9s0 controller br0
Enable the bridge to forward extensible authentication protocol over LAN (EAPOL) packets:
# nmcli connection modify br0 group-forward-mask 8
Configure the connection to automatically activate the ports:
# nmcli connection modify br0 connection.autoconnect-ports 1
Activate the connection:
# nmcli connection up br0
Verification
Display the link status of Ethernet devices that are ports of a specific bridge:
# ip link show master br0 3: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UP mode DEFAULT group default qlen 1000 link/ether 52:54:00:62:61:0e brd ff:ff:ff:ff:ff:ff ...
Verify if forwarding of EAPOL packets is enabled on the
br0
device:# cat /sys/class/net/br0/bridge/group_fwd_mask 0x8
If the command returns
0x8
, forwarding is enabled.
Additional resources
-
nm-settings(5)
man page on your system
35.3. Configuring FreeRADIUS to authenticate network clients securely by using EAP
FreeRADIUS supports different methods of the Extensible authentication protocol (EAP). However, for a supported and secure scenario, use EAP-TTLS (tunneled transport layer security).
With EAP-TTLS, the clients use a secure TLS connection as the outer authentication protocol to set up the tunnel. The inner authentication then uses LDAP to authenticate to Identity Management. To use EAP-TTLS, you need a TLS server certificate.
The default FreeRADIUS configuration files serve as documentation and describe all parameters and directives. If you want to disable certain features, comment them out instead of removing the corresponding parts in the configuration files. This enables you to preserve the structure of the configuration files and the included documentation.
Prerequisites
-
You installed the
freeradius
andfreeradius-ldap
packages. -
The configuration files in the
/etc/raddb/
directory are unchanged and as provided by thefreeradius
packages. - The host is enrolled in a Red Hat Identity Management (IdM) domain.
Procedure
Create a private key and request a certificate from IdM:
# ipa-getcert request -w -k /etc/pki/tls/private/radius.key -f /etc/pki/tls/certs/radius.pem -o "root:radiusd" -m 640 -O "root:radiusd" -M 640 -T caIPAserviceCert -C 'systemctl restart radiusd.service' -N freeradius.idm.example.com -D freeradius.idm.example.com -K radius/freeradius.idm.example.com
The
certmonger
service stores the private key in the/etc/pki/tls/private/radius.key
file and the certificate in the/etc/pki/tls/certs/radius.pem
file, and it sets secure permissions. Additionally,certmonger
will monitor the certificate, renew it before it expires, and restart theradiusd
service after the certificate was renewed.Verify that the CA successfully issued the certificate:
# ipa-getcert list -f /etc/pki/tls/certs/radius.pem ... Number of certificates and requests being tracked: 1. Request ID '20240918142211': status: MONITORING stuck: no key pair storage: type=FILE,location='/etc/pki/tls/private/radius.key' certificate: type=FILE,location='/etc/pki/tls/certs/radius.crt' ...
Create the
/etc/raddb/certs/dh
file with Diffie-Hellman (DH) parameters. For example, to create a DH file with a 2048 bits prime, enter:# openssl dhparam -out /etc/raddb/certs/dh 2048
For security reasons, do not use a DH file with less than a 2048 bits prime. Depending on the number of bits, the creation of the file can take several minutes.
Edit the
/etc/raddb/mods-available/eap
file:Configure the TLS-related settings in the
tls-config tls-common
directive:eap { ... tls-config tls-common { ... private_key_file = /etc/pki/tls/private/radius.key certificate_file = /etc/pki/tls/certs/radius.pem ca_file = /etc/ipa/ca.crt ... } }
Set the
default_eap_type
parameter in theeap
directive tottls
:eap { ... default_eap_type = ttls ... }
Comment out the
md5
directives to disable the insecure EAP-MD5 authentication method:eap { ... # md5 { # } ... }
Note that, in the default configuration file, other insecure EAP authentication methods are commented out by default.
Edit the
/etc/raddb/sites-available/default
file, and comment out all authentication methods other thaneap
:authenticate { ... # Auth-Type PAP { # pap # } # Auth-Type CHAP { # chap # } # Auth-Type MS-CHAP { # mschap # } # mschap # digest ... }
This leaves only EAP enabled for the outer authentication and disables plain-text authentication methods.
Edit the
/etc/raddb/sites-available/inner-tunnel
file, and make the following changes:Comment out the
-ldap
entry and add theldap
module configuration to theauthorize
directive:authorize { ... #-ldap ldap if ((ok || updated) && User-Password) { update { control:Auth-Type := ldap } } ... }
Uncomment the LDAP authentication type in the
authenticate
directive:authenticate { Auth-Type LDAP { ldap } }
Enable the
ldap
module:# ln -s /etc/raddb/mods-available/ldap /etc/raddb/mods-enabled/ldap
Edit the
/etc/raddb/mods-available/ldap
file, and make the following changes:In the
ldap
directive, set the IdM LDAP server URL and the base distinguished name (DN):ldap { ... server = 'ldaps://idm_server.idm.example.com' base_dn = 'cn=users,cn=accounts,dc=idm,dc=example,dc=com' ... }
Specify the
ldaps
protocol in the server URL to use TLS-encrypted connections between the FreeRADIUS host and the IdM server.In the
ldap
directive, enable TLS certificate validation of the IdM LDAP server:tls { ... require_cert = 'demand' ... }
Edit the
/etc/raddb/clients.conf
file:Set a secure password in the
localhost
andlocalhost_ipv6
client directives:client localhost { ipaddr = 127.0.0.1 ... secret = localhost_client_password ... } client localhost_ipv6 { ipv6addr = ::1 secret = localhost_client_password }
Add a client directive for the network authenticator:
client hostapd.example.org { ipaddr = 192.0.2.2/32 secret = hostapd_client_password }
Optional: If other hosts should also be able to access the FreeRADIUS service, add client directives for them as well, for example:
client <hostname_or_description> { ipaddr = <IP_address_or_range> secret = <client_password> }
The
ipaddr
parameter accepts IPv4 and IPv6 addresses, and you can use the optional classless inter-domain routing (CIDR) notation to specify ranges. However, you can set only one value in this parameter. For example, to grant access to both an IPv4 and IPv6 address, you must add two client directives.Use a descriptive name for the client directive, such as a hostname or a word that describes where the IP range is used.
Verify the configuration files:
# radiusd -XC ... Configuration appears to be OK
Open the RADIUS ports in the
firewalld
service:# firewall-cmd --permanent --add-service=radius # firewall-cmd --reload
Enable and start the
radiusd
service:# systemctl enable --now radiusd
Troubleshooting
If the
radiusd
service fails to start, verify that you can resolve the IdM server host name:# host -v idm_server.idm.example.com
For other problems, run
radiusd
in debug mode:Stop the
radiusd
service:# systemctl stop radiusd
Start the service in debug mode:
# radiusd -X ... Ready to process requests
-
Perform authentication tests on the FreeRADIUS host, as referenced in the
Verification
section.
Next steps
- Disable no longer required authentication methods and other features you do not use.
35.4. Configuring hostapd
as an authenticator in a wired network
The host access point daemon (hostapd
) service can act as an authenticator in a wired network to provide 802.1X authentication. For this, the hostapd
service requires a RADIUS server that authenticates the clients.
The hostapd
service provides an integrated RADIUS server. However, use the integrated RADIUS server only for testing purposes. For production environments, use FreeRADIUS server, which supports additional features, such as different authentication methods and access control.
The hostapd
service does not interact with the traffic plane. The service acts only as an authenticator. For example, use a script or service that uses the hostapd
control interface to allow or deny traffic based on the result of authentication events.
Prerequisites
-
You installed the
hostapd
package. - The FreeRADIUS server has been configured, and it is ready to authenticate clients.
Procedure
Create the
/etc/hostapd/hostapd.conf
file with the following content:# General settings of hostapd # =========================== # Control interface settings ctrl_interface=/var/run/hostapd ctrl_interface_group=wheel # Enable logging for all modules logger_syslog=-1 logger_stdout=-1 # Log level logger_syslog_level=2 logger_stdout_level=2 # Wired 802.1X authentication # =========================== # Driver interface type driver=wired # Enable IEEE 802.1X authorization ieee8021x=1 # Use port access entry (PAE) group address # (01:80:c2:00:00:03) when sending EAPOL frames use_pae_group_addr=1 # Network interface for authentication requests interface=br0 # RADIUS client configuration # =========================== # Local IP address used as NAS-IP-Address own_ip_addr=192.0.2.2 # Unique NAS-Identifier within scope of RADIUS server nas_identifier=hostapd.example.org # RADIUS authentication server auth_server_addr=192.0.2.1 auth_server_port=1812 auth_server_shared_secret=hostapd_client_password # RADIUS accounting server acct_server_addr=192.0.2.1 acct_server_port=1813 acct_server_shared_secret=hostapd_client_password
For further details about the parameters used in this configuration, see their descriptions in the
/usr/share/doc/hostapd/hostapd.conf
example configuration file.Enable and start the
hostapd
service:# systemctl enable --now hostapd
Troubleshooting
If the
hostapd
service fails to start, verify that the bridge interface you use in the/etc/hostapd/hostapd.conf
file is present on the system:# ip link show br0
For other problems, run
hostapd
in debug mode:Stop the
hostapd
service:# systemctl stop hostapd
Start the service in debug mode:
# hostapd -d /etc/hostapd/hostapd.conf
-
Perform authentication tests on the FreeRADIUS host, as referenced in the
Verification
section.
Additional resources
-
hostapd.conf(5)
man page on your system -
/usr/share/doc/hostapd/hostapd.conf
file
35.5. Testing EAP-TTLS authentication against a FreeRADIUS server or authenticator
To test if authentication by using extensible authentication protocol (EAP) over tunneled transport layer security (EAP-TTLS) works as expected, run this procedure:
- After you set up the FreeRADIUS server
-
After you set up the
hostapd
service as an authenticator for 802.1X network authentication.
The output of the test utilities used in this procedure provide additional information about the EAP communication and help you to debug problems.
Prerequisites
When you want to authenticate to:
A FreeRADIUS server:
-
The
eapol_test
utility, provided by thehostapd
package, is installed. - The client, on which you run this procedure, has been authorized in the FreeRADIUS server’s client databases.
-
The
-
An authenticator, the
wpa_supplicant
utility, provided by the same-named package, is installed.
-
You stored the certificate authority (CA) certificate in the
/etc/ipa/ca.cert
file.
Procedure
Optional: Create a user in Identity Management (IdM):
# ipa user-add --first "Test" --last "User" idm_user --password
Create the
/etc/wpa_supplicant/wpa_supplicant-TTLS.conf
file with the following content:ap_scan=0 network={ eap=TTLS eapol_flags=0 key_mgmt=IEEE8021X # Anonymous identity (sent in unencrypted phase 1) # Can be any string anonymous_identity="anonymous" # Inner authentication (sent in TLS-encrypted phase 2) phase2="auth=PAP" identity="idm_user" password="idm_user_password" # CA certificate to validate the RADIUS server's identity ca_cert="/etc/ipa/ca.crt" }
To authenticate to:
A FreeRADIUS server, enter:
# eapol_test -c /etc/wpa_supplicant/wpa_supplicant-TTLS.conf -a 192.0.2.1 -s <client_password> ... EAP: Status notification: remote certificate verification (param=success) ... CTRL-EVENT-EAP-SUCCESS EAP authentication completed successfully ... SUCCESS
The
-a
option defines the IP address of the FreeRADIUS server, and the-s
option specifies the password for the host on which you run the command in the FreeRADIUS server’s client configuration.An authenticator, enter:
# wpa_supplicant -c /etc/wpa_supplicant/wpa_supplicant-TTLS.conf -D wired -i enp0s31f6 ... enp0s31f6: CTRL-EVENT-EAP-SUCCESS EAP authentication completed successfully ...
The
-i
option specifies the network interface name on whichwpa_supplicant
sends out extended authentication protocol over LAN (EAPOL) packets.For more debugging information, pass the
-d
option to the command.
Additional resources
-
/usr/share/doc/wpa_supplicant/wpa_supplicant.conf
file
35.6. Blocking and allowing traffic based on hostapd
authentication events
The hostapd
service does not interact with the traffic plane. The service acts only as an authenticator. However, you can write a script to allow and deny traffic based on the result of authentication events.
This procedure is not supported and is no enterprise-ready solution. It only demonstrates how to block or allow traffic by evaluating events retrieved by hostapd_cli
.
When the 802-1x-tr-mgmt
systemd service starts, RHEL blocks all traffic on the listen port of hostapd
except extensible authentication protocol over LAN (EAPOL) packets and uses the hostapd_cli
utility to connect to the hostapd
control interface. The /usr/local/bin/802-1x-tr-mgmt
script then evaluates events. Depending on the different events received by hostapd_cli
, the script allows or blocks traffic for MAC addresses. Note that, when the 802-1x-tr-mgmt
service stops, all traffic is automatically allowed again.
Perform this procedure on the hostapd
server.
Prerequisites
-
The
hostapd
service has been configured, and the service is ready to authenticate clients.
Procedure
Create the
/usr/local/bin/802-1x-tr-mgmt
file with the following content:#!/bin/sh TABLE="tr-mgmt-${1}" read -r -d '' TABLE_DEF << EOF table bridge ${TABLE} { set allowed_macs { type ether_addr } chain accesscontrol { ether saddr @allowed_macs accept ether daddr @allowed_macs accept drop } chain forward { type filter hook forward priority 0; policy accept; meta ibrname "br0" jump accesscontrol } } EOF case ${2:-NOTANEVENT} in block_all) nft destroy table bridge "$TABLE" printf "$TABLE_DEF" | nft -f - echo "$1: All the bridge traffic blocked. Traffic for a client with a given MAC will be allowed after 802.1x authentication" ;; AP-STA-CONNECTED | CTRL-EVENT-EAP-SUCCESS | CTRL-EVENT-EAP-SUCCESS2) nft add element bridge tr-mgmt-br0 allowed_macs { $3 } echo "$1: Allowed traffic from $3" ;; AP-STA-DISCONNECTED | CTRL-EVENT-EAP-FAILURE) nft delete element bridge tr-mgmt-br0 allowed_macs { $3 } echo "$1: Denied traffic from $3" ;; allow_all) nft destroy table bridge "$TABLE" echo "$1: Allowed all bridge traffice again" ;; NOTANEVENT) echo "$0 was called incorrectly, usage: $0 interface event [mac_address]" ;; esac
Create the
/etc/systemd/system/802-1x-tr-mgmt@.service
systemd service file with the following content:[Unit] Description=Example 802.1x traffic management for hostapd After=hostapd.service After=sys-devices-virtual-net-%i.device [Service] Type=simple ExecStartPre=bash -c '/usr/sbin/hostapd_cli ping | grep PONG' ExecStartPre=/usr/local/bin/802-1x-tr-mgmt %i block_all ExecStart=/usr/sbin/hostapd_cli -i %i -a /usr/local/bin/802-1x-tr-mgmt ExecStopPost=/usr/local/bin/802-1x-tr-mgmt %i allow_all [Install] WantedBy=multi-user.target
Reload systemd:
# systemctl daemon-reload
Enable and start the
802-1x-tr-mgmt
service with the interface namehostapd
is listening on:# systemctl enable --now 802-1x-tr-mgmt@br0.service
Verification
- Authenticate with a client to the network. See Testing EAP-TTLS authentication against a FreeRADIUS server or authenticator.
Additional resources
-
systemd.service(5)
man page on your system