WPA-EAP TLS WiFi

After seeing this configuration deployed in enterprise I struggled to understand how it worked, so I picked up a UniFi AC-AP access point second hand and set around seeing how to do it using open source platforms.

Knowing that this required a certificate authority to work and RADIUS I figured I could eventually get it to work, but having never used RADIUS to any great degree it wasn’t without it’s pain. Eventually I did get it to a robust system and managed to deploy enterprise grade WiFi to my personal network.

Operating System: Ubuntu 18.04
Required Applications: freeradius2, openssl
Required Systems: A functioning CA, see here for a previous project.

Install Pre-Requisite Software

sudo apt-get update
sudo apt-get install openssl freeradius

Configure Your Access Point

Any access point or WiFi router which supports WPA-EAP (also referred to as WPA 802.1X or WPA-Enterprise) can be used in conjunction with RADIUS. All that needs to be entered on the router is a Shared Secret. This is a random string of characters and should be very complex, ideally be be between 48-63 characters (this length is to avoid incompatibility with certain hardware).

I am using UniFi which handles this configuration as a Profile that is then assigned to devices. This can be accessed via Settings > Profiles and configured as below:

RADIUS by default runs it's authorisation service on UDP port 1812

Generate Certificates and Private Key

First we will need to get a signed client certificate as well as the CA’s own certificate from our Certificate Authority (I have covered here how to set up a CA using openssl but any CA will do fine), we will need this to verify connection requests from WiFi clients.

In order to generate a CSR (Certificate Signing Request) for our RADIUS server, we’ll first need to save a configuration file:

sudo nano freeradius-csr.cnf

Enter the values below:

[ req ]
default_bits = 2048
prompt = no
encrypt_key = no
distinguished_name = dn
req_extensions = req_ext

[ dn ]
CN = radius.tinfoilcipher.co.uk
emailAddress = radius@tinfoilcipher.co.uk
O = madcaplaughs
OU = IT
L = Newcastle
ST = North East
C = GB

[ req_ext ]
subjectAltName = DNS: radius.tinfoilcipher.co.uk, DNS: radius

Save the file with CTRL+O and exit with CTRL+X

Generate a new private key and CSR with:

#--Generate CSR
openssl req -out radius.csr -newkey rsa:2048 -nodes -keyout radius.key -config freeradius-csr.cnf

#--Move key to private keys dir
sudo mv radius.key /etc/ssl/private/radius.key
sudo chmod 400 /etc/ssl/private/radius.key

The remaining CSR can be submitted to your CA in return for a signed certificate, this will need to be exported along with the CA certificate of your CA to your RADIUS server at /etc/ssl/certs.

freeradius - Configure clients.conf

First, freeradius needs to be configured to look at your access point in order to see it as a valid RADIUS station:

sudo nano /etc/freeradius/clients.conf

Locate the existing line which states ipaddr = 127.0.0.1 and edit it reflect the IP Address of your access point E.G:

ipaddr = 172.16.0.5

Following this locate the line that states secret = Testing123 and enter the secret you added to your access point, E.G.:

secret = thisismysharedsecret

Save the file with CTRL+O

freeradius - Configure eap.conf

In v2 of freeradius, the configuration of EAP-TLS is configured within EAP > TLS, in later versions, the EAP file calls an external file, the configuration itself is identical however so watch out for that!

Assuming version 2:

sudo nano /etc/freeradius/eap.conf

Locate the eap config block and set the values at the root:

eap {
    default_eap_type = tls
    timer_expire = 60
    ignore_unknown_eap_types = no
    cisco_accounting_username_bug = no
    max_sessions = ${max_requests}
    ...
}

Within the eap block, locate the tls, verify and oscp blocks and set the below values:

eap {
...
    tls {
        certdir = ${confdir}/certs
        cadir = ${confdir}/certs
        private_key_file = /etc/ssl/private/radius.key
        certificate_file = /etc/ssl/certs/radius.crt
        CA_file = /etc/ssl/certs/ca-tinfoilcipher.crt
        dh_file = ${certdir}/dh
        random_file = /dev/urandom
        CA_path = ${cadir}
        cipher_list = "DEFAULT"
        ecdh_curve = "prime256v1"
        cache {
        enable = no
        lifetime = 24 # hours
        max_entries = 255
    }
    
    verify {
    }
    
    ocsp {
        enable = no
        override_cert_url = yes
        url = "http://127.0.0.1/ocsp/"
    }
...
}

Save the file with CTRL+O, exit with CTRL+X and restart the RADIUS service:

sudo /etc/init.d/freeradius restart

In order to connect to the SSID, export a Cert/Key bundle from your CA and install it to your device (this can be called a .PKCS#12, .p12 or .pfx file).

Debugging

Freeradius provides a live debug mode, in order to see connections hit the RADIUS server:

sudo /etc/init.d/freeradius stop
sudo freeradius -X

You will now see connections hit the RADIUS server and their path, in order to exit this mode and resume normal operation use CTRL+C and resume with:

sudo /etc/init.d/freeradius start

Written on November 15, 2019