Securing your WiFi – WPA2-Enterprise with EAP-TLS made easy with Open Source tools

Recently I’ve been playing a lot with WPA2-Enterprise EAP-TLS at work. I wanted to share my experience with you all.

First of all, a little explanation about WiFi security. Most of you are familiar with WEP/WPA1+2 from your home WiFi. You probably know that WEP has been “hacked” long time ago and isn’t considered secure. Also, there are publicly available rainbow tables for WPA2-PSK as well – although you need a combination of SSID+PSK for it to work (PSK authentication uses both the SSID name and the PSK to generate the secret with the access point. The publicly available rainbow table consists the top 1000 SSID names and a heavy load of passwords). WPA1/2-PSK is the method most widely used on WiFi networks. It uses a pre-shared key (password) to authenticate to the access point.

On large enterprises, PSK authentication simply does not fit. For example, consider a company with 1000 employees. One of the employees that knows the PSK password gets fired. The password is compromised and has to be replaced (not to mention that every employee with minor knowledge can extract the PSK from his/hers computer) – that is a big deal.

This article will focus on deploying EAP-TLS with WPA2-Enterprise, although it might work with other IEEE 802.1x implementations (such as a Cisco layer 2 switch) with minor or no adjustments at all. As for other EAP authentication types, FreeRADIUS supports a lot of them. See FreeRADIUS documentation and google for some examples.

First of all, a few words about EAP-TLS. EAP-TLS implements TLS certificates authentication, where both the client (also called the supplicant) authenticates to the AP (the authenticator), which authenticates it with a RADIUS server, and the RADIUS server authenticates itself to the client. This means that only computers that posses your certificate will be able to connect to your network, also, these clients won’t be hijack-able.
If a computer is stolen or an employee is fired, that particular certificate can be revoked. For this to work properly, you’ll have to configure FreeRADIUS to validate the certificate against a CRL – something I won’t be covering on this post, however, it’s documented in the eap.conf file comments.

I won’t be elaborating on how certificates work and why it’s a trustworthy security mechanism. If it interests you, be sure to comment and ask for a post about it.

In our case, the supplicant is the WiFi client, the authenticator is the WiFi Access Point, and the authentication server is the FreeRADIUS server – which we’ll be deploying throughout this post.
I’m not going to elaborate much on TLS authentication. If you’re interested, you can read about Transport Layer Security (TLS) on Wikipedia.

For implementing EAP-TLS, we need a CA (Certification Authority). Every client has a client certificate and the RADIUS server has a server certificate. I’m going to use easy-rsa, which is a package of scripts to deploy/manage a simple CA with OpenSSL.

Ok, so lets start deploying then. For this installation I’ll be using a Debian 6 64bits installation. I’m assuming you already have it installed and that you are at least a bit familiar with Linux. Any distribution that has FreeRADIUS packages (including the EAP, EAP-TLS modules) will be ok.

First step: Creating the CA (you can skip this step if you already have a CA, however, I do suggest you start by deploying with easy-rsa and replace it later with your own certificates)

If something went wrong and you got an “access-reject” reply, make sure you ran the command correctly. You can also check the other terminal’s freeradius -X command.
If you still don’t figure it out, paste the output here as a comment and I’ll do my best to help you.

Terminate the “freeradius -X” instance, run it with init.d again:

killall freeradius # control+c on the other terminal will also do the trick
/etc/init.d/freeradius start

Configring a RADIUS client (the access point).
On the previous step we’ve checked the authentication from localhost. If you’d take a look on /etc/freeradius/clients.conf(the file that contains the allowed clients/NAS to authenticate with this RADIUS server), you’ll see that it is pre-configured for localhost with “testing123” shared secret:

Don’t forget to restart FreeRADIUS (/etc/init.d/freeradius restart will do the trick) after the change.

Configure your access point:
This step varies between access points. You’ll have to find where you configure WPA1/2-Enterprise on yours. It’s usually on the same place where you define the pre-shared secret for your SSID.
On some access points this is called RADIUS authentication.
Configure it with the IP address of your FreeRADIUS server, and the pre-shared key we’ve just configured onclients.conf.

Install the certificate on the client:
On Windows, you just double-click the .p12 file and it automatically imports it to Window’s certificate store, on Android, you’ll have to put the .p12 file on the SD card and import the certificate (On Android 2.3.x it’s on the settings menu under “Location & security“, “Credential storage“, “Install from SD card“.

Read the error message, you have filesystem permission issues…
Execute “chown -R freerad:freerad /etc/raddb/certs”
Note that the “freerad” username and group are Debian specific, it might be different in your distribution.

I suggest you check who’s the owner of /etc/raddb (by running “ls -ld /etc/raddb”) and change to that.

I just ignored the test (and after some adventures with converting certificates to android-friendly format) and setting up the hostapd daemon – It works 😀 (with same certificates and failing test). Thanks for the guide :).

Would you please give some more clarification please? I have followed your tutorial but have some additional questions. So what happened to username and password now? OK, Radius authenticates users (or computers, depending where the certificate have been stored and what kind of 802.1x authorization have been used). But how do I do some accounting? I would like to be able to use username and password also. Is this possible using EAP-TLS? It would be easy to just use single client certificate (with private key not exportable) and username/password. The idea is to use password inside the EAP-TLS tunnel. If the username/password pair is not matched, the Access-Reject would bi issued. What do you think?

You are mixing EAP-TTLS with EAP-TLS. The former tunnels other authentication mechanisms inside a TLS tunnel (hence the name TTLS).
The EAP-TLS method (the one this post is about) relies solely on certificates. Both ends (the authenticator and the supplicant) authenticate each other with the certificate.

Do some reading about CAs and TLS/SSL. Keep in mind that the common SSL installations do not implement client authentication, but only server (EAP-TTLS as way IIRC).

As for your accounting question: each client is allocated a unique client certificate, with a certain CN (common name). My guess is you can get this common name inside the accounting packets, although it might be implemented differently on different APs.

What I would also recommend as further reading is CRL (certificate revocation list)