not logged in | [Login]
Always use radiusd -X
when debugging!
This guide is intended to help any site wishing to join eduroam implement the IdP (home service) and SP (visited service) eduroam components. It contains sample configuration files that may be used in place of the normal v3.0.x configuration files that ship with the server.
In addition to the configuration files here, you will need to configure a module to talk to your user store (LDAP, Novell, Active Directory, SQL). See notes in the inner-tunnel configuration.
The general order of operations is:
/etc/raddb
or /etc/freeradius
with the ones found here.radiusd -X || freeradius -X
eapol_test
to verify the server is functional.files
module in the inner-tunnel, and either configure ntlm_auth
, the ldap module, or the sql module.eapol_test
files with real credentials in your user directory (preferably a test account).radiusd -X || freeradius -X
eapol_test
files work with REAL credentials.certs
directory (/etc/raddb/certs
or /etc/freeradius/certs/
) with ones issued by edupki or a commerical certification authority.eapol_test
files so they specify a certification authority.eapol_test
files work with a REAL certificate, and REAL credentials.proxy.conf
and clients.conf
A separate page gives more detail on configuring efficient logging for eduroam.
Before you begin you should build a copy of eapol_test
. eapol_test
is an extremely useful tool produced by the hostapd project which can simulate both a Wireless Access Point and a Supplicant (client). Unfortunately it's not usually packaged and can be quite challenging to build manually.
A script is included in the FreeRADIUS CIT suite that will automatically build eapol_test
, which you should use. Instructions on building it are as follows:
sudo yum groupinstall "Development Tools"
sudo yum install git openssl-devel pkgconfig libnl3-devel
sudo apt-get install git libssl-dev devscripts pkg-config libnl-3-dev libnl-genl-3-dev
git clone --depth 1 --no-single-branch https://github.com/FreeRADIUS/freeradius-server.git
cd freeradius-server/scripts/ci/
./eapol_test-build.sh
cp ./eapol_test/eapol_test /usr/local/bin/
You should now have a functional eapol_test
in your path.
You should replace existing configuration files in their entirety with the configuration file contents provided below.
This is a bare bones configuration file for the outer virtual-server. This virtual-server handles the outer EAP conversation, i.e. data outside of the TLS tunnel.
It does the following:
User-Name
strings.sites-available/default
# The domain users will add to their username to have their credentials
# routed to your institution. You will also need to register this
# and your RADIUS server addresses with your NRO.
operator_name = "<your-institutions-domain>"
# The VLAN to assign eduroam visitors
eduroam_default_guest_vlan = "<guest-vid>"
# The VLAN to assign your students/staff
eduroam_default_local_vlan = "<local-vid>"
server eduroam {
listen {
type = auth
ipaddr = *
port = 1812
}
authorize {
# Log requests before we change them
linelog_recv_request
# split_username_nai is a policy in the default distribution to
# split a username into username and domain. We reject user-name
# strings without domains, as they're not routable.
split_username_nai
if (noop || !&Stripped-User-Domain) {
reject
}
# Send the request to the NRO for your region.
# The details of the FLRs (Federation Level RADIUS servers)
# are in proxy.conf.
# You can make this condition as complex as you like, to
# include additional subdomains just concatenate the conditions
# with &&.
if (&Stripped-User-Domain != "${operator_name}") {
update {
control:Load-Balance-Key := &Calling-Station-ID
control:Proxy-To-Realm := 'eduroam_flr'
# Operator name (RFC 5580) identifies the network the
# request originated from. It's not absolutely necessary
# but it helps with debugging.
request:Operator-Name := "1${operator_name}"
}
return
}
# If the EAP module returns 'ok' or 'updated', it means it has handled
# the request and we don't need to call any other modules in this
# section.
eap {
ok = return
updated = return
}
}
pre-proxy {
attr_filter.pre-proxy
linelog_send_proxy_request
}
post-proxy {
attr_filter.post-proxy
linelog_recv_proxy_response
}
authenticate {
eap
}
post-auth {
# To implement eduroam you must:
# - Use wireless access points or a controller which supports
# dynamic VLAN assignments.
# - Have that feature enabled.
# - Have the guest_vlan/local_vlan available to the controller,
# or to all your access points.
# eduroam user traffic *MUST* be segregated, this is *NOT* optional.
update reply {
Tunnel-Type := VLAN
Tunnel-Medium-Type := IEEE-802
}
if (&control:Proxy-To-Realm) {
update reply {
Tunnel-Private-Group-ID = ${eduroam_default_guest_vlan}
}
}
else {
update reply {
Tunnel-Private-Group-ID = ${eduroam_default_local_vlan}
}
}
# We're sending a response to one of OUR network devices for one of
# OUR users so provide it with the real user-identity.
if (&session-state:Stripped-User-Name) {
update reply {
User-Name := "%{session-state:Stripped-User-Name}@%{Stripped-User-Domain}"
}
}
linelog_send_accept
Post-Auth-Type REJECT {
attr_filter.access_reject
linelog_send_reject
}
}
}
This is a stripped down EAP configuration that'll allow:
mods-available/eap
eap {
# The initial EAP type requested. Change this to peap if you're
# using peap, or tls if you're using EAP-TLS.
default_eap_type = ttls
# The maximum time an EAP-Session can continue for
timer_expire = 60
# The maximum number of ongoing EAP sessions
max_sessions = ${max_requests}
tls-config tls-common {
# The public certificate that your server will present
certificate_file = ${certdir}/server.pem
# The private key for the public certificate
private_key_file = ${certdir}/server.key
# The password to decrypt 'private_key_file'
private_key_password = whatever
# The certificate of the authority that issued 'certificate_file'
ca_file = ${cadir}/ca.pem
# If your AP drops packets towards the client, try reducing this.
fragment_size = 1024
# When issuing client certificates embed the OCSP URL in the
# certificate if you want to be able to revoke them later.
ocsp {
enable = yes
override_cert_url = no
use_nonce = yes
}
}
tls {
tls = tls-common
}
ttls {
tls = tls-common
default_eap_type = mschapv2
virtual_server = "eduroam-inner"
}
peap {
tls = tls-common
default_eap_type = mschapv2
virtual_server = "eduroam-inner"
}
}
All eduroam members should log requests to/from their servers for compliance purposes and because it makes debugging much easier.
These logging module instances and the virtual server configuration above will make your site fully compliant, so long as the syslog messages are retained for the requisite period.
We recommend ingesting the messages into logstash or Splunk to make debugging/helpdesk activities easier.
mods-available/linelog
linelog linelog_recv_request {
filename = syslog
syslog_facility = local0
syslog_severity = debug
format = "action = Recv-Request, %{pairs:request:}"
}
linelog linelog_send_accept {
filename = syslog
syslog_facility = local0
syslog_severity = debug
format = "action = Send-Accept, %{pairs:request:}"
}
linelog linelog_send_reject {
filename = syslog
syslog_facility = local0
syslog_severity = debug
format = "action = Send-Reject, %{pairs:request:}"
}
linelog linelog_send_proxy_request {
filename = syslog
syslog_facility = local0
syslog_severity = debug
format = "action = Send-Proxy-Request, %{pairs:proxy-request:}"
}
linelog linelog_recv_proxy_response {
filename = syslog
syslog_facility = local0
syslog_severity = debug
reference = "messages.%{proxy-reply:Response-Packet-Type}"
messages {
Access-Accept = "action = Recv-Proxy-Accept, User-Name = %{User-Name}, Calling-Station-Id = %{Calling-Station-Id}, %{pairs:proxy-reply:}"
Access-Reject = "action = Recv-Proxy-Reject, User-Name = %{User-Name}, Calling-Station-Id = %{Calling-Station-Id}, %{pairs:proxy-reply:}"
Access-Challenge = "action = Recv-Proxy-Challenge, User-Name = %{User-Name}, Calling-Station-ID = %{Calling-Station-Id}, %{pairs:proxy-reply:}"
}
}
You will also need to configure your local syslog deaemon to log these messages.
For rsyslogd you could do that with the following:
echo "local0.debug /var/log/radius_auth.log" > /etc/rsyslog.d/radiusd.conf
Then setup the appropriate log rotation rules.
A basic realm to forward requests to your NRO's FLRs'.
proxy.conf
home_server eduroam_flr_server_1 {
ipaddr = <ip-address>
secret = <secret>
status_check = status-server
response_window = 5
check_interval = 10
check_timeout = 5
}
# Only uncomment if there are two FLRS
#home_server eduroam_flr_server_2 {
# ipaddr = <ip-address>
# secret = <secret>
# status_check = status-server
# response_window = 5
# check_interval = 10
# check_timeout = 5
#}
home_server_pool eduroam_flr_pool {
type = keyed-balance
home_server = eduroam_flr_server_1
# Only uncomment if there are two FLRS
# home_server = eduroam_flr_server_2
}
realm eduroam_flr {
auth_pool = eduroam_flr_pool
nostrip
}
The clients.conf
file determines which devices can talk to the RADIUS server.
In most instances we need:
clients.conf
client localhost {
ipaddr = 127.0.0.1
secret = testing123
}
client eduroam_flr_server_1 {
ipaddr = <ip-address>
secret = <secret>
nastype = 'eduroam_flr'
}
# As above, only uncomment if there are two federation level servers
#client eduroam_flr_server_2 {
# ipaddr = <ip-address>
# secret = <secret>
# nastype = 'eduroam_flr'
#}
client wireless_access_points_mgmt {
ipaddr = <ip-address>/<cidr-mask>
# This should be long and random
secret = <secret>
}
This is a bare bones configuration file for the outer virtual-server. This virtual-server handles the inner EAP conversation, i.e. data inside of the TLS tunnel.
It does the following:
NOTE: You may need to symlink mods-enabled/inner-eap
to mods-available/inner-eap
. i.e. cd /etc/raddb/mods-available; ln -s ../mods-available/inner-eap ../mods-enabled/inner-eap
.
sites-available/inner-tunnel
server eduroam-inner {
listen {
type = auth
ipaddr = *
port = 18120 # Used for testing only. Requests proxied internally.
}
authorize {
# The outer username is considered garabage for autz purposes, but
# the domain portion of the outer and inner identities must match.
split_username_nai
if (noop || (&Stripped-User-Domain && \
(&outer.Stripped-User-Domain != &Stripped-User-Domain))) {
reject
}
# Make the user's real identity available to anything that needs
# it in the outer server.
if (&outer.session-state:)
update {
&outer.session-state:Stripped-User-Name := &Stripped-User-Name
}
}
# EAP for PEAPv0 (EAP-MSCHAPv2)
inner-eap {
ok = return
}
# THIS IS SITE SPECIFIC
#
# The files module is *ONLY* used for testing. It lets you define
# credentials in a flat file, IT WILL NOT SCALE.
#
# - If you use OpenLDAP with salted password hashes you should
# call the 'ldap' module here and use EAP-TTLS-PAP as your EAP method.
# - If you use OpenLDAP with cleartext passwords you should
# call the 'ldap' module here and use EAP-TTLS or PEAPv0.
# - If you use an SQL DB with salted password hashes you should call
# the 'sql' module here and use EAP-TTLS-PAP as your EAP method.
# - If you use an SQL DB with cleartext passwords you should call
# the 'sql' module here and use EAP-TTLS or PEAPv0.
# - If you use Novell you should call the 'ldap' module here and
# set ``edir = yes`` in ``mods-available/ldap`` and use EAP-TTLS or
# PEAPv0.
# - If you use Active Directory, you don't need anything here (remove
# the call to files) but you'll need to follow this
# [guide](freeradius-active-directory-integration-howto) and use
# EAP-TTLS-PAP or PEAPv0.
# - If you're using EAP-TLS (i'm impressed!) remove the call to files.
#
# EAP-TTLS-PAP and PEAPv0 are equally secure/insecure depending on how the
# supplicant is configured. PEAPv0 has a slight edge in that you need to
# crack MSCHAPv2 to get the user's password (but this is not hard).
files
pap
mschap
}
authenticate {
inner-eap
mschap
pap
# Comment pap above and uncomment the stanza below if you're using
# Active Directory; this will allow it to work with EAP-TTLS/PAP.
#Auth-Type pap {
# ntlm_auth
#}
}
}
This is a stripped inner-eap configuration that'll allow
mods-available/inner-eap
eap inner-eap {
default_eap_type = mschapv2
timer_expire = 60
max_sessions = ${max_requests}
mschapv2 {
send_error = yes
}
}
eapol_test
is the utility of choice when testing. Some basic config files for eapol_test
are given below, which allow you to generate EAP-TTLS, EAP-PEAP and EAP-TLS requests.
This testing entry for the files module set the 'known-good' or 'reference' password to be 'changeme' for all users.
The files
module should be removed from the config before the server is placed into production.
mods-config/files/authorize
DEFAULT Cleartext-Password := 'changeme'
~/eapol_test/eap-ttls.conf
#
# eapol_test -c ttls-pap.conf -s testing123
#
network={
key_mgmt=WPA-EAP
eap=TTLS
identity="a_user@<your-instiutions-domain>"
anonymous_identity="anonymous@<your-instiutions-domain>"
# Uncomment to validate the server's certificate by checking
# it was signed by this CA.
#ca_cert="raddb/certs/ca.pem"
password="changeme"
phase2="auth=PAP"
}
~/eapol_test/peap-mschapv2.conf
#
# eapol_test -c peap-mschapv2.conf -s testing123
#
network={
key_mgmt=WPA-EAP
eap=PEAP
identity="a_user@<your-instiutions-domain>"
anonymous_identity="anonymous@<your-instiutions-domain>"
# Uncomment to validate the server's certificate by checking
# it was signed by this CA.
#ca_cert="raddb/certs/ca.pem"
password="changeme"
phase2="auth=MSCHAPV2 mschapv2_retry=0"
phase1="peapver=0"
}
~/eapol_test/tls.conf
#
# eapol_test -c tls.conf -s testing123
#
network={
key_mgmt=WPA-EAP
eap=TLS
anonymous_identity="anonymous@<your-instiutions-domain>"
# Uncomment to validate the server's certificate by checking
# it was signed by this CA.
#ca_cert="raddb/certs/ca.pem"
# supplicant's public cert
client_cert="raddb/certs/client.crt"
# supplicant's private key
private_key="raddb/certs/client.key"
# password to decrypt private key
private_key_passwd="whatever"
}
Last edited by Arran Cudbard-Bell (arr2036), 2021-09-02 13:35:55
Sponsored by Network RADIUS