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. Note 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 and freeradius-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 the dnf 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: Assign the Ethernet interfaces to the bridge: Enable the bridge to forward extensible authentication protocol over LAN (EAPOL) packets: Configure the connection to automatically activate the ports: Activate the connection: Verification Display the link status of Ethernet devices that are ports of a specific bridge: Verify if forwarding of EAPOL packets is enabled on the br0 device: 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. Note 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 and freeradius-ldap packages. The configuration files in the /etc/raddb/ directory are unchanged and as provided by the freeradius packages. The host is enrolled in a Red Hat Enterprise Linux Identity Management (IdM) domain. Procedure Create a private key and request a certificate from IdM: 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 the radiusd service after the certificate was renewed. Verify that the CA successfully issued the certificate: 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: 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: Set the default_eap_type parameter in the eap directive to ttls : Comment out the md5 directives to disable the insecure EAP-MD5 authentication method: 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 than eap : 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 the ldap module configuration to the authorize directive: Uncomment the LDAP authentication type in the authenticate directive: Enable the ldap module: 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): 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: Edit the /etc/raddb/clients.conf file: Set a secure password in the localhost and localhost_ipv6 client directives: Add a client directive for the network authenticator: Optional: If other hosts should also be able to access the FreeRADIUS service, add client directives for them as well, for example: 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: Open the RADIUS ports in the firewalld service: Enable and start the radiusd service: Verification Testing EAP-TTLS authentication against a FreeRADIUS server or authenticator Troubleshooting If the radiusd service fails to start, verify that you can resolve the IdM server host name: For other problems, run radiusd in debug mode: Stop the radiusd service: Start the service in debug mode: Perform authentication tests on the FreeRADIUS host, as referenced in the Verification section. 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. Important 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: 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: Verification Testing EAP-TTLS authentication against a FreeRADIUS server or authenticator 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: For other problems, run hostapd in debug mode: Stop the hostapd service: Start the service in debug mode: 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 the hostapd package, is installed. The client, on which you run this procedure, has been authorized in the FreeRADIUS server's client databases. 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): Create the /etc/wpa_supplicant/wpa_supplicant-TTLS.conf file with the following content: To authenticate to: A FreeRADIUS server, enter: 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: The -i option specifies the network interface name on which wpa_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. Important 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-USD{1}" read -r -d '' TABLE_DEF << EOF table bridge USD{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 USD{2:-NOTANEVENT} in block_all) nft destroy table bridge "USDTABLE" printf "USDTABLE_DEF" | nft -f - echo "USD1: 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 { USD3 } echo "USD1: Allowed traffic from USD3" ;; AP-STA-DISCONNECTED | CTRL-EVENT-EAP-FAILURE) nft delete element bridge tr-mgmt-br0 allowed_macs { USD3 } echo "USD1: Denied traffic from USD3" ;; allow_all) nft destroy table bridge "USDTABLE" echo "USD1: Allowed all bridge traffice again" ;; NOTANEVENT) echo "USD0 was called incorrectly, usage: USD0 interface event [mac_address]" ;; esac Create the /etc/systemd/system/802-1x-tr-mgmt@.service systemd service file with the following content: Reload systemd: Enable and start the 802-1x-tr-mgmt service with the interface name hostapd is listening on: 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

Commands:
nmcli connection add type bridge con-name br0 ifname br0
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
nmcli connection modify br0 group-forward-mask 8
nmcli connection modify br0 connection.autoconnect-ports 1
nmcli connection up br0
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
cat /sys/class/net/br0/bridge/group_fwd_mask 0x8
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
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'
openssl dhparam -out /etc/raddb/certs/dh 2048
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 } }
eap { default_eap_type = ttls }
eap { # md5 { # } }
authenticate { # Auth-Type PAP { # pap # } # Auth-Type CHAP { # chap # } # Auth-Type MS-CHAP { # mschap # } # mschap # digest }
authorize { #-ldap ldap if ((ok || updated) && User-Password) { update { control:Auth-Type := ldap } } }
authenticate { Auth-Type LDAP { ldap } }
ln -s /etc/raddb/mods-available/ldap /etc/raddb/mods-enabled/ldap
ldap { server = 'ldaps:// idm_server.idm.example.com ' base_dn = 'cn=users,cn=accounts, dc=idm,dc=example,dc=com ' }
tls { require_cert = 'demand' }
client localhost { ipaddr = 127.0.0.1 secret = localhost_client_password } client localhost_ipv6 { ipv6addr = ::1 secret = localhost_client_password }
client hostapd.example.org { ipaddr = 192.0.2.2/32 secret = hostapd_client_password }
client <hostname_or_description> { ipaddr = <IP_address_or_range> secret = <client_password> }
radiusd -XC Configuration appears to be OK
firewall-cmd --permanent --add-service=radius firewall-cmd --reload
systemctl enable --now radiusd
host -v idm_server.idm.example.com
systemctl stop radiusd
radiusd -X Ready to process requests
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
systemctl enable --now hostapd
ip link show br0
systemctl stop hostapd
hostapd -d /etc/hostapd/hostapd.conf
ipa user-add --first " Test " --last " User " idm_user --password
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 " }
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
wpa_supplicant -c /etc/wpa_supplicant/wpa_supplicant-TTLS.conf -D wired -i enp0s31f6 enp0s31f6: CTRL-EVENT-EAP-SUCCESS EAP authentication completed successfully
#!/bin/sh TABLE="tr-mgmt-USD{1}" read -r -d '' TABLE_DEF << EOF table bridge USD{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 USD{2:-NOTANEVENT} in block_all) nft destroy table bridge "USDTABLE" printf "USDTABLE_DEF" | nft -f - echo "USD1: 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 { USD3 } echo "USD1: Allowed traffic from USD3" ;; AP-STA-DISCONNECTED | CTRL-EVENT-EAP-FAILURE) nft delete element bridge tr-mgmt-br0 allowed_macs { USD3 } echo "USD1: Denied traffic from USD3" ;; allow_all) nft destroy table bridge "USDTABLE" echo "USD1: Allowed all bridge traffice again" ;; NOTANEVENT) echo "USD0 was called incorrectly, usage: USD0 interface event [mac_address]" ;; esac
[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
systemctl daemon-reload
systemctl enable --now 802-1x-tr-mgmt@br0.service