Red Hat Training

A Red Hat training course is available for RHEL 8

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

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.

rhel authenticator 802 1x

17.1. Prerequisites

  • A clean installation of FreeRADIUS.

    If the freeradius package is already installed, remove the /etc/raddb/ directory, uninstall and then install the package again. Do not reinstall the package by using the yum reinstall command, because the permissions and symbolic links in the /etc/raddb/ directory are then different.

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

  1. Create the bridge interface:

    # nmcli connection add type bridge con-name br0 ifname br0
  2. Assign the Ethernet interfaces to the bridge:

    # nmcli connection add type ethernet slave-type bridge con-name br0-port1 ifname enp1s0 master br0
    # nmcli connection add type ethernet slave-type bridge con-name br0-port2 ifname enp7s0 master br0
    # nmcli connection add type ethernet slave-type bridge con-name br0-port3 ifname enp8s0 master br0
    # nmcli connection add type ethernet slave-type bridge con-name br0-port4 ifname enp9s0 master br0
  3. Enable the bridge to forward extensible authentication protocol over LAN (EAPOL) packets:

    # nmcli connection modify br0 group-forward-mask 8
  4. Configure the connection to automatically activate the ports:

    # nmcli connection modify br0 connection.autoconnect-slaves 1
  5. Activate the connection:

    # nmcli connection up br0

Verification

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

17.3. Certificate requirements by FreeRADIUS

For a secure FreeRADIUS service, you require TLS certificates for different purposes:

  • A TLS server certificate for encrypted connections to the server. Use a trusted certificate authority (CA) to issue the certificate.

    The server certificate requires the extended key usage (EKU) field set to TLS Web Server Authentication.

  • Client certificates issued by the same CA for extended authentication protocol transport layer security (EAP-TLS). EAP-TLS provides certificate-based authentication and is enabled by default.

    The client certificates require their EKU field set to TLS Web Client Authentication.

Warning

To secure connection, use your company’s CA or create your own CA to issue certificates for FreeRADIUS. If you use a public CA, you allow it to authenticate users and issue client certificates for EAP-TLS.

17.4. Creating a set of certificates on a FreeRADIUS server for testing purposes

For testing purposes, the freeradius package installs scripts and configuration files in the /etc/raddb/certs/ directory to create your own certificate authority (CA) and issue certificates.

Important

If you use the default configuration, certificates generated by these scripts expire after 60 days and keys use an insecure password ("whatever"). However, you can customize the CA, server, and client configuration.

After you perform the procedure, the following files, which you require later in this documentation, are created:

  • /etc/raddb/certs/ca.pem: CA certificate
  • /etc/raddb/certs/server.key: Private key of the server certificate
  • /etc/raddb/certs/server.pem: Server certificate
  • /etc/raddb/certs/client.key: Private key of the client certificate
  • /etc/raddb/certs/client.pem: Client certificate

Prerequisites

  • You installed the freeradius package.

Procedure

  1. Change into the /etc/raddb/certs/ directory:

    # cd /etc/raddb/certs/
  2. Optional: Customize the CA configuration in the /etc/raddb/certs/ca.cnf file:

    ...
    [ req ]
    default_bits            = 2048
    input_password          = ca_password
    output_password         = ca_password
    ...
    [certificate_authority]
    countryName             = US
    stateOrProvinceName     = North Carolina
    localityName            = Raleigh
    organizationName        = Example Inc.
    emailAddress            = admin@example.org
    commonName              = "Example Certificate Authority"
    ...
  3. Optional: Customize the server configuration in the /etc/raddb/certs/server.cnf file::

    ...
    [ CA_default ]
    default_days            = 730
    ...
    [ req ]
    distinguished_name      = server
    default_bits            = 2048
    input_password          = key_password
    output_password         = key_password
    ...
    [server]
    countryName             = US
    stateOrProvinceName     = North Carolina
    localityName            = Raleigh
    organizationName        = Example Inc.
    emailAddress            = admin@example.org
    commonName              = "Example Server Certificate"
    ...
  4. Optional: Customize the client configuration in the /etc/raddb/certs/client.cnf file::

    ...
    [ CA_default ]
    default_days            = 365
    ...
    [ req ]
    distinguished_name      = client
    default_bits            = 2048
    input_password          = password_on_private_key
    output_password         = password_on_private_key
    ...
    [client]
    countryName             = US
    stateOrProvinceName     = North Carolina
    localityName            = Raleigh
    organizationName        = Example Inc.
    emailAddress            = user@example.org
    commonName              = user@example.org
    ...
  5. Create the certificates:

    # make all
  6. Change the group on the /etc/raddb/certs/server.pem file to radiusd:

    # chgrp radiusd /etc/raddb/certs/server.pem

Additional resources

  • /etc/raddb/certs/README.md

17.5. Configuring FreeRADIUS to authenticate network clients securely by using EAP

FreeRADIUS supports different methods of the Extensible authentication protocol (EAP). However, for a secure network, configure FreeRADIUS to support only the following secure EAP authentication methods:

  • EAP-TLS (transport layer security) uses a secure TLS connection to authenticate clients by using certificates. To use EAP-TLS, you need TLS client certificates for each network client and a server certificate for the server. Note that the same certificate authority (CA) must have issued the certificates. Always use your own CA to create certificates, because all client certificates issued by the CA you use can authenticate to your FreeRADIUS server.
  • EAP-TTLS (tunneled transport layer security) uses a secure TLS connection and authenticates clients by using mechanisms, such as password authentication protocol (PAP) or challenge handshake authentication protocol (CHAP). To use EAP-TTLS, you need a TLS server certificate.
  • EAP-PEAP (protected extensible authentication protocol) uses a secure TLS connection as the outer authentication protocol to set up the tunnel. The authenticator authenticates the certificate of the RADIUS server. Afterwards, the supplicant authenticates through the encrypted tunnel by using Microsoft challenge handshake authentication protocol version 2 (MS-CHAPv2) or other methods.
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 package.
  • The configuration files in the /etc/raddb/ directory are unchanged and as provided by the freeradius package.
  • The following files exist on the server:

    • TLS private key of the FreeRADIUS host: /etc/raddb/certs/server.key
    • TLS server certificate of the FreeRADIUS host: /etc/raddb/certs/server.pem
    • TLS CA certificate: /etc/raddb/certs/ca.pem

    If you store the files in a different location or if they have different names, set the private_key_file, certificate_file, and ca_file parameters in the /etc/raddb/mods-available/eap file accordingly.

Procedure

  1. If the /etc/raddb/certs/dh with Diffie-Hellman (DH) parameters does not exist, create one. 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.

  2. Set secure permissions on the TLS private key, server certificate, CA certificate, and the file with DH parameters:

    # chmod 640 /etc/raddb/certs/server.key /etc/raddb/certs/server.pem /etc/raddb/certs/ca.pem /etc/raddb/certs/dh
    # chown root:radiusd /etc/raddb/certs/server.key /etc/raddb/certs/server.pem /etc/raddb/certs/ca.pem /etc/raddb/certs/dh
  3. Edit the /etc/raddb/mods-available/eap file:

    1. Set the password of the private key in the private_key_password parameter:

      eap {
          ...
          tls-config tls-common {
              ...
              private_key_password = key_password
              ...
          }
      }
    2. Depending on your environment, set the default_eap_type parameter in the eap directive to your primary EAP type you use:

      eap {
          ...
          default_eap_type = ttls
          ...
      }

      For a secure environment, use only ttls, tls, or peap.

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

  4. Edit the /etc/raddb/sites-available/default file, and comment out all authentication methods other than eap:

    authenticate {
        ...
        # Auth-Type PAP {
        #     pap
        # }
    
        # Auth-Type CHAP {
        #     chap
        # }
    
        # Auth-Type MS-CHAP {
        #     mschap
        # }
    
        # mschap
    
        # digest
        ...
    }

    This leaves only EAP enabled and disables plain-text authentication methods.

  5. Edit the /etc/raddb/clients.conf file:

    1. Set a secure password in the localhost and localhost_ipv6 client directives:

      client localhost {
          ipaddr = 127.0.0.1
          ...
          secret = client_password
          ...
      }
      
      client localhost_ipv6 {
          ipv6addr = ::1
          secret = client_password
      }
    2. If RADIUS clients, such as network authenticators, on remote hosts should be able to access the FreeRADIUS service, add corresponding client directives for them:

      client hostapd.example.org {
          ipaddr = 192.0.2.2/32
          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 an IPv4 and IPv6 address, 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.

  6. If you want to use EAP-TTLS or EAP-PEAP, add the users to the /etc/raddb/users file:

    example_user        Cleartext-Password := "user_password"

    For users who should use certificate-based authentication (EAP-TLS), do not add any entry.

  7. Verify the configuration files:

    # radiusd -XC
    ...
    Configuration appears to be OK
  8. Enable and start the radiusd service:

    # systemctl enable --now radiusd

Troubleshooting

  1. Stop the radiusd service:

    # systemctl stop radiusd
  2. Start the service in debug mode:

    # radiusd -X
    ...
    Ready to process requests
  3. 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.

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

  1. 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=client_password
    
    # RADIUS accounting server
    acct_server_addr=192.0.2.1
    acct_server_port=1813
    acct_server_shared_secret=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.

  2. Enable and start the hostapd service:

    # systemctl enable --now hostapd

Troubleshooting

  1. Stop the hostapd service:

    # systemctl stop hostapd
  2. Start the service in debug mode:

    # hostapd -d /etc/hostapd/hostapd.conf
  3. Perform authentication tests on the FreeRADIUS host, as referenced in the Verification section.

Additional resources

  • hostapd.conf(5) man page
  • /usr/share/doc/hostapd/hostapd.conf file

17.7. 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/pki/tls/certs/ca.pem file.

Procedure

  1. 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="example_user"
        password="user_password"
    
        # CA certificate to validate the RADIUS server's identity
        ca_cert="/etc/pki/tls/certs/ca.pem"
    }
  2. 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 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

17.8. Testing EAP-TLS authentication against a FreeRADIUS server or authenticator

To test if authentication by using extensible authentication protocol (EAP) transport layer security (EAP-TLS) 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/pki/tls/certs/ca.pem file.
  • The CA that issued the client certificate is the same that issued the server certificate of the FreeRADIUS server.
  • You stored the client certificate in the /etc/pki/tls/certs/client.pem file.
  • You stored the private key of the client in the /etc/pki/tls/private/client.key

Procedure

  1. Create the /etc/wpa_supplicant/wpa_supplicant-TLS.conf file with the following content:

    ap_scan=0
    
    network={
        eap=TLS
        eapol_flags=0
        key_mgmt=IEEE8021X
    
        identity="user@example.org"
        client_cert="/etc/pki/tls/certs/client.pem"
        private_key="/etc/pki/tls/private/client.key"
        private_key_passwd="password_on_private_key"
    
        # CA certificate to validate the RADIUS server's identity
        ca_cert="/etc/pki/tls/certs/ca.pem"
    }
  2. To authenticate to:

    • A FreeRADIUS server, enter:

      # eapol_test -c /etc/wpa_supplicant/wpa_supplicant-TLS.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-TLS.conf -D wired -i enp0s31f6
      ...
      enp0s31f6: CTRL-EVENT-EAP-SUCCESS EAP authentication completed successfully
      ...

      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

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

  1. Create the /usr/local/bin/802-1x-tr-mgmt file with the following content:

    #!/bin/sh
    
    if [ "x$1" == "xblock_all" ]
    then
    
        nft delete table bridge tr-mgmt-br0 2>/dev/null || true
        nft -f - << EOF
    table bridge tr-mgmt-br0 {
            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
        echo "802-1x-tr-mgmt Blocking all traffic through br0. Traffic for given host will be allowed after 802.1x authentication"
    
    elif [ "x$1" == "xallow_all" ]
    then
    
        nft delete table bridge tr-mgmt-br0
        echo "802-1x-tr-mgmt Allowed all forwarding again"
    
    fi
    
    case ${2:-NOTANEVENT} in
    
        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 "802-1x-tr-mgmt $1: Denied traffic from $3"
            ;;
    
    esac
  2. 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=-/bin/sh -c '/usr/sbin/tc qdisc del dev %i ingress > /dev/null 2>&1'
    ExecStartPre=-/bin/sh -c '/usr/sbin/tc qdisc del dev %i clsact > /dev/null 2>&1'
    ExecStartPre=/usr/sbin/tc qdisc add dev %i clsact
    ExecStartPre=/usr/sbin/tc filter add dev %i ingress pref 10000 protocol 0x888e matchall action ok index 100
    ExecStartPre=/usr/sbin/tc filter add dev %i ingress pref 10001 protocol all matchall action drop index 101
    ExecStart=/usr/sbin/hostapd_cli -i %i -a /usr/local/bin/802-1x-tr-mgmt
    ExecStopPost=-/usr/sbin/tc qdisc del dev %i clsact
    
    [Install]
    WantedBy=multi-user.target
  3. Reload systemd:

    # systemctl daemon-reload
  4. Enable and start the 802-1x-tr-mgmt service with the interface name hostapd is listening on:

    # systemctl enable --now 802-1x-tr-mgmt@br0.service

Additional resources

  • systemd.service(5) man page