Providing 802.1X authentication with FreeRADIUS and PEAPv0/EAP-MSCHAPv2 support over a Raspberry Pi

This article covers a step by step how-to dealing with the right orchestration of some software components that can help to secure for example a guest network at your home. Because of the lightweight software usually an older Raspberry Pi model will be fine for the job. Most of the following steps will just be the same on other Debian based Linux distributions.

The goal

The goal is to provide

  • RADIUS based AAA mechanisms in your local network with the help of FreeRADIUS over a secure tunnel (PEAP in conjunction with MS-CHAPv2, what in reality is PEAPv0/EAP-MSCHAPv2)
  • an browser based administration interface in form of daloRADIUS
  • MySQL support for the above points

Prerequisites

  • Running Raspian
  • The RasPi is listening on a static IP address in your local network

How-to

First of all install the mostly obvious parts and some further dependencies:

sudo apt-get install freeradius freeradius-mysql apache2 php5 libapache2-mod-php5 mysql-server mysql-client php5-mysql php-pear php5-gd php-db

During this installation you will be asked for a root password to access your MySQL system, so be careful for a moment.

FreeRADIUS

As the default mode FreeRADIUS looks up its users in a plain file. As a first test you may edit it and run FreeRADIUS in debug mode. But that’s not my scope here.

In order to instruct FreeRADIUS to administrate its users in a mysql database you have to change the config

sudo vi /etc/freeradius/radiusd.conf

where you uncomment two lines

# $INCLUDE sql.conf
# $INCLUDE sql/mysql/counter.conf

as well as you have to change

sudo vi /etc/freeradius/sql.conf

where you change those values to your needs:

server = "localhost"
#port = 3306
login = "radiususer"
password = "radius_password"
# Database table configuration for everything except Oracle
radius_db = "radiusdb"

Now enable SQL for authorization, accounting, sessions and post-authentication in FreeRADIUS. Therefore edit

sudo vi /etc/freeradius/sites-enabled/default

by uncommenting the sql keyword in these lines:

# See "Authorization Queries" in sql.conf
sql
# See "Accounting queries" in sql.conf
sql
# See "Simultaneous Use Checking Queries" in sql.conf
sql
# See "Authentication Logging Queries" in sql.conf
sql

To restrict access to the RADIUS instance edit

sudo vi /etc/freeradius/clients.conf

where you add rules like

client 192.168.2.0/29 {
 secret = somesecret
 shortname = radius_wlan_guest
}

to allow access only to hosts of the network 192.168.2.0/24.

Restart FreeRADIUS:

sudo /etc/init.d/freeradius restart

MySQL and daloRADIUS

Next step is to configure MySQL. Do it together with the setup of daloRADIUS so you don’t have to open a MySQL prompt multiple times.

Download daloRADIUS (a web based frontend for FreeRADIUS) and extract it to a location in your web-root:

cd ~/downloads
wget http://downloads.sourceforge.net/project/daloradius/daloradius/daloradius0.9-9/daloradius-0.9-9.tar.gz
sudo tar zxvf daloradius-0.9-9.tar.gz -C /var/www/
sudo mv /var/www/daloradius-0.9-9/ /var/www/daloradius
cd /var/www/daloradius

Now open a mysql prompt, add a new user and execute a script provided by daloRADIUS:

mysql -uroot -p
mysql>create database radiusdb;
mysql>exit
mysql -u root -p radiusdb < /var/www/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('radius_password');
mysql>GRANT ALL ON radiusdb.* to 'radiususer'@'localhost';
mysql>exit

Afterwards edit those two files:

sudo vi /var/www/daloradius/library/daloradius.conf.php
sudo vi /var/www/daloradius/daloradius-users/library/daloradius.conf.php

For some reasons daloRADIUS provides separated configurations for the system administration frontend and for the user frontend. You have to change the following:

$configValues['CONFIG_DB_ENGINE'] = 'mysql';
$configValues['CONFIG_DB_HOST'] = 'localhost';
$configValues['CONFIG_DB_PORT'] = '3306';
$configValues['CONFIG_DB_USER'] = 'radiusuder';
$configValues['CONFIG_DB_PASS'] = 'radius_password';
$configValues['CONFIG_DB_NAME'] = 'radiusdb';

From now on daloRADIUS is accessible via:

Log in to the system administration GUI with default credentials username = administrator, password = radius. Change the password for administrator under configuration -> operator.

Create an additional testuser and allow him to access the user frontend under edit user -> user info -> check: “Enable User Portal Login”, set a “User Portal Login Password”. Be careful with the passwords. Our combination PEAPv0/EAP-MSCHAPv2 only allows the usage of NT password hashes or cleartext passwords (info).

PEAPv0/EAP-MSCHAPv2

This combination is a wide spread one and will be usable nearly out of the box by most clients. With the default EAP type MD5 you will not get lucky if you try to authenticate a Microsoft Client. They stopped to support MD5. For this reason and because it is not very secure you may change it.

In

sudo vi /etc/freeradius/eap.conf

take a look at the section “eap” and change

default-eap-type = md5

to

default-eap-type = peap

Create certificates

The required files are under /usr/share/doc/freeradius/example/certs. Take them to another folder an start certificate creation:

cd /usr/share/doc/freeradius/examples/certs
sudo cp Makefile ca.cnf server.cnf xpextensions /etc/freeradius/certs
cd /etc/freeradius/certs

Edit ca.cnf and server.cnf the thame way as follows:

[ CA_default ]
default_days = 1826 # 5 years
[ req ]
input_password = your_inputoutput_password
output_password = your_inputoutput_password
[certificate_authority]
countryName = DE
stateOrProvinceName = somestate
localityName = yourtown
organizationName = yourorg
emailAddress = mail@yourdomain.com
commonName = "some cool short desription"

Make them:

sudo make all

Because the certificate you just generated is not signed by a trusted root ca, you have to provide it (the “ca.der”) at least to all the Windows clients (need to import it).

In the section “tls” of

sudo vi /etc/freeradius/eap.conf

change the private key password

private_key_password = your_inputoutput_password

Enable and configurate MSCHAPv2

In

sudo vi /etc/freeradius/modules/mschap

change

use_mppe = yes
require_encryption = yes
require_strong = yes
with_ntdomain_hack = yes

To tell FreeRADIUS that it has to use SQL in the inner CHAP tunnel edit

sudo vi /etc/freeradius/sites-enabled/inner-tunnel

where you uncomment “sql”:

# See "Authorization Queries" in sql.conf
sql
# See "Simultaneous Use Checking Queries" in sql.conf
sql
# See "Authentication Logging Queries" in sql.conf
sql

Then reload new libraries and restart service:

sudo ldconfig
sudo /etc/init.d/freeradius restart

To go beyond

Secure access to daloRADIUS

Without applying any changes daloRADIUS will be accessable via unsecure HTTP connection. A good idea would be to create a redirection to HTTPS channel.

FreeRadius logging behavior

You may want to change the logging behavior of FreeRADIUS. If so, change the values in

sudo vi /etc/freeradius/radiusd.conf

to fit your needs:

auth = yes
auth_badpass = yes
auth_goodpass = yes

If you recognize problems when daloRADIUS should show up several log file entries (e.g. it says “permission denied”) it is because the user www-data has no right to read the content. If you really wish to see the log content of for example syslog you have to make it readable for www-data.

7 thoughts on “Providing 802.1X authentication with FreeRADIUS and PEAPv0/EAP-MSCHAPv2 support over a Raspberry Pi

  1. Hi Steven,

    really appreciated your little manual. Everything worked fine until I needed to make the certificates. I hope I have made all changes to the .cnf file correctly – but the “sudo make all” command comes up with the following error message:

    openssl ca -batch -keyfile ca.key -cert ca.pem -in server.csr -key `grep output_password ca.cnf | sed ‘s/.*=//;s/^ *//’` -out server.crt -extensions xpserver_ext -extfile xpextensions -config ./server.cnf
    Using configuration from ./server.cnf
    unable to load CA private key
    1995539664:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:539:
    1995539664:error:23077074:PKCS12 routines:PKCS12_pbe_crypt:pkcs12 cipherfinal error:p12_decr.c:104:
    1995539664:error:2306A075:PKCS12 routines:PKCS12_item_decrypt_d2i:pkcs12 pbe crypt error:p12_decr.c:130:
    1995539664:error:0907B00D:PEM routines:PEM_READ_BIO_PRIVATEKEY:ASN1 lib:pem_pkey.c:132:
    Makefile:70: recipe for target ‘server.crt’ failed
    make: *** [server.crt] Error 1

  2. Hi Steven,

    i have follow your guide to create the certificate, below is the error i getting, please assist.
    rad_recv: Access-Request packet from host 192.168.0.1 port 48587, id=2, length=65
    User-Name = “145a05-f02d62”
    NAS-Port = 1
    NAS-Port-Type = Wireless-802.11
    User-Password = “testing123”
    # Executing section authorize from file /etc/freeradius/sites-enabled/default
    +- entering group authorize {…}
    ++[preprocess] returns ok
    ++[chap] returns noop
    ++[mschap] returns noop
    ++[digest] returns noop
    [suffix] No ‘@’ in User-Name = “145a05-f02d62”, looking up realm NULL
    [suffix] No such realm “NULL”
    ++[suffix] returns noop
    [eap] No EAP-Message, not doing EAP
    ++[eap] returns noop
    [sql] expand: %{User-Name} -> 145a05-f02d62
    [sql] sql_set_user escaped user –> ‘145a05-f02d62’
    rlm_sql (sql): Reserving sql socket id: 2
    [sql] expand: SELECT id, username, attribute, value, op FROM radcheck WHERE username = ‘%{SQL-User-Name}’ ORDER BY id -> SELECT id, username, attribute, value, op FROM radcheck WHERE username = ‘145a05-f02d62’ ORDER BY id
    [sql] expand: SELECT groupname FROM radusergroup WHERE username = ‘%{SQL-User-Name}’ ORDER BY priority -> SELECT groupname FROM radusergroup WHERE username = ‘145a05-f02d62’ ORDER BY priority
    rlm_sql (sql): Released sql socket id: 2
    [sql] User 145a05-f02d62 not found
    ++[sql] returns notfound
    ++[expiration] returns noop
    ++[logintime] returns noop
    [pap] WARNING! No “known good” password found for the user. Authentication may fail because of this.
    ++[pap] returns noop
    ERROR: No authenticate method (Auth-Type) found for the request: Rejecting the user
    Failed to authenticate the user.
    Using Post-Auth-Type Reject
    # Executing group from file /etc/freeradius/sites-enabled/default
    +- entering group REJECT {…}
    [attr_filter.access_reject] expand: %{User-Name} -> 145a05-f02d62
    attr_filter: Matched entry DEFAULT at line 11
    ++[attr_filter.access_reject] returns updated
    Delaying reject of request 4 for 1 seconds
    Going to the next request
    Waking up in 0.9 seconds.
    Sending delayed reject for request 4
    Sending Access-Reject of id 2 to 192.168.0.1 port 48587
    Waking up in 3.5 seconds.
    Cleaning up request 0 ID 4 with timestamp +27
    Cleaning up request 1 ID 5 with timestamp +27
    Cleaning up request 2 ID 6 with timestamp +27
    Cleaning up request 3 ID 7 with timestamp +27
    WARNING: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    WARNING: !! EAP session for state 0xe8eb9ac7ebee83ff did not finish!
    WARNING: !! Please read http://wiki.freeradius.org/Certificate_Compatibility
    WARNING: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    Waking up in 1.4 seconds.
    Cleaning up request 4 ID 2 with timestamp +27

  3. Hi,

    Clearly explained, thank you very much.

    Being a beginner in Linux … could you tell me what I did wrong. I have finished the step of MySQL and daloRADIUS, but unfortunately when I open the page of http: //serverxxx/daloradius /, I have the following message.

    Not Found

    The requested URL /daloradius was not found on this server.

    Apache/2.4.10 (Raspbian) Server at xxx.xx.x.xx Port 80

    Thank you very much for your help. Kind regards

  4. Help
    Problem
    openssl ca -batch -keyfile ca.key -cert ca.pem -in server.csr -key `grep output_password ca.cnf | sed ‘s/.*=//;s/^ *//’` -out server.crt -extensions xpserver_ext -extfile xpextensions -config ./server.cnf
    unknown option your_inputoutput_password
    usage: ca args

  5. @Moana, try the following

    Move the directory to /var/www/html/

    cd /var/www/html
    mv /var/www/daloradius .

    Restart freeradius

    /etc/init.d/freeradius restart

    Good luck “;”

Leave a Reply

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