This post documents my efforts in reconciling multiple tutorials for setting up WPA2-Enterprise at home, which have all been great, but subtly out of date or missing steps. The primary reference was this great tutorial by Jurgens Krause, although some steps had to be updated based on searching the official docs of the various pieces of software we're integrating.

The problem

The key component for getting WPA2-Enterprise running is a RADIUS server to authenticate connecting clients.

The plan

DD-WRT support for my router (the Asus RT-N66U), seemed to be more of a hack than for most other routers, and running RADIUS on the router seemed like even more of a hack. I love a good hack, but maybe not for something I rely on every day.

Instead, let's set up a Raspberry Pi as a RADIUS server, which seems only a little less hack-y.

WARNING and DISCLAIMER

I've reconstructed these steps from my recollection and command history. These instructions may be incomplete and inaccurate, may result in an inoperable configuration. Please take steps to ensure you don't end up completely unable to connect to your network. For example, if your router lets you set up multiple networks, switch only one over to WPA2-Enterprise so that you can still configure your router and such through your other network, or make sure that you have a computer that can connect to the router over Ethernet.

As consistent with the title of this blog, I have no idea what I'm doing and probably won't know how to diagnose or fix problems that you encounter when trying to set this up.

Materials

Setting up the Raspberry Pi

For expediency, I defaulted to Raspbian Stretch Lite for the operating system. (This is a total lie. I first tried FreeBSD, but couldn't get it to boot.)

Following the official installation guide, I flashed the Raspbian image onto the MicroSD card using Etcher.

Pop the SD card into the Raspberry Pi, connect the Pi to the router with an Ethernet cable, plug in my monitor to the HDMI port, and a keyboard into one of the USB ports.

Plug in the USB power.

Yay, it boots.

Configuring Raspbian

Login password

On Raspbian, the default username is pi and the default password is raspberry.

I logged in and first changed the password:

pi@raspberrypi:~ $ passwd
Changing password for pi.
(current) UNIX password:
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
pi@raspberrypi:~ $

Keyboard

Raspbian comes with the keyboard set to a UK layout, which I'm just not used to. (I noticed when I tried to type the # character and a £ came out). I ended up changing it to a US layout:

pi@raspberrypi:~ $ sudo dpkg-reconfigure keyboard-configuration

Network

Let's set a static IP for this new server, so that the router will have a consistent place to look for this thing. Since the router is currently set to distribute IP addresses in the range 192.168.1.100 - 192.168.1.254, I can give this new server the IP address 192.168.1.2 without worrying about interfering with the DHCP server.

Apparently, the way to configure IP addresses is in /etc/dhcpcd.conf rather than manually entering a configuration into /etc/network/interfaces. I ended up just uncommenting and tweaking the example in /etc/dhcpcd.conf:

# Example static IP configuration:
interface eth0
static ip_address=192.168.1.2/24
static routers=192.168.1.1
static domain_name_servers=192.168.1.1 8.8.8.8

sudo reboot to see if the IP address gets set properly on cold boot. It is.

Software updates

Let's update / upgrade our packages:

pi@raspberrypi:~ $ sudo apt update

then

pi@raspberrypi:~ $ sudo apt upgrade

Installing FreeRadius and DaloRadius

With all of that setup out of the way, we can now install a RADIUS server. FreeRadius seems to the one that is currently best maintained (and also the one used in Krause's tutorial), so let's go with that.

FreeRadius

Krause's tutorial sets up FreeRadius with a MySQL database to store the user credentials, so we'll also need to install MySQL:

pi@raspberrypi:~ $ sudo apt install freeradius freeradius-mysql mysql-server mysql-client

We can test the FreeRadius installation by temporarily enabling one of the test users in /etc/freeradius/3.0/users:

pi@raspberrypi:~ $ sudo nano /etc/freeradius/3.0/users

Find the lines:

#
# The canonical testing user which is in most of the
# examples.
#
#bob    Cleartext-Password := "hello"
#       Reply-Message := "Hello, %{User-Name}"

and uncomment bob's configuration:

#
# The canonical testing user which is in most of the
# examples.
#
bob     Cleartext-Password := "hello"
        Reply-Message := "Hello, %{User-Name}"

Save the changes (Ctrl-O for "Write Out" in nano) and exit (Ctrl-X).

Then we'll stop and restart the freeradius server in debug mode:

pi@raspberrypi:~ $ sudo service freeradius stop
pi@raspberrypi:~ $ sudo freeradius -X

Let's open another terminal window (Ctrl-Alt-F2), login with the same pi username, and test out the server:

pi@raspberrypi:~ $ radtest bob hello 127.0.0.1 0 testing123
Sent Access-Request Id 183 from 0.0.0.0:51430 to 127.0.0.1:1812 length 73
	User-Name = "bob"
	User-Password = "hello"
	NAS-IP-Address = 127.0.1.1
	NAS-Port = 0
	Message-Authenticator = 0x00
	Cleartext-Password = "hello"
Received Access-Accept Id 183 from 127.0.0.1:1812 to 0.0.0.0:0 length 32
	Reply-Message = "Hello, bob"

If that worked, then the FreeRadius server is working. If so, switch back to the first console (Ctrl-Alt-F1) and kill the server in debug mode (Ctrl-C). Then we can restart the FreeRadius server:

pi@raspberrypi:~ $ sudo service freeradius start

(You might also want to go back into the /etc/freeradius/3.0/users and comment out the lines for user bob.)

Now that we know it works, let's make sure that the Raspberry Pi starts the freeradius server on boot:

pi@raspberrypi:~ $ sudo systemctl enable freeradius

DaloRadius

We'll also install the DaloRadius web interface for configuring and monitoring FreeRadius. DaloRadius needs a web server and php installed:

pi@raspberrypi:~ $ sudo apt install apache2 php libapache2-mod-php php-pear php-mysql php-gd php-db

DaloRadius is not available via the Debian repositories, and the latest version on SourceForge was uploaded in October 2014, so I opted to install what seems to be the current version on Github. But to do that, I first need to install git.

pi@raspberrypi:~ $ sudo apt install git

and now:

pi@raspberrypi:~ $ git clone https://github.com/lirantal/daloradius.git
Cloning into 'daloradius'...
remote: Counting objects: 13858, done.
remote: Total 13858 (delta 0), reused 0 (delta 0), pack-reused 13858
Receiving objects: 100% (13858/13858), 8.81 MiB | 5.77 MiB/s, done.
Resolving deltas: 100% (9279/9279), done.
pi@raspberrypi:~ $

This leaves a daloradius directory in your home directory. Let's move this to where the web server can see it, and also give ownership to the www-data user:

pi@raspberrypi:~ $ sudo mv daloradius /var/www/html/
pi@raspberrypi:~ $ cd /var/www/html
pi@raspberrypi:~ $ sudo chown -R www-data:www-data /var/www/html/daloradius/

You can check to see if apache is configured properly by visiting your Raspberry Pi's IP address in a web browser (e.g., http://192.168.1.2). Hopefully you'll see a web page titled "Apache 2 Debian Default Page".

Configuring FreeRadius, DaloRadius, and MySQL

Let's start by setting up the database for use with FreeRadius and DaloRadius. We'll import a template from DaloRadius:

pi@raspberrypi:~ $ sudo su
root@raspberrypi:~# mysql -uroot -p
mysql>create database radiusdb;
mysql>exit
mysql -u root -p radiusdb < /var/www/html/daloradius/contrib/db/fr2-mysql-daloradius-and-freeradius.sql
mysql -u root -p
mysql>CREATE USER 'radiususer'@'localhost';
mysql>SET PASSWORD FOR 'radiususer'@'localhost' = PASSWORD('radiuspass');
mysql>GRANT ALL ON radiusdb.* to 'radiususer'@'localhost';
mysql>exit
root@raspberrypi:~# exit
pi@raspberrypi:~ $

If you want, you can choose your own database username and password in place of radiususer and radiuspass.

We'll also configure DaloRadius to connect to the database. Edit /var/www/html/daloradius/library/daloradius.conf.php

pi@raspberrypi:~ $ sudo nano /var/www/html/daloradius/library/daloradius.conf.php

and edit the matching lines:

$configValues['DALORADIUS_VERSION'] = '0.9-9';
$configValues['FREERADIUS_VERSION'] = '3';
$configValues['CONFIG_DB_ENGINE'] = 'mysqli';
$configValues['CONFIG_DB_HOST'] = 'localhost';
$configValues['CONFIG_DB_PORT'] = '3306';
$configValues['CONFIG_DB_USER'] = 'radiususer';
$configValues['CONFIG_DB_PASS'] = 'radiuspass';
$configValues['CONFIG_DB_NAME'] = 'radiusdb';

leaving the rest at their default settings.

Now let's configure FreeRadius to use the MySQL database. Edit the /etc/freeradius/3.0/mods-available/sql file using nano:

pi@raspberrypi:~ $ sudo nano /etc/freeradius/3.0/mods-available/sql

And change the driver line to:

sql {
        # The sub-module to use to execute queries. This should match
        # the database you're attempting to connect to.
        #
        #    * rlm_sql_mysql
    	#    * rlm_sql_mssql
        #    * rlm_sql_oracle
        #    * rlm_sql_postgresql
        #    * rlm_sql_sqlite
        #    * rlm_sql_null (log queries to disk)
        #
        driver = "rlm_sql_mysql"

Farther down, set the "dialect" to "mysql" and also enter the database user settings under "Connection info":

    # The dialect of SQL you want to use, this should usually match
    # the driver you selected above.
#
    # If you're using rlm_sql_null, then it should be the type of
    # database the logged queries are going to be executed against.
    dialect = "mysql"

    # Connection info:
    #
    server = "localhost"
    port = 3306
    login = "radiususer"
    password = "radiuspass"

    # Database table configuration for everything except Oracle
    radius_db = "radiusdb"

Next, we'll enable the sql mod by adding a symlink to it in the mods-enabled directory:

pi@raspberrypi:~ $ cd /etc/freeradius/3.0/mods-enabled
pi@raspberrypi:/etc/freeradius/3.0/mods-enabled $ sudo ln -s ../mods-available/sql

Then we'll make sure that the sql option is used in our server configuration:

pi@raspberrypi:~ $ sudo nano /etc/freeradius/3.0/sites-enabled/default

Replace all lines that read -sql with sql (use Ctrl-\ for Replace), e.g.:

#
#  Look in an SQL database.  The schema of the database
#  is meant to mirror the "users" file.
#
#  See "Authorization Queries" in mods-available/sql
-sql

becomes:

#
#  Look in an SQL database.  The schema of the database
#  is meant to mirror the "users" file.
#
#  See "Authorization Queries" in mods-available/sql
sql

I think there are about 4 instances to replace.

Save and exit.

See if the configuration is approximately correct (i.e., look for error messages when starting the debug server:

pi@raspberrypi:~ $ sudo service freeradius stop
pi@raspberrypi:~ $ sudo freeradius -X

Everything good? Then kill the debug server again (Ctrl-C) and restart the freeradius service:

pi@raspberrypi:~ $ sudo service freeradius start

Now it's time to configure the router as a "client" of the FreeRadius server. Edit /etc/freeradius/3.0/clients.conf:

pi@raspberrypi:~ $ sudo nano /etc/freeradius/3.0/clients.conf

I added a new client under the examples:

client home {
       ipaddr = 192.168.1.1
       secret = set_your_own_secret_here
}

Enter the IP address of your router in the ipaddr line and your own secret in line.

From here, go into your router configuration (in my case http://192.168.1.1) and look for the RADIUS settings page. Use the Raspberry Pi's ip address as the "RADIUS Server IP Address," set the "server port" to the default 1812 and enter the secret you created and saved into /etc/freeradius/3.0/clients.conf as your "connection secret."

Setting passwords

Now it's time to set up your users and passwords. Visit the DaloRadius configuration page at http://<your Raspberry Pi IP>/daloradius

Then login with the default username administrator and password radius.

After you've logged in, you can set the password under "Config" -> "Operators" -> "List Operators" -> "administrator"

Create a new user under "Management" -> "Users" -> "New User". The "username" and "password" will be what your clients use to connect to the WPA2-Enterprise network. Choose whatever you like. I just created one user, rather than create a separate user for everyone in the household.

Connecting clients

Ok, we should be good to go!

Go back to your router configuration page (e.g., http://192.168.1.1) and change the authentication mode on your wireless network from "WPA2-Personal" to "WPA2-Enterprise".

Your laptop will probably disconnect. When you try to reconnect, it'll prompt you for a username and password, so enter the ones that you created in the DaloRadius configuration page.

You'll also probably get a prompt about an untrusted, certificate self-signed by "raspberrypi". Just click accept or whatever.

That should be it, and you should be online.

Other things

Power consumption

Because the Raspberry Pi will be turned on 24/7 in order to provide authentication, I thought it would be good to reduce power consumption by turning some things off.

Edit /config/boot.txt:

pi@raspberrypi:~ $ sudo nano /boot/config.txt

To turn off the green activity LED, I added these lines:

# Disable activity LEDs
dtparam=act_led_trigger=none
dtparam=act_led_activelow=off

I also have my Raspberry Pi connected to the router over Ethernet, so I don't need WiFi or Bluetooth on the Raspberry Pi:

# disable wifi and bluetooth
dtoverlay=pi3-disable-wifi
dtoverlay=pi3-disable-bt

And I don't need audio, so I commented out the audio driver:

# Enable audio (loads snd_bcm2835)
# dtparam=audio=on

Turning off the red power LED is a little trickier and involved adding a command to the /etc/rc.local file:

pi@raspberrypi:~ $ sudo nano /etc/rc.local

Add these lines just before the exit 0 line:

# turn off power LED
echo 0 | tee /sys/class/leds/led1/brightness

Let's Encrypt

As noted above, the above setup uses a self-signed certificate. You could also use Let's Encrypt to get signed certificates. I haven't tried this yet:

https://framebyframewifi.net/2017/01/29/use-lets-encrypt-certificates-with-freeradius/