Chapter 21. 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.
21.1. Prerequisites Copy linkLink copied to clipboard!
A clean installation of the
freeradiusandfreeradius-ldappackages.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 reinstallcommand, 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.
21.2. Setting up the bridge on the authenticator Copy linkLink copied to clipboard!
A network bridge is a link-layer device that 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 br0Assign 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 br0Enable the bridge to forward extensible authentication protocol over LAN (EAPOL) packets:
# nmcli connection modify br0 group-forward-mask 8Disable the Spanning Tree Protocol (STP) on the bridge device:
# *nmcli connection modify br0 stp off"Configure the connection to automatically activate the ports:
# nmcli connection modify br0 connection.autoconnect-ports 1Activate 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
br0device:# cat /sys/class/net/br0/bridge/group_fwd_mask 0x8If the command returns
0x8, forwarding is enabled.
21.3. Configuring FreeRADIUS to authenticate network clients securely by using EAP Copy linkLink copied to clipboard!
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
freeradiusandfreeradius-ldappackages. -
The configuration files in the
/etc/raddb/directory are unchanged and as provided by thefreeradiuspackages. - 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.comThe
certmongerservice stores the private key in the/etc/pki/tls/private/radius.keyfile and the certificate in the/etc/pki/tls/certs/radius.pemfile, and it sets secure permissions. Additionally,certmongerwill monitor the certificate, renew it before it expires, and restart theradiusdservice 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/dhfile 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 2048For 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/eapfile:Configure the TLS-related settings in the
tls-config tls-commondirective: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_typeparameter in theeapdirective tottls:eap { ... default_eap_type = ttls ... }Comment out the
md5directives 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/defaultfile, 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-tunnelfile, and make the following changes:Comment out the
-ldapentry and add theldapmodule configuration to theauthorizedirective:authorize { ... #-ldap ldap if ((ok || updated) && User-Password) { update { control:Auth-Type := ldap } } ... }Uncomment the LDAP authentication type in the
authenticatedirective:authenticate { Auth-Type LDAP { ldap } }
Enable the
ldapmodule:# ln -s /etc/raddb/mods-available/ldap /etc/raddb/mods-enabled/ldapEdit the
/etc/raddb/mods-available/ldapfile, and make the following changes:In the
ldapdirective, 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
ldapsprotocol in the server URL to use TLS-encrypted connections between the FreeRADIUS host and the IdM server.In the
ldapdirective, enable TLS certificate validation of the IdM LDAP server:tls { ... require_cert = 'demand' ... }
Edit the
/etc/raddb/clients.conffile:Set a secure password in the
localhostandlocalhost_ipv6client 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
ipaddrparameter 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 OKOpen the RADIUS ports in the
firewalldservice:# firewall-cmd --permanent --add-service=radius # firewall-cmd --reloadEnable and start the
radiusdservice:# systemctl enable --now radiusd
Troubleshooting
If the
radiusdservice fails to start, verify that you can resolve the IdM server host name:# host -v idm_server.idm.example.comFor other problems, run
radiusdin debug mode:Stop the
radiusdservice:# systemctl stop radiusdStart the service in debug mode:
# radiusd -X ... Ready to process requests-
Perform authentication tests on the FreeRADIUS host, as referenced in the
Verificationsection.
Next steps
- Disable no longer required authentication methods and other features you do not use.
21.4. Configuring hostapd as an authenticator in a wired network Copy linkLink copied to clipboard!
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
hostapdpackage. - The FreeRADIUS server has been configured, and it is ready to authenticate clients.
Procedure
Create the
/etc/hostapd/hostapd.conffile 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_passwordFor further details about the parameters used in this configuration, see their descriptions in the
/usr/share/doc/hostapd/hostapd.confexample configuration file.Enable and start the
hostapdservice:# systemctl enable --now hostapd
Troubleshooting
If the
hostapdservice fails to start, verify that the bridge interface you use in the/etc/hostapd/hostapd.conffile is present on the system:# ip link show br0For other problems, run
hostapdin debug mode:Stop the
hostapdservice:# systemctl stop hostapdStart the service in debug mode:
# hostapd -d /etc/hostapd/hostapd.conf-
Perform authentication tests on the FreeRADIUS host, as referenced in the
Verificationsection.
21.5. Testing EAP-TTLS authentication against a FreeRADIUS server or authenticator Copy linkLink copied to clipboard!
After you set up the FreeRADIUS server and the hostapd service, test if authentication by using extensible authentication protocol (EAP) over tunneled transport layer security (EAP-TTLS) works as expected.
The output of the test utilities used in this procedure provide additional information about the EAP communication and help you to debug problems.
Prerequisites
- You set up the FreeRADIUS server.
-
You set up the
hostapdservice as an authenticator for 802.1X network authentication. When you want to authenticate to:
A FreeRADIUS server:
-
The
eapol_testutility, provided by thehostapdpackage, 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_supplicantutility, provided by the same-named package, is installed.
-
You stored the certificate authority (CA) certificate in the
/etc/ipa/ca.certfile.
Procedure
Optional: Create a user in Identity Management (IdM):
# ipa user-add --first "Test" --last "User" idm_user --passwordCreate the
/etc/wpa_supplicant/wpa_supplicant-TTLS.conffile 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 ... SUCCESSThe
-aoption defines the IP address of the FreeRADIUS server, and the-soption 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
-ioption specifies the network interface name on whichwpa_supplicantsends out extended authentication protocol over LAN (EAPOL) packets.For more debugging information, pass the
-doption to the command.
21.6. Blocking and allowing traffic based on hostapd authentication events Copy linkLink copied to clipboard!
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
hostapdservice has been configured, and the service is ready to authenticate clients.
Procedure
Create the
/usr/local/bin/802-1x-tr-mgmtfile 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 "$0" 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 traffic again" ;; NOTANEVENT) echo "$0 was called incorrectly, usage: $0 interface event [mac_address]" ;; esacCreate the
/etc/systemd/system/802-1x-tr-mgmt@.servicesystemd 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.targetReload systemd:
# systemctl daemon-reloadEnable and start the
802-1x-tr-mgmtservice with the interface namehostapdis 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.