Ubuntu 18.04 + FreeRadius v3 (WiFi Authentication)
Ubuntu 18.04 comes with FreeRadius version 3 so there is no need to add a PPA. Simply install FreeRadius and it’s dependencies.
sudo apt install freeradius freeradius-mysql freeradius-utils mariadb-server php-common php-gd php-curl php-mysql make
Then configure a database for FreeRadius.
Set a mysql root password (if you haven’t done so already):
mysqladmin -u root password NEWPASSWORD
Log in to MariaDB as root:
mysql -u root -p
You should now see the MariaDB prompt:
MariaDB [(none)]>
Enter these commands one at a time (pressing ENTER after each one) to create and configure the FreeRadius database:
Note: “password” should be replaced by the actual password you want to set for the database!
CREATE DATABASE radiusdb;
GRANT ALL ON radiusdb.* TO radius@localhost IDENTIFIED BY "password";
FLUSH PRIVILEGES;
EXIT;
Import the FreeRadius MySQL database schema with the following command:
mysql -u root -p radiusdb < /etc/freeradius/3.0/mods-config/sql/main/mysql/schema.sql
You will be prompted for the radiusdb password which you set earlier.
Create a symbolic link for sql module:
ln -s /etc/freeradius/3.0/mods-available/sql /etc/freeradius/3.0/mods-enabled/
You can check to see if the FreeRadius database is setup correctly like this:
mysql -u root -p
use radiusdb;
show tables;
You should see the following:
+--------------------+
| Tables_in_radiusdb |
+--------------------+
| nas |
| radacct |
| radcheck |
| radgroupcheck |
| radgroupreply |
| radpostauth |
| radreply |
| radusergroup |
+--------------------+
Exit MariaDB:
EXIT;
Next, edit this config:
nano /etc/freeradius/3.0/mods-enabled/sql
… and change the following information as shown:
Note: “password” should be replaced by the actual password you set for the database!
sql { driver = "rlm_sql_mysql" dialect = "mysql" # Connection info: server = "localhost" port = 3306 login = "radius" password = "password" # Database table configuration for everything except Oracle radius_db = "radiusdb" } read_clients = yes client_table = "nas"
Save and close the file.
Change the ownership permissions of the file:
chgrp -h freerad /etc/freeradius/3.0/mods-available/sql
chown -R freerad:freerad /etc/freeradius/3.0/mods-enabled/sql
Restart the FreeRadius service and check the status:
service freeradius restart
service freeradius status
You should see something like this:
● freeradius.service - FreeRADIUS multi-protocol policy server
Loaded: loaded (/lib/systemd/system/freeradius.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2019-10-31 12:34:42 CET; 1 day 3h ago
Docs: man:radiusd(8)
man:radiusd.conf(5)
http://wiki.freeradius.org/
http://networkradius.com/doc/
Main PID: 3822 (freeradius)
Tasks: 6 (limit: 2318)
CGroup: /system.slice/freeradius.service
└─3822 /usr/sbin/freeradius
Time to configure FreeRadius
Credits: Much of the following is taken from previous work done with https://www.ossramblings.com on the subject.
The following is the configuration which has been working for me for years in a business environment.
Disable proxy feature and enable extra logging info:
nano /etc/freeradius/3.0/radiusd.conf
Set the following:
proxy_requests = no
# $INCLUDE proxy.conf
auth=yes
Save and close file.
Tell FreeRadius about your WAP (Wireless Access Point) by editing this file:
nano /etc/freeradius/3.0/clients.conf
… with information which looks like this:
# Define RADIUS clients (usually a NAS, Access Point, etc.).
client mywap {
ipaddr = 192.168.1.100
secret = myRandomP@55w05D
require_message_authenticator = yes
}
Each WAP you have will need to have it’s own client entry, so if you have multiple it would look something like this:
# Define RADIUS clients (usually a NAS, Access Point, etc.).
client mywap1 {
ipaddr = 192.168.1.100
secret = myRandomP@55w05D
require_message_authenticator = yes
}
client mywap2 {
ipaddr = 192.168.1.101
secret = myRandomP@55w05D
require_message_authenticator = yes
}
When you configure the “WPA2-Enterprise” options on your WAP, you’ll enter the IP address of your Radius server, and this password.
Configure EAP-TLS
I personally like to keep the original config files, so I rename them to .orig like so:
mv /etc/freeradius/3.0/mods-available/eap /etc/freeradius/3.0/mods-available/eap.orig
Then I make a new config:
nano /etc/freeradius/3.0/mods-available/eap
… and dump this in:
Note: The “myserverkeypassword” will need to match the password you use when generating the server’s keys later.
# Example /etc/freeradius/mods-available/eap file
eap {
default_eap_type = tls
timer_expire = 60
ignore_unknown_eap_types = no
cisco_accounting_username_bug = no
max_sessions = 4096
tls {
certdir = ${confdir}/certs
cadir = ${confdir}/certs
private_key_password = "myserverkeypassword"
private_key_file = ${certdir}/server.key
certificate_file = ${certdir}/server.pem
ca_path = ${cadir}
ca_file = ${cadir}/ca.pem
dh_file = ${certdir}/dh
random_file = /dev/urandom
cipher_list = "HIGH"
make_cert_command = "${certdir}/bootstrap"
ecdh_curve = "prime256v1"
cache {
enable = no # Optionally enable
lifetime = 24 # hours
max_entries = 255
}
verify {
tmpdir = /tmp/radiusd
client = "/usr/bin/openssl verify -CAfile ${..ca_file} %{TLS-Client-Cert-Filename}"
}
ocsp {
enable = no # optionally enable
override_cert_url = yes
url = "http://127.0.0.1/ocsp/"
}
}
ttls {
default_eap_type = md5
copy_request_to_tunnel = no
use_tunneled_reply = no
virtual_server = "inner-tunnel"
}
}
Server configuration
Remove the default server configs:
rm /etc/freeradius/sites-enabled/*
Create a new server config:
Note: Replace “mynetwork” with whatever you want to call it.
nano /etc/freeradius/3.0/sites-available/"mynetwork"
… with the following contents:
######################################################################
server {
listen {
type = auth
port = 1812
ipaddr = *
}
authorize {
preprocess
eap {
ok = return
}
expiration
logintime
}
authenticate {
eap
}
preacct {
preprocess
acct_unique
suffix
files
}
accounting {
detail
# unix
radutmp
# exec
attr_filter.accounting_response
}
session {
radutmp
}
post-auth {
# exec
Post-Auth-Type REJECT {
attr_filter.access_reject
}
}
pre-proxy {
}
post-proxy {
eap
}
}
Link that to the sites-enabled directory:
cd /etc/freeradius/3.0/sites-enabled/
ln -s ../sites-available/"mynetwork" ./"mynetwork"
CONFIGURE SSL CERTIFICATES
rm /etc/freeradius/3.0/certs/*
cp /usr/share/doc/freeradius/examples/certs/* /etc/freeradius/3.0/certs/
nano /etc/freeradius/3.0/certs/ca.cnf
Change the following options:
Note: Edit the lines under the certificate_authority section to match what your certificate should say about you, and change “mycapassword” (the CA password) to yours.
[CA_default]
..
default_days = 1825
..
[req]
default_bits = 4096
input_password = "mycapassword"
output_password = "mycapassword"
..
[certificate_authority]
..
Make the CA keys and the DH file:
cd /etc/freeradius/3.0/certs/
make ca.pem
make ca.der
make printca
make dh
Edit server.cnf:
nano /etc/freeradius/3.0/certs/server.cnf
… and make some similar changes:
Note: Change the server section to match what your certificate should say about your server. The “myserverkeypassword” in this file should match the “myserverkeypassword” in the eap config we configured previously!
[ CA_default ]
..
default_days = 1825
..
[ req ]
..
default_bits = 4096
input_password = "myserverkeypassword"
output_password = "myserverkeypassword"
[server]
...
Make the server certificate:
make server.pem
Getting around a bug
In order for this FreeRadius configuration to work it needs /tmp/radiusd to be created and be given certain permissions. At the time of writing this it was not automatically being done (we submitted this bug report) so this is how we solved it:
Create the following file …
nano /etc/tmpfiles.d/radius.conf
… with the following content …
d /tmp/radiusd 0700 freerad freerad – –
… save and exit, then execute the following command …
systemd-tmpfiles –create
Is it all working?
Test it by:
service freeradius stop
freeradius -X
The last line should say: “Ready to process requests“
If everything is good go ahead and reboot the server and after boot check the FreeRadius service with:
service freeradius status
CREATE USER CERTIFICATES
nano /etc/freeradius/3.0/certs/Makefile
Locate these lines:
client.p12: client.crt
openssl pkcs12 -export -in client.crt -inkey client.key -out client.p12 -passin pass:$(PASSWORD_CLIENT) -passout pass:$(PASSWORD_CLIENT)
client.pem: client.p12
openssl pkcs12 -in client.p12 -out client.pem -passin pass:$(PASSWORD_CLIENT) -passout pass:$(PASSWORD_CLIENT)
cp client.pem $(USER_NAME).pem
Replace them with:
client.p12: client.crt
openssl pkcs12 -export -in client.crt -inkey client.key -out client.p12 -passin pass:$(PASSWORD_CLIENT) -passout pass:$(PASSWORD_CLIENT)
cp client.p12 $(USER_NAME).p12
client.pem: client.p12
openssl pkcs12 -in client.p12 -out client.pem -passin pass:$(PASSWORD_CLIENT) -passout pass:$(PASSWORD_CLIENT)
cp client.pem $(USER_NAME).pem
client_android.p12: client.crt
openssl pkcs12 -export -in client.crt -inkey client.key -certfile ca.pem -name "$(USER_NAME)" -out client_android.p12 -passin pass:$(PASSWORD_CLIENT) -passout pass:$(PASSWORD_CLIENT)
cp client_android.p12 $(USER_NAME)_android.p12
Note: Make sure indented lines are tabs and not spaces or the file will not work. If you just copy-paste this, it will probably paste as spaces, and you’ll need to delete the indents and replace with tabs.
nano /etc/freeradius/3.0/certs/client.cnf
Edit the following information:
[ CA_default ]
..
default_days = 365
..
[ req ]
prompt = now
distinguished_name = client
default_bits = 4096
input_password = clientpassword
output_password = clientpassword
..
Set your defaults just like you did before but this time for any client certificates. Setting the “default_days” to 365 means you will need to regenerate keys for the device in a year. Change the “default_bits” to 4096.
In the “input_password” and “output_password” set both to the same password, and keep in mind that this password will be needed when the certificate is installed on the client hardware.
Note: The “distinguished_name” should remain as “client” and not the name of the client.
The “[client]” section uniquely identifies the user in log files, so be sure the emailAddress and commonName are set properly to the user’s email address. It causes less confusion if the emailAddress and commonName both match.
Create the client certificate:
cd /etc/freeradius/3.0/certs/
make client.pem
make client_android.p12
Simply edit the client.cnf file for the next certificate and run those commands again to generate certificates for each device that will have WIFI access.
Finally, lets set the proper permissions for certificates:
cd /etc/freeradius/3.0/certs/
chmod 600 *
chown root:freerad *
chmod 640 ca.pem
chmod 644 dh
chmod 640 server.key
chmod 640 server.pem
What files are needed where?
- Windows: ca.der and [user].p12
- Linux: ca.pem and [user].p12
- Android: [user]_android.p12
Configure CRL (Certificate Revocation List)
nano /root/crl_gen.sh
contents:
#!/bin/bash
cd /etc/freeradius/3.0/certs
openssl ca -gencrl -keyfile ./ca.key -cert ./ca.pem -out /etc/freeradius/3.0/certs/mycrl.pem -config ./ca.cnf -passin pass: *ca.key password*
cat /etc/freeradius/3.0/certs/ca.pem /etc/freeradius/3.0/certs/mycrl.pem > /etc/freeradius/3.0/certs/ca_and_crl.pem
chown root:freerad /etc/freeradius/3.0/certs/ca_and_crl.pem
chmod 640 /etc/freeradius/3.0/certs/ca_and_crl.pem
chmod 750 crl_gen.sh
sh /root/crl_gen.sh
crontab -e
crontab entry:
0 0 */5 * * /root/crl_gen.sh >/dev/null 2>&1
Revoke Certificate
openssl ca -revoke user@email.com.pem -keyfile ca.key -cert ca.pem -config ./ca.cnf
Verify revocation (“Revoked certificates”):
openssl crl -in /etc/freeradius/3.0/certs/ca_and_crl.pem -text
Hi,
Great tutorial though! It worked a charm for me.
I am wondering though, you could do it without MySQL, I would presume right? As we’re not going to configure any users using MySQL. But instead, certificates are issues and revoked according to the specified user.
I would think, can we not remove those steps instead?
Mike
Hi,
Yes, I removed MySQL, MariaDB etc, and configured without, you don’t really need all those additional packages.
Mike