How to secure your Wifi network with Freeradius

Published by Stephan on

At our school we have an open wireless network with a captive portal as well as another WLAN (WPA Enterprise, 802.1X) which is only intended for teachers. For both networks we use a RADIUS server for authentication. Freeradius is the most widely used OpenSource RADIUS server, which we also use. In this article we want to set up a Freeradius server and certificates for an encrypted connection. In particular I would like to focus on the connection to linuxmuster.net 6.2 and the authentication with an LDAP server.

A RADIUS server generally takes care of 3 things: authentication, authorization and accounting (often referred to as Triple-A or AAA). We will only deal with the first two “As”, i.e. whether the credentials are correct and whether the user is authorized to gain access (to the Wifi, for example).

Installation of Freeradius

We perform the installation on a current Linux installation (here Ubuntu 18.04 Server), e.g. in an LXD container or a virtual machine.

$ apt install freeradius freeradius-ldap freeradius-utils

Configuration

Basic Configuration

To test our freeradius server, we comment out the following line in /etc/freeradius/3.0/users or insert it at the beginning of the file:

# Remove the "#" before the next line
steve Cleartext-Password := "testing"

By default, the file /etc/freeradius/3.0/clients.conf should contain the localhost as client:

client localhost {
    ipaddr = 127.0.0.1
    secret = testing123
}

Now we can run a first test. Therefore we stop the freeradius service and restart it manually in debug mode:

$ systemctl stop freeradius.service
$ freeradius -X
...
Ready to process request

It is important that at the end there is “Ready to process requests“.

Testing the Basic Configuration

Next, we check if our test user “Steve” can log on to the RADIUS server (preferably in a new/second terminal):

$ radtest steve testing 127.0.0.1 10 testing123

If everything is OK, we should get the following answer:

Sent Access-Request Id 234 from 0.0.0.0:40302 to 127.0.0.1:1812 length 75
	User-Name = "steve"
	User-Password = "testing"
	NAS-IP-Address = 10.18.10.60
	NAS-Port = 10
	Message-Authenticator = 0x00
	Cleartext-Password = "testing"
Received Access-Accept Id 234 from 127.0.0.1:1812 to 0.0.0.0:0 length 20

It’s important that we get a Received Access Accept. If this request was successful, the freeradius server is basically set up and the following authentication procedures should work without any further problems:

  • PAP
  • CAP
  • MS-CHAPv1
  • MS-CHAPv2
  • PEAP
  • EAP-TTLS
  • EAP-GTC
  • EAP-MD5

These methods are different protocols that are different “secure”. All use a username and password for authentication. You can read more about the different (P)EAP methods here. MS-CHAPv1 and v2 are protocols from Microsoft.

Note: We should comment or delete the line with our user “Steve” now!

In the following we will configure the LDAP module and create new certificates for EAP-TTLS.

Set up LDAP connection

We configure the LDAP server in the file /etc/freeradius/3.0/mods-enabled/ldap. If this file does not exist, we must first create a symbolic link.

$ cd /etc/freeradius/3.0/mods-enabled/
$ ln -s ../mods-available/ldap ./

Quite at the beginning of the file we configure our LDAP server:

server = "ldaps://linuxmuster.internal.example.com" 
identity = "cn=admin,dc=internal,dc=example,dc=com" 
password = superSecretPassword 
base_dn = "ou=accounts,dc=internal,dc=example,dc=com"
...

group {
    ...
    membership_filter = "(|(member=%{control:Ldap-UserDn})(memberUid=%{%{Stripped-User-Name}:-%{User-Name}}))"
    ...
}

You have to ensure that all necessary ports for communication between the RADIUS and the LDAP server are open.

Note: If you want to use Freeradius 3.0 together with linuxmuster.net v6.2, you have to adjust the following lines to make authentication with Windows work ():

update {
            control:Password-With-Header    += 'userPassword'
            control:NT-Password             := 'sambaNTPassword'
            ...
}

Test LDAP connection

After we configured LDAP server in freeradius, we have to restart freeradius once and can then test whether a user from the LDAP can log on to the RADIUS server.

$ systemctl restart freeradius.service
$ radtest testuser password localhost 10 testing123
Sent Access-Request Id 213 from 0.0.0.0:46425 to 127.0.0.1:1812 length 73
    User-Name = "testuser"
    User-Password = "password"
    NAS-IP-Address = 10.18.10.60
    NAS-Port = 10
    Message-Authenticator = 0x00
    Cleartext-Password = "password"
Received Access-Accept Id 213 from 127.0.0.1:1812 to 0.0.0.0:0 length 20

If we receive a “Received Access-Accept” as answer again, the connection between RADIUS and LDAP server works. If it doesn’t work, we should start the RADIUS server manually and see what errors the RADIUS server gives us.

$ systemctl stop freeradius.service 
$ freeradius -X 
... 
Ready to process request

Create certificates (for EAP-TTLS)

As default, Freeradius uses so-called Snake-Oil certificates, which of course are not intended for productive use. Therefore we create a new root CA and a certificate for the server in the following steps. You will find the certificates and the corresponding configuration files at /etc/freeradius/3.0/certs/. First we open the file ca.cnf and change a few settings:

...
[ CA_default ]
...
default_days        = 3650
...
default_md          = sha256
...

[ req ]
....
default_bits        = 2048
input_password      = supersecretandlongpassword
output_password     = supersecretandlongpassword
...

[certificate_authority]
countryName         = US
stateOrProvinceName = My State
localityName        = My Town
organizationName    = My School
emailAddress        = [email protected]
commonName          = "CA Freeradius"
...

We now make similar settings for the file server.cnf:

...

[ CA_default ]
...
default_days        = 3560
...
default_md          = sha256
... 

[ req ]
...
default_bits        = 2048
input_password      = supersecretandlongpassword
output_password     = supersecretandlongpassword

[server]
countryName         = US
stateOrProvinceName = My State
localityName        = My Town
organizationName    = My School
emailAddress        = [email protected]
commonName          = "Freeradius Server Certificate"

Now we have to change the password  also in the file /etc/freeradius/3.0/mods-enabled/eap:

tls-config tls-common {
    private_key_password = supersecretandlongpassword
    ...
}

We create the certificates with a simple make:

$ cd /etc/freeradius/3.0/certs/
$ make

Test EAP-TTLS Login

Compile epol_test

radtest does not support a test for EAP-TTLS authentication. For this we need the tool eapol_test, which is part of the wpa_supplicant package. Unfortunately, this tool is not built by wpa_supplicant by default, so we have to do it ourselves. We download the source code, unpack it and have to install some dependencies.

$ wget https://w1.fi/releases/wpa_supplicant-2.7.tar.gz
$ tar -xzvf wpa_supplicant-2.7.tar.gz
$ apt install build-essential pkg-config libnl-3-dev libssl-dev libnl-genl-3-dev
$ cd wpa_supplicant-2.7
$ cp defconfig .config

Then we have to open the file .config and find the line #CONFIG_EAPOL_TEST=y and remove the “#”.

$ nano .config
# Remove the "#"
CONFIG_EAPOL_TEST=y

With the following commands we build the program and copy it to the right place:

$ make eapol_test
$ cp eapol_test /usr/local/bin

Test login with eapol_test

To test EAP-TTLS, we need a small config file for eapol_test, which can look like this:

$ nano eapol_test.conf
network={
        ssid="example"
        key_mgmt=WPA-EAP
        eap=TTLS
        identity="mustermann"
        anonymous_identity="anonymous"
        password="strenggeheim"
        phase2="auth=PAP"
}

Now we can call eapol_test:

$ eapol_test -c eapol_test.conf -a 127.0.0.1 -p 1812 -s testing123

If you get this issue at the end, everything was successful:

MPPE keys OK: 1 mismatch: 0
SUCCESS

Setting up clients (e.g. access points)

So far we have only tested directly on the RADIUS server. Normally the authentication request will come from an access point, a captive portal or a wireless controller. We have to set them up as clients on the RADIUS server. We open the file /etc/freeradius/3.0/clients.conf and insert all access points etc. with their IP and a password / secret at the end:

$ nano /etc/freeradius/3.0/clients.conf
client AP1 {
    ipaddr = 10.0.0.10
    secret = supersecretsecret
}

Now you can set up a WPA Enterprise (802.1X) network on the access point and configure the RADIUS server with its IP, port (1812) and the password/secret you just set. Now you should be able to log in to the WLAN with your mobile device.

Restricting access to certain LDAP groups

At our school only employees and teachers as well as high school students have access to the WLAN at the school. In linuxmuster.net there is a group p_wifi. Everyone who is in this group should have access. So far our RADIUS server is configured in such a way that every user gets access in LDAP. To restrict access, we add the following lines to the file /etc/freeradius/3.0/users:

DEFAULT Ldap-Group == "cn=p_wifi,ou=groups,dc=internal,dc=example,dc=com"
DEFAULT Auth-Type := Reject
   Reply-Message = "Your are not allowed to access the WLAN!"

Freeradius and linuxmuster.net 6.2

The installation of Freeradius for linuxmuster.net 6.2 is described in the documentation. Apart from a few details, the configuration is very similar. In Freeradius 2.0 the default settings for the certificates are no longer up to date, so there may be connection problems with some clients (e.g. with a current macOS). Here you should definitely use the defaults of Freeradius 3.0 (see above)!

Different access restrictions according to WLAN network

At our school we have a captive portal for guests and students, as well as a WPA 802.1X (Enterprise) network for staff and teachers. While everyone in the p_wifi group can log in to the Captive Portal, only teachers and staff are allowed to log in to the WPA 802.1X network. The requests from the Captive Portal come from a different IP (pfSense) than that for the WPA Enterprise Network. In the file /etc/freeradius/sites-enabled/inner-tunnel we have therefore included a condition that checks which IP the request comes from and decides accordingly whether someone gets access or not:

post-auth {
    ...
    #Only allow Teacher&Staff on WPA 802.1X Teacher and Staff network  
    if (NAS-IP-Address == 10.0.0.10) {
        if (LDAP-Group == "cn=teachers,ou=groups,dc=internal,dc=example,dc=com" || LDAP-Group == "cn=staff,ou=groups,dc=internal,dc=example,dc=com") {
            noop
        } else {
            reject
        }
    }
    ...
}

Conslusion

This article describes only one of many possible configurations. A RADIUS server is complex, but thanks to the good standard configuration of freeradius (especially in version 3), you’ll quickly succeed. For a long time we only used the Captive Portal and it worked well, but the usability and security has increased with a WPA 802.1X (Enterprise) network. Without the RADIUS server this would not have been possible.

Useful links:


Stephan

I'm a teacher and IT system administrator in an international school. I love open source software and I used it over a decade in my private and work life. My passion is to solve problems with open source software!

0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *