FreeRADIUS¶
Installazione¶
Per l'installazione su sistemi Ubuntu, è possibile ottenere la versione di FreeRADIUS più aggiornata aggiungendo il repository ppa:freeradius/stable-3.0
add-apt-repository ppa:freeradius/stable-3.0
apt-get update
apt-get install freeradius
Configurazione¶
Nel seguito si mostrerà un template di configurazione per l'integrazione di FreeRADIUS all'interno della federazione eduroam.
La configurazione che viene proposta è relativa alla versione 3 di FreeRADIUS essendo la versione 2 ormai deprecata.
Prima di procedere è necessario prendere nota dei seguenti valori che andranno opportunamente sostituiti nei file di configurazione:
- Operator-Name
rappresenta un valore univoco che identifica l'ente che invia le richieste di autenticazione alla federazione eduroam in qualità di Resource Provider. Si prende come riferimento il dominio principale dell'ente preceduto dalla stringa 1 (es. 1uniroma1.it). Nei file di configurazione verrà indicato come ###OPERATOR_NAME###
- Secret
è il segreto condiviso scambiato con gli operatori della federazione nazionale. Nei file di configurazione verrà indicato come ###SHARED_SECRET###
Per gli Identity Provider, è necessario procurarsi un certificato server. Nel momento in cui si scrive, i certificati rilasciati da Digicert mediante Terena SSL CA 3 rispettano tutti i requisiti indicati nel relativo paragrafo. Per i certificati self-signed, far riferimento alle istruzioni contenute nel paragrafo eap in quanto i certificati creati automaticamente con l'installazione di freeradius non sono correttamente riconosciuti con alcuni dispositivi che si collegano ad eduroam.
Avvertimento
Attenzione! I seguenti file rappresentano solo delle linee guida per la configurazione di FreeRADIUS e non vanno intesi come sostituti delle attuali configurazioni in essere presso gli enti.
radiusd.conf¶
Per Identity Provider e Resource Provider
Il file principale per la configurazione di FreeRADIUS è radiusd.conf
. Rispetto alla versione di default con cui viene installato, non richiede particolari variazioni, eccetto per le direttive:
- reject_delay
0
- auth
yes
- cleanup_delay
10
prefix = /usr
exec_prefix = /usr
sysconfdir = /etc
localstatedir = /var
sbindir = ${exec_prefix}/sbin
logdir = /var/log/freeradius
raddbdir = /etc/freeradius
radacctdir = ${logdir}/radacct
name = freeradius
confdir = ${raddbdir}
modconfdir = ${confdir}/mods-config
certdir = ${confdir}/certs
cadir = ${confdir}/certs
run_dir = ${localstatedir}/run/${name}
db_dir = ${raddbdir}
libdir = /usr/lib/freeradius
pidfile = ${run_dir}/${name}.pid
correct_escapes = true
max_request_time = 30
cleanup_delay = 10
max_requests = 16384
hostname_lookups = no
log {
destination = files
colourise = yes
file = ${logdir}/radius.log
syslog_facility = daemon
stripped_names = no
auth = yes
auth_badpass = no
auth_goodpass = no
msg_denied = "You are already logged in - access denied"
}
checkrad = ${sbindir}/checkrad
security {
user = freerad
group = freerad
allow_core_dumps = no
max_attributes = 200
reject_delay = 0
status_server = yes
}
proxy_requests = yes
$INCLUDE proxy.conf
$INCLUDE clients.conf
thread pool {
start_servers = 5
max_servers = 32
min_spare_servers = 3
max_spare_servers = 10
max_requests_per_server = 0
auto_limit_acct = no
}
modules {
$INCLUDE mods-enabled/
}
instantiate {
}
policy {
$INCLUDE policy.d/
}
$INCLUDE sites-enabled/
clients.conf¶
Per Identity Provider e Resource Provider
Nel file clients.conf
vengono configurati tutti gli apparati e/o server che possono inviare richieste di autenticazione al FreeRADIUS.
Nel caso di Resource Provider, gli unici client configurati saranno gli apparati di rete dell'ente (es. Access Point, Wireless LAN Controller).
Nel caso di Identity Provider, invece, i client da configurare sono i server della federazione nazionale radius.garr.net e radius2.garr.net da cui proverranno le richieste di autenticazione dei propri utenti in roaming.
#LOCALHOST
client localhost {
ipaddr = 127.0.0.1
proto = *
# Il secret per il client localhost è di default valorizzato come testing123.
# Cambiare il valore con uno di propria scelta.
# NON UTILIZZARE LO SHARED_SECRET COMUNICATO ALLA FEDERAZIONE NAZIONALE
secret = testing123
require_message_authenticator = no
virtual_server = eduroam
# L'Operator-Name deve essere preceduto da 1. (es. 1uniroma1.it)
Operator-Name = ###OPERATOR_NAME###
add_cui = yes
limit {
max_connections = 16
lifetime = 0
idle_timeout = 30
}
}
client localhost_ipv6 {
ipv6addr = ::1
# Il secret per il client localhost è di default valorizzato come testing123.
# Cambiare il valore con uno di propria scelta.
# NON UTILIZZARE LO SHARED_SECRET COMUNICATO ALLA FEDERAZIONE NAZIONALE
secret = testing123
}
#
# RESOURCE PROVIDER
#
# Esempio di Wireless LAN Controller
client wlc {
ipaddr = 192.168.1.1
shortname = wlc
# Il secret per il client wlc è uno di propria scelta con cui configurare
# l'apparato che effettuerà le richieste di autenticazione.
# NON UTILIZZARE LO SHARED_SECRET COMUNICATO ALLA FEDERAZIONE NAZIONALE
secret = secret123
nas_type = other
virtual_server = eduroam
# L'Operator-Name deve essere preceduto da 1. (es. 1uniroma1.it)
Operator-Name = ###OPERATOR_NAME###
# Richiede il Chargeable-User-Identity
add_cui = yes
}
#
# IDENTITY PROVIDER
#
# Sono configurati i server radius della federazione nazionale radius.garr.net e radius2.garr.net
# con il secret condiviso con il personale tecnico.
client radius.garr.net {
ipaddr = radius.garr.net
secret = ###SHARED_SECRET###
nas_type = other
virtual_server = eduroam
}
client radius2.garr.net {
ipaddr = radius2.garr.net
secret = ###SHARED_SECRET###
nas_type = other
virtual_server = eduroam
}
proxy.conf¶
Per Identity Provider e Resource Provider
Il file proxy.conf
configura la gestione del realm.
Gli Identity Provider devono gestire il proprio realm localmente.
Gli Resource Provider, invece, dovranno effettuare l'inoltro ai server della federazione nazionale.
proxy server {
default_fallback = no
}
realm LOCAL {
}
realm NULL {
virtual_server = auth-reject
}
#
# RESOURCE PROVIDER
#
# Le autenticazioni per i domini che non sono gestiti dall'ente,
# dovranno essere inviate alla federazione nazionale eduroam.
home_server radius.garr.net {
type = auth+acct
ipaddr = radius.garr.net
port = 1812
secret = ###SHARED_SECRET###
status_check = status-server
}
home_server radius2.garr.net {
type = auth+acct
ipaddr = radius2.garr.net
port = 1812
secret = ###SHARED_SECRET###
status_check = status-server
}
home_server_pool EDUROAM-FTLR {
type = fail-over
home_server = radius.garr.net
home_server = radius2.garr.net
}
realm "~.+$" {
pool = EDUROAM-FTLR
nostrip
}
#
# IDENTITY PROVIDER
#
# Tutti realm gestiti dall'ente, dovranno essere definiti in questo modo.
realm realm1.it {
}
realm realm2.it {
}
realm realm3.it {
}
Virtual server eduroam¶
Per Identity Provider e Resource Provider
Il virtual_server eduroam definito nel clients.conf
identifica come i pacchetti di autenticazioni devono essere analizzati da FreeRADIUS.
Innanzitutto viene effettuata una verifica sulla sintassi della outer-identity e aggiunto l'attributo Operator-Name. Con la direttiva suffix
si verifica se l'autenticazione sia relativa ad un dominio gestito localmente (come definito in proxy.conf
) oppure è necessario demandare alla federazione nazionale (aggiungendo gli attributi definiti nel pre-proxy
). Nel caso di autenticazioni locali, allora si attiva il modulo eap
. Se si tratta invece di autenticazioni remote, si attivano le stanze post-proxy
e post-auth
.
Creare il file sites-available/eduroam
con il seguente contenuto:
server eduroam {
listen {
type = "auth"
ipaddr = *
port = 0
}
listen {
type = "acct"
ipaddr = *
port = 0
}
listen {
type = "auth"
ipv6addr = ::
port = 0
}
listen {
type = "acct"
ipv6addr = ::
port = 0
}
authorize {
filter_username
# Se almeno Resource Provider, aggiungere
filter_eduroam_realms
operator-name
# #######################################
cui
auth_log
suffix
# Se almeno Identity Provider, aggiungere
eap {
ok = return
updated = return
}
# #######################################
}
authenticate {
# Se almeno Identity Provider, aggiungere
eap
# #######################################
}
preacct {
suffix
}
accounting {
}
post-auth {
update {
&reply: += &session-state:
}
cui
reply_log
eduroam_log
Post-Auth-Type REJECT {
attr_filter.access_reject
eap
reply_log
eduroam_log
}
}
pre-proxy {
operator-name
cui
pre_proxy_log
if("%{Packet-Type}" != "Accounting-Request") {
attr_filter.pre-proxy
}
}
post-proxy {
post_proxy_log
attr_filter.post-proxy
eap
}
}
Abilitare il virtual site creando il collegamento simbolico rimuovendo eventualmente il virtual site default
cd /etc/freeradius/sites-enabled
ln -s ../sites-available/eduroam .
rm default
Virtual server eduroam-inner-tunnel¶
Solo per Identity Provider
Le richieste di autenticazione che sono state analizzate dal virtual server eduroam
e che devono essere autenticate localmente poiché si riferiscono ad un realm locale, dopo aver attivato il modulo eap
, passano al virtual server eduroam-inner-tunnel
nel quale il tunnel TLS viene decifrato per accedere alla inner-identity e alla password dell'utente.
Creare il file sites-available/eduroam-inner-tunnel
con il seguente contenuto:
#
# SOLO IDENTITY PROVIDER
#
server eduroam-inner-tunnel {
authorize {
filter_username
if ("%{request:User-Name}" =~ /^(.*)@(.*)/) {
update request {
Stripped-User-Name := "%{1}"
Realm := "%{2}"
}
}
auth_log
eap
# Se gli utenti sono memorizzati su file di testo
files
# Se gli utenti sono memorizzati su un database
sql
# Se gli utenti sono memorizzati su LDAP
ldap
if ((ok || updated) && User-Password) {
update {
control:Auth-Type := ldap
}
}
mschap
pap
}
authenticate {
Auth-Type PAP {
pap
}
Auth-Type MS-CHAP {
mschap
}
Auth-Type LDAP {
ldap
}
eap
}
post-auth {
cui-inner
reply_log
eduroam_inner_log
Post-Auth-Type REJECT {
attr_filter.access_reject
reply_log
eduroam_inner_log
update outer.session-state {
&Module-Failure-Message := &request:Module-Failure-Message
}
}
}
post-proxy {
eap
}
}
Abilitare il virtual site creando il collegamento simbolico
cd /etc/freeradius/sites-enabled
ln -s ../sites-available/eduroam-inner-tunnel .
eap¶
Solo per Identity Provider
Modificare il file mods-enabled/eap
eap {
default_eap_type = peap
timer_expire = 60
ignore_unknown_eap_types = no
cisco_accounting_username_bug = no
max_sessions = ${max_requests}
#md5 {
#}
#leap {
#}
gtc {
auth_type = PAP
}
tls-config tls-common {
private_key_password = whatever
private_key_file = ${certdir}/server.pem
# If Private key & Certificate are located in
# the same file, then private_key_file &
# certificate_file must contain the same file
# name.
#
# If CA_file (below) is not used, then the
# certificate_file below MUST include not
# only the server certificate, but ALSO all
# of the CA certificates used to sign the
# server certificate.
certificate_file = ${certdir}/server.pem
# Trusted Root CA list
#
# ALL of the CA's in this list will be trusted
# to issue client certificates for authentication.
#
# In general, you should use self-signed
# certificates for 802.1x (EAP) authentication.
# In that case, this CA file should contain
# *one* CA certificate.
#
# This parameter is used only for EAP-TLS,
# when you issue client certificates. If you do
# not use client certificates, and you do not want
# to permit EAP-TLS authentication, then delete
# this configuration item.
ca_file = ${cadir}/ca.pem
#
# For DH cipher suites to work, you have to
# run OpenSSL to create the DH file first:
#
# openssl dhparam -out certs/dh 1024
#
dh_file = ${certdir}/dh
ca_path = ${cadir}
#
# This can never exceed the size of a RADIUS
# packet (4096 bytes), and is preferably half
# that, to accomodate other attributes in
# RADIUS packet. On most APs the MAX packet
# length is configured between 1500 - 1600
# In these cases, fragment size should be
# 1024 or less. If your AP drops packets
# towards the client, try reducing this.
#
fragment_size = 1024
# include_length is a flag which is
# by default set to yes If set to
# yes, Total Length of the message is
# included in EVERY packet we send.
# If set to no, Total Length of the
# message is included ONLY in the
# First packet of a fragment series.
#
include_length = yes
# TLS cipher suites. The format is listed
# in "man 1 ciphers".
cipher_list = "DEFAULT"
ecdh_curve = "prime256v1"
#
# Session resumption / fast reauthentication
# cache.
#
# The cache contains the following information:
#
# session Id - unique identifier, managed by SSL
# User-Name - from the Access-Accept
# Stripped-User-Name - from the Access-Request
# Cached-Session-Policy - from the Access-Accept
#
# The "Cached-Session-Policy" is the name of a
# policy which should be applied to the cached
# session. This policy can be used to assign
# VLANs, IP addresses, etc. It serves as a useful
# way to re-apply the policy from the original
# Access-Accept to the subsequent Access-Accept
# for the cached session.
#
# On session resumption, these attributes are
# copied from the cache, and placed into the
# reply list.
#
# You probably also want "use_tunneled_reply = yes"
# when using fast session resumption.
#
cache {
#
# Enable it. The default is "no".
# Deleting the entire "cache" subsection
# Also disables caching.
#
# You can disallow resumption for a
# particular user by adding the following
# attribute to the control item list:
#
# Allow-Session-Resumption = No
#
# If "enable = no" below, you CANNOT
# enable resumption for just one user
# by setting the above attribute to "yes".
#
enable = yes
#
# Lifetime of the cached entries, in hours.
# The sessions will be deleted after this
# time.
#
lifetime = 24
#
# The maximum number of entries in the
# cache. Set to "0" for "infinite".
#
# This could be set to the number of users
# who are logged in... which can be a LOT.
#
max_entries = 255
}
verify {
}
ocsp {
enable = no
override_cert_url = yes
url = "http://127.0.0.1/ocsp/"
}
}
tls {
tls = tls-common
}
ttls {
tls = tls-common
default_eap_type = pap
copy_request_to_tunnel = yes
use_tunneled_reply = yes
virtual_server = "eduroam-inner-tunnel"
}
peap {
tls = tls-common
default_eap_type = mschapv2
copy_request_to_tunnel = yes
use_tunneled_reply = yes
virtual_server = "eduroam-inner-tunnel"
}
mschapv2 {
}
}
Certificati¶
Solo per Identity Provider
Se si è ottenuto un certificato da Digicert mediante Terena SSL CA 3 è sufficiente creare il file /etc/freeradius/certs/server.pem
composto dalla concatenazione del:
Certificato server rilasciato da Terena
Certificato di TERENA SSL CA 3
Certificato di DigiCert Assured ID Root CA
Ad esempio:
-----BEGIN CERTIFICATE-----
*server radius certificate*
------END CERTIFICATE------
-----BEGIN CERTIFICATE-----
MIIE+zCCA+OgAwIBAgIQCHC8xa8/25Wakctq7u/kZTANBgkqhkiG9w0BAQsFADBl
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
b3QgQ0EwHhcNMTQxMTE4MTIwMDAwWhcNMjQxMTE4MTIwMDAwWjBkMQswCQYDVQQG
EwJOTDEWMBQGA1UECBMNTm9vcmQtSG9sbGFuZDESMBAGA1UEBxMJQW1zdGVyZGFt
MQ8wDQYDVQQKEwZURVJFTkExGDAWBgNVBAMTD1RFUkVOQSBTU0wgQ0EgMzCCASIw
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMV2Dw/ZQyk7bG3RR63eEL8jwnio
Snc18SNb4EweQefCMQC9iDdFdd25AhCAHo/tZCMERaegOTuBTc9jP8JJ/yKeiLDS
lrlcinQfkioq8hLIt2hUtVhBgUBoBhpPhSn7tU08D08/QJYbzqjMXjX/ZJj1dd10
VAWgNhEEEiRVY++Udy538RV27tOkWUUhn6i+0SftCuirOMo/h9Ha8Y+5Cx9E5+Ct
85XCFk3shKM6ktTPxn3mvcsaQE+zVLHzj28NHuO+SaNW5Ae8jafOHbBbV1bRxBz8
mGXRzUYvkZS/RYVJ+G1ShxwCVgEnFqtyLvRx5GG1IKD6JmlqCvGrn223zyUCAwEA
AaOCAaYwggGiMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMHkG
CCsGAQUFBwEBBG0wazAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu
Y29tMEMGCCsGAQUFBzAChjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln
aUNlcnRBc3N1cmVkSURSb290Q0EuY3J0MIGBBgNVHR8EejB4MDqgOKA2hjRodHRw
Oi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3Js
MDqgOKA2hjRodHRwOi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVk
SURSb290Q0EuY3JsMD0GA1UdIAQ2MDQwMgYEVR0gADAqMCgGCCsGAQUFBwIBFhxo
dHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMB0GA1UdDgQWBBRn/YggFCeYxwnS
JRm76VERY3VQYjAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq
hkiG9w0BAQsFAAOCAQEAqSg1esR71tonHqyYzyc2TxEydHTmQN0dzfJodzWvs4xd
xgS/FfQjZ4u5b5cE60adws3J0aSugS7JurHogNAcyTnBVnZZbJx946nw09E02DxJ
WYsamM6/xvLYMDX/6W9doK867mZTrqqMaci+mqege9iCSzMTyAfzd9fzZM2eY/lC
J1OuEDOJcjcV8b73HjWizsMt8tey5gvHacDlH198aZt+ziYaM0TDuncFO7pdP0GJ
+hY77gRuW6xWS++McPJKe1e9GW6LNgdUJi2GCZQfXzer8CM/jyxflp5HcahE3qm5
hS+1NGClXwmgmkMd1L8tRNaN2v11y18WoA5hwnA9Ng==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG
EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c
JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP
mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+
wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4
VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/
AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB
AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun
pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC
dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf
fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm
NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx
H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
-----END CERTIFICATE-----
Il file mods-enabled/eap
deve avere come parametri:
- private_key:
file della chiave private non cifrata con cui è stata generate la CSR sottomessa a Digicert. Se la chiave è cifrata, allora è necessario valorizzare la direttiva
private_key_password
- certificate_file:
file
server.pem
creato come indicato in precedenza- ca_file:
questa direttiva deve essere commentata
Se invece si vuole utilizzare una CA self-signed, è necessario che questa sia generata in modo proprio. Infatti, non solo i certificati generati in automatico al momento dell'installazione di FreeRADIUS sono validi solo per pochi giorni, ma essi non rispettano i requisiti che deve avere un certificato server radius in eduroam. La procedura è la seguente:
Eliminare i certificati creati automaticamente
cd /etc/freeradius/certs
rm -f *.pem *.der *.csr *.crt *.key *.p12 serial* index.txt*
Modificare le configurazioni della CA:
ca.cnf
valorizzando gli attributi###LOCALITA###
,###ORGANIZZAZIONE###
,###EMAIL###
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = ./
certs = $dir
crl_dir = $dir/crl
database = $dir/index.txt
new_certs_dir = $dir
certificate = $dir/ca.pem
serial = $dir/serial
crl = $dir/crl.pem
private_key = $dir/ca.key
RANDFILE = $dir/.rand
name_opt = ca_default
cert_opt = ca_default
default_days = 3650
default_crl_days = 30
crl_extensions = crl_ext
default_md = sha256
preserve = no
policy = policy_match
crlDistributionPoints = URI:http://www.example.org/example_ca.crl
name_opt = ca_default
cert_opt = ca_default
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
prompt = no
distinguished_name = certificate_authority
default_md = sha256
default_bits = 2048
input_password = whatever
output_password = whatever
x509_extensions = v3_ca
[certificate_authority]
countryName = IT
stateOrProvinceName = Italy
localityName = ###LOCALITA###
organizationName = ###ORGANIZZAZIONE###
commonName = "Eduroam Root ###ORGANIZZAZIONE###"
emailAddress = ###EMAIL###
[v3_ca]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
basicConstraints = critical,CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
crlDistributionPoints = URI:http://www.example.org/example_ca.crl
[ crl_ext ]
# Extension for CRLs (`man x509v3_config`).
authorityKeyIdentifier = keyid:always
Modificare la configurazione per la creazione del certificato server
server.cnf
valorizzando gli attributi###LOCALITA###
,###ORGANIZZAZIONE###
,###EMAIL###
e###FQDN_RADIUS###
facendo particolare attenzione a valorizzare correttamente il valore###FQDN_RADIUS###
nella sezionereq_distinguished_name
e nella sezionealt_names
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = ./
certs = $dir
crl_dir = $dir/crl
database = $dir/index.txt
new_certs_dir = $dir
certificate = $dir/ca.pem
serial = $dir/serial
crl = $dir/crl.pem
private_key = $dir/ca.key
RANDFILE = $dir/.rand
name_opt = ca_default
cert_opt = ca_default
default_days = 3600
default_crl_days = 30
crl_extensions = crl_ext
default_md = sha256
preserve = no
policy = policy_match
crlDistributionPoints = URI:http://www.example.org/example_ca.crl
name_opt = ca_default
cert_opt = ca_default
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
prompt = no
input_password = whatever
output_password = whatever
default_bits = 2048
distinguished_name = req_distinguished_name
req_extensions = req_ext
x509_extensions = req_ext
[ req_distinguished_name ]
countryName = IT
stateOrProvinceName = Italy
localityName = ###LOCALITA###
organizationName = ###ORGANIZZAZIONE###
commonName = ###FQDN_RADIUS###
emailAddress = ###EMAIL###
[ req_ext ]
subjectKeyIdentifier = hash
subjectAltName = @alt_names
basicConstraints = critical,CA:false
keyUsage = critical,digitalSignature,keyEncipherment
extendedKeyUsage = serverAuth
crlDistributionPoints = URI:http://www.example.com/example_ca.crl
[ alt_names ]
DNS.1 = ###FQDN_RADIUS###
[ crl_ext ]
# Extension for CRLs (`man x509v3_config`).
authorityKeyIdentifier = keyid:always
Modificare il file
Makefile
come di seguito indicato:
######################################################################
#
# Make file to be installed in /etc/raddb/certs to enable
# the easy creation of certificates.
#
# See the README file in this directory for more information.
#
# $Id: ef243c9b3719af58690bf48bcbb532eaa96099dd $
#
######################################################################
DH_KEY_SIZE = 2048
OPENSSL = openssl
#
# Set the passwords
#
-include passwords.mk
######################################################################
#
# Make the necessary files, but not client certificates.
#
######################################################################
.PHONY: all
all: index.txt serial dh server ca client
.PHONY: client
client: client.pem
.PHONY: ca
ca: ca.der
.PHONY: server
server: server.pem server.vrfy
.PHONY: verify
verify: server.vrfy client.vrfy
passwords.mk: server.cnf ca.cnf client.cnf
@echo "PASSWORD_SERVER = '$(shell grep output_password server.cnf | sed 's/.*=//;s/^ *//')'" > $@
@echo "PASSWORD_CA = '$(shell grep output_password ca.cnf | sed 's/.*=//;s/^ *//')'" >> $@
@echo "PASSWORD_CLIENT = '$(shell grep output_password client.cnf | sed 's/.*=//;s/^ *//')'" >> $@
@echo "USER_NAME = '$(shell grep emailAddress client.cnf | grep '@' | sed 's/.*=//;s/^ *//')'" >> $@
@echo "CA_DEFAULT_DAYS = '$(shell grep default_days ca.cnf | sed 's/.*=//;s/^ *//')'" >> $@
######################################################################
#
# Diffie-Hellman parameters
#
######################################################################
dh:
$(OPENSSL) dhparam -out dh -2 $(DH_KEY_SIZE)
######################################################################
#
# Create a new self-signed CA certificate
#
######################################################################
ca.key ca.pem: ca.cnf
@[ -f index.txt ] || $(MAKE) index.txt
@[ -f serial ] || $(MAKE) serial
$(OPENSSL) req -new -x509 -keyout ca.key -out ca.pem \
-days $(CA_DEFAULT_DAYS) -config ./ca.cnf
chmod g+r ca.key
ca.der: ca.pem
$(OPENSSL) x509 -inform PEM -outform DER -in ca.pem -out ca.der
######################################################################
#
# Create a new server certificate, signed by the above CA.
#
######################################################################
server.csr server.key: server.cnf
$(OPENSSL) req -new -out server.csr -keyout server.key -config ./server.cnf
chmod g+r server.key
server.crt: server.csr ca.key ca.pem
$(OPENSSL) ca -batch -keyfile ca.key -cert ca.pem -in server.csr -key $(PASSWORD_CA) -out server.crt -extensions req_ext -config ./server.cnf
server.p12: server.crt
$(OPENSSL) pkcs12 -export -in server.crt -inkey server.key -out server.p12 -passin pass:$(PASSWORD_SERVER) -passout pass:$(PASSWORD_SERVER)
chmod g+r server.p12
server.pem: server.p12
$(OPENSSL) pkcs12 -in server.p12 -out server.pem -passin pass:$(PASSWORD_SERVER) -passout pass:$(PASSWORD_SERVER)
chmod g+r server.pem
.PHONY: server.vrfy
server.vrfy: ca.pem
@$(OPENSSL) verify -CAfile ca.pem server.pem
######################################################################
#
# Create a new client certificate, signed by the the above server
# certificate.
#
######################################################################
client.csr client.key: client.cnf
$(OPENSSL) req -new -out client.csr -keyout client.key -config ./client.cnf
chmod g+r client.key
client.crt: client.csr ca.pem ca.key
$(OPENSSL) ca -batch -keyfile ca.key -cert ca.pem -in client.csr -key $(PASSWORD_CA) -out client.crt -extensions xpclient_ext -extfile xpextensions -config ./client.cnf
client.p12: client.crt
$(OPENSSL) pkcs12 -export -in client.crt -inkey client.key -out client.p12 -passin pass:$(PASSWORD_CLIENT) -passout pass:$(PASSWORD_CLIENT)
chmod g+r client.p12
client.pem: client.p12
$(OPENSSL) pkcs12 -in client.p12 -out client.pem -passin pass:$(PASSWORD_CLIENT) -passout pass:$(PASSWORD_CLIENT)
chmod g+r client.pem
cp client.pem $(USER_NAME).pem
.PHONY: client.vrfy
client.vrfy: ca.pem client.pem
c_rehash .
$(OPENSSL) verify -CApath . client.pem
######################################################################
#
# Miscellaneous rules.
#
######################################################################
index.txt:
@touch index.txt
serial:
@echo '01' > serial
print:
$(OPENSSL) x509 -text -in server.crt
printca:
$(OPENSSL) x509 -text -in ca.pem
clean:
@rm -f *~ *old client.csr client.key client.crt client.p12 client.pem
#
# Make a target that people won't run too often.
#
destroycerts:
rm -f *~ dh *.csr *.crt *.p12 *.der *.pem *.key index.txt* \
serial* *\.0 *\.1
Ricreare i certificati
make ca.pem
make server.pem
cui¶
Per Identity Provider e Resource Provider
Modificare il file policy.d/cui
che gestisce la richiesta e la generazione dell'attributo Chargeable-User-Identity.
cui_hash_key = "###CHANGEME###"
cui_require_operator_name = "yes"
cui.authorize {
if ("%{client:add_cui}" == 'yes') {
update request {
&Chargeable-User-Identity := 0x00
}
}
}
cui.pre-proxy {
if (("%{request:Packet-Type}" == 'Access-Request') && ("%{client:add_cui}" == 'yes')) {
update proxy-request {
&Chargeable-User-Identity = 0x00
}
}
}
cui.post-auth {
if (!&control:Proxy-To-Realm && &Chargeable-User-Identity && !&reply:Chargeable-User-Identity && \
(&Operator-Name || ('${policy.cui_require_operator_name}' != 'yes')) ) {
update reply {
&Chargeable-User-Identity = "%{sha1:${policy.cui_hash_key}%{tolower:%{Stripped-User-Name}%{%{Operator-Name}:-}}}"
}
}
#if (&reply:Chargeable-User-Identity) {
# update {
# &reply:User-Name := &request:User-Name
# }
# cuisql
#}
}
cui-inner.post-auth {
if (&outer.request:Chargeable-User-Identity && \
(&outer.request:Operator-Name || ('${policy.cui_require_operator_name}' != 'yes'))) {
update reply {
&Chargeable-User-Identity := "%{sha1:${policy.cui_hash_key}%{tolower:%{Stripped-User-Name}%{%{outer.request:Operator-Name}:-}}}"
}
}
}
cui.accounting {
if (!&Chargeable-User-Identity) {
update request {
&Chargeable-User-Identity := "%{cuisql:\
SELECT cui FROM cui \
WHERE clientipaddress = '%{%{Packet-Src-IPv6-Address}:-%{Packet-Src-IP-Address}}' \
AND callingstationid = '%{Calling-Station-Id}' \
AND username = '%{User-Name}'}"
}
}
if (&Chargeable-User-Identity && (&Chargeable-User-Identity != '')) {
cuisql
}
}
Filtri¶
Solo Resource Provider
Al fine di prevenire autenticazioni che de facto sono errate e quindi non ha senso che transitino sulla federazione eduroam, creare il seguente filtro policy.d/eduroam-realm-checks
filter_eduroam_realms {
if (&User-Name) {
#*********************************************************#
# Prima Parte
# ~~~~~~~~~~~
#
# In questa sezione sono elencati i realm che non sono validi
#
#*********************************************************#
# Richiesta di autenticazione senza dominio, ma con sola User-Name
if(!(&User-Name =~ /@/)){
update reply {
Reply-Message := "Your User-Name is invalid (no realm)"
}
reject
}
# Richiesta di autenticazione nel formato username@, cioè senza
# un dominio valido
if(&User-Name =~ /@$/){
update reply {
Reply-Message := "Your realm is invalid (it is blank)"
}
reject
}
# Presenza di più domini (più @)
if(&User-Name =~ /@.+?@/){
update reply {
Reply-Message := "Your realm is invalid (more than one @)"
}
reject
}
# Dominio con caratteri non consentiti
if(&User-Name =~ /@.+?[^[:alnum:]\.-]/){
update reply {
Reply-Message := "Your realm is invalid (contains not alphanumeric, hyphen or period)"
}
reject
}
# Dominio che inizia con un punto o un trattino
if(&User-Name =~ /@[\.-]/){
update reply {
Reply-Message := "Your realm is invalid (begins with a period or hyphen)"
}
reject
}
# Dominio che finisce con un punto o trattivo
if(&User-Name =~ /@.+?[\.-]$/){
update reply {
Reply-Message := "Your realm is invalid (ends with a period or hyphen)"
}
reject
}
# Dominio in cui non è presente almeno un punto
if(&User-Name =~ /@[^\.]+$/){
update reply {
Reply-Message := "Your realm is invalid (does not contain a period)"
}
reject
}
# Dominio che ha più punti in sequenza
if(&User-Name =~ /@.+?\.\./){
update reply {
Reply-Message := "Your realm is invalid (contains sequential periods)"
}
reject
}
#*********************************************************#
# Seconda parte
# ~~~~~~~~~~~~~
#
# Domini che, seppur sintatticamente validi,
# non sono validi all'interno della federazione eduroam
#
#*********************************************************#
# myabc.com tipicamente utilizzato dai supplicant Intel
if(&User-Name =~ /@myabc\.com$/i){
update reply {
Reply-Message := "Your realm is invalid (it is myabc.com)"
}
reject
}
# 3gppnetwork.org, another common default realm
if(&User-Name =~ /@wlan\.[[:alnum:]]+\.[[:alnum:]]+\.3gppnetwork\.org$/i){
update reply {
Reply-Message := "Your realm is invalid (it matches a wlan. subrealm of 3gppnetwork.org)"
}
reject
}
# gmail.com e gmail.co.??
if (&User-Name =~ /@gmail\.co(m|\.[[:alnum:]][[:alnum:]])$/i){
update reply {
Reply-Message := "Your realm is invalid (looks like a Gmail domain)"
}
reject
}
# yahoo.com e yahoo.co.??
if (&User-Name =~ /@yahoo\.co(m|\.[[:alnum:]][[:alnum:]])$/i){
update reply {
Reply-Message := "Your realm is invalid (looks like a Yahoo domain)"
}
reject
}
# hotmail.com e hotmail.co.??
if (&User-Name =~ /@hotmail\.co(m|\.[[:alnum:]][[:alnum:]])$/i){
update reply {
Reply-Message := "Your realm is invalid (looks like a Hotmail domain)"
}
reject
}
}
}
Logging¶
Per Identity Provider e Resource Provider
Per configurare FreeRADIUS affinché le autenticazioni siano loggate su una sola riga invece che su più righe come avviene di default, creare il modulo mods-available/eduroam_logging
.
linelog eduroam_log {
filename = ${logdir}/eduroam-log
format = ""
reference = "eduroam_log.%{%{reply:Packet-Type}:-format}"
eduroam_log {
Access-Accept = "%S eduroam-auth USER=%{User-Name} ORG=%{request:Realm} CSI=%{%{Calling-Station-Id}:-Unknown Caller Id} NAS=%{%{Called-Station-Id}:-Unknown Access Point} CUI=%{%{reply:Chargeable-User-Identity}:-Unknown} MSG=%{%{EAP-Message}:-No EAP Message} RESULT=OK"
Access-Reject = "%S eduroam-auth USER=%{User-Name} ORG=%{request:Realm} CSI=%{%{Calling-Station-Id}:-Unknown Caller Id} NAS=%{%{Called-Station-Id}:-Unknown Access Point} CUI=%{%{reply:Chargeable-User-Identity}:-Unknown} MSG=%{%{reply:Reply-Message}:-No Failure Reason} RESULT=FAIL"
}
}
#
# SOLO IDENTITY PROVIDER
#
linelog eduroam_inner_log {
filename = ${logdir}/eduroam-log-inner
format = ""
reference = "inner_auth_log.%{%{reply:Packet-Type}:-format}"
inner_auth_log {
Access-Accept = "%S user-auth USER=%{User-Name} VISINST=%{request:Operator-Name} CSI=%{%{Calling-Station-Id}:-Unknown Caller Id} NAS=%{%{Called-Station-Id}:-Unknown Access Point} CUI=%{%{%{reply:Chargeable-User-Identity}:-%{outer.reply:Chargeable-User-Identity}}:-Local User} RESULT=OK"
Access-Reject = "%S user-auth USER=%{User-Name} VISINST=%{request:Operator-Name} CSI=%{%{Calling-Station-Id}:-Unknown Caller Id} NAS=%{%{Called-Station-Id}:-Unknown Access Point} CUI=%{%{%{reply:Chargeable-User-Identity}:-%{outer.reply:Chargeable-User-Identity}}:-Local User} RESULT=FAIL"
}
}
ed abilitarlo creando un link in mods-enabled
.
cd /etc/freeradius/mods-enabled
ln -s ../mods-available/eduroam_logging .
Proxy degli attributi¶
Per Identity Provider e Resource Provider
Affinché FreeRADIUS invii alla federazione eduroam tutti gli attributi obbligatori, è necessario modificare i file pre-proxy
e post-proxy
Pre-proxy¶
Modificare il file mods-config/attr_filter/pre-proxy
con il seguente contenuto:
DEFAULT
User-Name =* ANY,
EAP-Message =* ANY,
Message-Authenticator =* ANY,
NAS-IP-Address =* ANY,
NAS-Identifier =* ANY,
NAS-Port-Type =* ANY,
State =* ANY,
Proxy-State =* ANY,
Operator-Name =* ANY,
Class =* ANY,
Calling-Station-Id =* ANY,
Called-Station-Id =* ANY,
Chargeable-User-Identity =* ANY
Post-proxy¶
Modificare il file mods-config/attr_filter/post-proxy
con il seguente contenuto:
DEFAULT
Reply-Message =* ANY,
Proxy-State =* ANY,
EAP-Message =* ANY,
Message-Authenticator =* ANY,
MS-MPPE-Recv-Key =* ANY,
MS-MPPE-Send-Key =* ANY,
State =* ANY,
Calling-Station-Id =* ANY,
Operator-Name =* ANY,
User-Name =* ANY,
Class =* ANY,
Chargeable-User-Identity =* ANY