Freeradius Setup for WPA Enterprise (EAP-TTLS-PAP) authentication
This guide explains how to install and configure freeradius 3 in order to make it work with OpenWISP RADIUS for WPA Enterprise EAP-TTLS-PAP authentication.
The setup will allow users to authenticate via WiFi WPA Enterprise networks using their personal username and password of their django user accounts. Users can either be created manually via the admin interface, generated, imported from CSV, or can self register through a web page which makes use of the registration REST API (like OpenWISP WiFi Login Pages).
Prerequisites
Execute the steps explained in the following sections of the freeradius guide for captive portal authentication:
How to install freeradius 3
Enable the configured modules
Configure the REST module
Then proceed with the rest of the document.
Freeradius configuration
Configure the sites
Main sites
In this scenario it is necessary to set up one FreeRADIUS site for each organization you want to support, each FreeRADIUS instance will therefore need two dedicated ports, one for authentication and one for accounting and a related inner tunnel configuration.
Let's create the site for an hypothetical organization called org-A.
Don't forget to substitute the occurrences of <org_uuid>
and
<org_radius_api_token>
with the UUID & Radius API token of each
organization, refer to the section Organization UUID & RADIUS API Token
for finding these values.
# /etc/freeradius/sites-enabled/org_a
server org_a {
listen {
type = auth
ipaddr = *
# ensure each org has its own port
port = 1812
# adjust these as needed
limit {
max_connections = 16
lifetime = 0
idle_timeout = 30
}
}
listen {
ipaddr = *
# ensure each org has its own port
port = 1813
type = acct
limit {}
}
# IPv6 configuration skipped for brevity
# consult the freeradius default configuration if you need
# to add the IPv6 configuration
# Substitute the following variables with
# the organization UUID and RADIUS API Token
api_token_header = "Authorization: Bearer <org_uuid> <org_radius_api_token>"
authorize {
eap-org_a {
ok = return
}
update control { &REST-HTTP-Header += "${...api_token_header}" }
rest
}
authenticate {
Auth-Type eap-org_a {
eap-org_a
}
}
post-auth {
update control { &REST-HTTP-Header += "${...api_token_header}" }
rest
Post-Auth-Type REJECT {
update control { &REST-HTTP-Header += "${....api_token_header}" }
rest
}
}
accounting {
update control { &REST-HTTP-Header += "${...api_token_header}" }
rest
}
}
Please also ensure that acct_unique
is present in the
pre-accounting
section:
preacct {
# ...
acct_unique
# ...
}
Inner tunnels
You will need to set up one inner tunnel for each organization too.
Following the example for a hypothetical organization named org-A:
# /etc/freeradius/sites-enabled/inner-tunnel
server inner-tunnel_org_a {
listen {
ipaddr = 127.0.0.1
# each org will need a dedicated port for their inner tunnel
port = 18120
type = auth
}
api_token_header = "Authorization: Bearer <org_uuid> <org_radius_api_token>"
authorize {
filter_username
update control { &REST-HTTP-Header += "${...api_token_header}" }
rest
eap-org_a {
ok = return
}
expiration
logintime
pap
}
authenticate {
Auth-Type PAP {
pap
}
Auth-Type CHAP {
chap
}
Auth-Type MS-CHAP {
mschap
}
eap-org_a
}
session {}
post-auth {
}
pre-proxy {}
post-proxy {
eap-org_a
}
}
Configure the EAP modules
Note
Keep in mind these are basic sample configurations, once you get it working feel free to tweak it to make it more secure and fully featured.
You will need to set up one EAP module instance for each organization too.
Following the example for a hypothetical organization named org-A:
eap eap-org_a {
default_eap_type = ttls
timer_expire = 60
ignore_unknown_eap_types = no
cisco_accounting_username_bug = no
max_sessions = ${max_requests}
tls-config tls-common {
# make sure to have a valid SSL certificate for production usage
private_key_password = whatever
private_key_file = /etc/ssl/private/ssl-cert-snakeoil.key
certificate_file = /etc/ssl/certs/ssl-cert-snakeoil.pem
ca_file = /etc/ssl/certs/ca-certificates.crt
dh_file = ${certdir}/dh
ca_path = ${cadir}
cipher_list = "DEFAULT"
cipher_server_preference = no
ecdh_curve = "prime256v1"
cache {
enable = no
}
ocsp {
enable = no
override_cert_url = yes
url = "http://127.0.0.1/ocsp/"
}
}
ttls {
tls = tls-common
default_eap_type = pap
copy_request_to_tunnel = yes
use_tunneled_reply = yes
virtual_server = "inner-tunnel_org_a"
}
}
Repeating the steps for more organizations
Let's say you don't have only the hypothetical org-A in your system but more organizations, in that case you simply have to repeat the steps explained in the previous sections, substituting the occurrences of org-A with the names of the other organizations.
So if you have an organization named ACME Systems, copy the files and
substitute the occurrences org_a
with acme_systems
.
Final steps
Once the configurations are ready, you should restart freeradius and then test/troubleshoot/debug your setup.
Implementing other EAP scenarios
Implementing other setups like EAP-TLS requires additional development effort.
OpenWISP Controller already supports x509 certificates, so it would be a matter of integrating the django-x509 module into OpenWISP RADIUS and then implement mechanisms for the users to securely download their certificates.
If you're interested in this feature, let us know via the support channels.