Freeradius est un serveur Radius libre permettant de s’authentifier. Le protocole radius permet de se connecter via un échange de paquets UDP, généralement sur le port 1812. Radius intègre également un module d’accounting, permettant par exemple de la facturation. Radius permet de s’authentifier via diverses moyens comme une authentification en clair, par adresse MAC, via base MySQL/PgSQL, protocole MSCHAPv1 et MSCHAPv2 ou encore annuaire LDAP.
Radius gère également le 802.1X avec l’authenfication via tunnel EAP (PEAP/TLS/TTLS), qui sera étudiée en fin de tutoriel.
Freeradius s’appuie sur un système de modules qui sont activés/désactivés lors des phases d’autorisation et d’authentification. Le service peut gérer différents serveurs virtuels, afin de pouvoir gérer plusieurs types d’authentifications conflictuelles, des tunnels internes ou encore des requêtes de proxy radius (en cas de chaînage de différents serveurs radius).
La phase d’autorisation (authorization) définit les modules qui vont intervenir pour autoriser l’utilisateur à utiliser la connexion. La phase d’authentification va s’appuyer sur différents modules pour authentifier l’utilisateur, via son mot de passe ou son adresse MAC par exemple.
Pour installer Freeradius sous Debian, tapez la commande suivante (les paquets ne sont pas tous nécessaires):
aptitude install freeradius freeradius-ldap freeradius-mysql freeradius-postgresql
Pour l’installer sous FreeBSD:
cd /usr/ports/net/freeradius2
make install clean
Allez dans le répertoire /usr/local/etc/raddb/ (/etc/freeradius/ sous Debian) pour trouver l’ensemble des fichiers de configuration. Sous Freeradius 2.x (celle qui sera utilisée tout au long de ce tutoriel) la configuration est répartie en dossiers de manière à simplifier l’administration.
Les différents dossiers sont:
La configuration principale est lue à partir du fichier radiusd.conf, contenant la définition et les liens vers les modules et les serveurs virtuels.
Nous allons tunner un peu la configuration du serveur avant de s’occuper de la partie authentification.
Afin de gagner en temps de réponse, augmentez la taille des buffers de requête, de manière à avoir environ 32 fois le nombre de clients simultanés (la configuration suggère 256 fois, ceci dit ne passez pas en dessous de 1024):
# Pour 300 clients simultanés environ
max_requests = 10240
Ensuite, si c’est activé, pensez à désactiver la résolution des noms d’hôte, de façon à gagner en traitement. Cette valeur ne doit être mise à ‘yes’ que si vous souhaitez vraiment avoir les noms d’hôte au lieu des adresses IP dans vos logs:
hostname_lookups = no
Dans la section log, afin de respecter les mesures de sécurité de votre SI, activez l’option permettant d’identifier les authentifications ayant échoué
auth_badpass = yes
Si votre réseau 802.1X a plus de 500 clients, il peut être judicieux d’augmenter le nombre de threads de traitement des requêtes en simultanés (32 pour 500 est suffisant), modifiez alors ceci le nombre de serveurs maximum et le nombre de serveurs en spare en conséquence, ou alors redondez et utilisez des load balancers:
max_servers = 32
min_spare_servers = 3
max_spare_servers = 10
Votre serveur est désormais taillé afin de pouvoir supporter le maximum de requêtes.
Voyons maintenant comment gérer les différents clients radius
Les clients radius ne sont pas les utilisateurs, mais les services/binaires qui vont permettre d’authentifier l’utilisateur, comme par exemple le client d’une borne Wifi, le mod_auth_xradius d’Apache et bien d’autres encore. Ouvrez le fichier clients.conf
client 127.0.0.1 {
secret = pwdTest
shortname = localhost
nastype = other # localhost isn't usually a NAS...
}
client 192.168.12.0/24 {
secret = wifiPwd
shortname = wifiAP
nastype = other
}
Ce fichier contient les différents clients, identifiés par leur adresse IP ou adresse réseau. Chaque client utilise un secret afin de savoir s’il peut utiliser le serveur radius, et utilise un NASType, option bien souvent inutile ou obsolète. Il est conseillé de la positionner à other, par exemple si vous utilisez des bornes WiFi CISCO.
Voyons maintenant la partie authenfication. Nous étudierons tout d’abord une authentification simple, basée sur un annuaire LDAP, puis ensuite la couche EAP, avant de coupler les deux pour faire du 802.1X avec VLAN dynamiques.
Ouvrez le fichier modules/ldap présent au sein des fichiers de configuration. Voici la configuration de base que vous devriez avoir afin de lier radius et LDAP:
ldap ldap_1 {
server = "ldaps://ldaps.domain.tld"
identity = "cn=admin,dc=domain,dc=tld"
password = admPwd
basedn = "ou=people,dc=domain,dc=tld"
filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})"
dictionary_mapping = "${raddbdir}/ldap.attrmap"
ldap_connections_number = 5
access_attr = "uid"
timeout = 4
timelimit = 3
net_timeout = 1
tls {
start_tls = no
}
set_auth_type = yes
edir_account_policy_check = no
}
Cette configuration permet de définir un module de type LDAP nommé ldap_1. Les premiers champs sont les champs classiques du LDAP (URI, RootDN, RootPwd, BaseSearch, Filter). Vous remarquerez que le filtre est un peu plus complexe que d’habitude. Afin de pouvoir trouver l’utilisateur en fonction de son uid, il faut passer par l’attribut radius Stripped-User-Name.
On va indiquer un dictionnaire LDAP. Ce dictionnaire est ESSENTIEL, puisqu’il va servir à permettre d’aller chercher certain attributs permettant l’authentification, notamment via le module MSCHAP pour 802.1X.
Le champ access_attr permet d’accélérer le traitement des authentifications en indiquant l’attribut de référence qui permet de définir si un utilisateur existe. SI l’utilisateur n’a pas été trouvé, le serveur radius indiquera directement echec en sortie d’autorisation (hormis si vous spécifiez plusieurs types d’authentifications en parallèle), et ne cherchera pas à savoir si l’utilisateur a mis le bon mot de passe, ou a utiliser un tunnel EAP par exemple.
Les autres champs permettent de définir les différents timeout et éventuellement les options TLS, si vous l’utilisez.
Maintenant que le serveur ldap est défini, nous allons l’activer dans les phases d’autorisation et d’authentification. Ouvrez le fichier sites-enabled/default
authorize {
preprocess
suffix
files
group {
ldap_1
}
}
authenticate {
unix
Auth-Type LDAP1 {
ldap_1
}
}
# --- fin non exhaustive --- #
Nous créons dans la section authorize un groupe dans lequel se trouve l’appel à notre module ldap_1 (attention l’indentation est importante). Ce groupe permet de définir un ensemble de serveurs qui peuvent servir à authentifier l’utilisateur. Par exemple si votre entreprise possède un OpenLDAP et un ActiveDirectory avec deux identifiants/mots de passe différents, cela permet de pouvoir s’authentifer sur l’un OU l’autre. Sans la notion de groupe ce serait l’un ET l’autre.
Dans la section authenticate, on créé un type d’authentification LDAP1 qui utilise le module ldap_1. L’Auth-Type permet de pouvoir positionner la variable Auth-Type avec la valeur associée afin de pouvoir effectuer des tests dessus, notamment via le fichiers users, étudié plus loin dans ce tutoriel.
Vous pouvez désormais lancer votre serveur radius (voir plus loin) en mode démon, ou en mode debug afin de tester la configuration.
Un tunnel EAP est un tunnel chiffré et négocié entre le client radius et le serveur. Il existe différents types d’EAP, avec différents niveaux de sécurité:
Nous étudierons ici l’authentification PEAP, plus simple à mettre en place via l’authentification MSCHAP. Il existe également PEAP avec authentification GTC.
Ouvrez tout d’abord le fichier eap.conf
eap {
default_eap_type = peap
timer_expire = 60
ignore_unknown_eap_types = no
max_sessions = 4096
tls {
certdir = ${confdir}/certs
cadir = ${confdir}/certs
private_key_password = whatever
private_key_file = ${certdir}/server.key
certificate_file = ${certdir}/server.pem
CA_file = ${cadir}/ca.pem
dh_file = ${certdir}/dh
random_file = ${certdir}/random
CA_path = ${cadir}
make_cert_command = "${certdir}/bootstrap"
}
peap {
default_eap_type = mschapv2
copy_request_to_tunnel = yes
use_tunneled_reply = yes
virtual_server = "inner-tunnel"
}
mschapv2 {
}
}
On définit tout d’abord le type d’eap par défaut à PEAP. Ceci permet d’initier la connexion via le tunnel PEAP lorsqu’EAP sera sollicité. Pour la sécurité, vous pouvez définir d’ignorer les types EAP non connus (non définis) sur le serveur Radius. Le nombre de sessions EAP simultanées à été défini à 4096, sachant que chaque requête peut engendrer entre 2 et 3 sessions suivant le type d’EAP utilisé.
La section TLS permet de définir les certificats utilisés. Ici ce sont les certificats par défaut, mais je vous convie à en générer de nouveaux au nom de votre entreprise, signés ou auto-signés suivant la situation.
La section peap est la plus intéressante ici. Tout d’abord on va redéfinir le type d’EAP à utiliser en tant que mschapv2, ce qui permettra d’utiliser l’authentification via NT-Password. On va ensuite activer deux éléments essentiels au 802.1X, notamment pour l’attribution dynamique de VLANs, ce sont la copie de la requête dans le tunnel et la copie de la réponse du tunnel dans la réponse EAP (ce qui permet ainsi de ramener des attributs de l’authentification MSCHAPv2, autrement ce ne serait pas possible). Pour finir, on définit un serveur virtuel local qui va permettre de traiter l’authentification MSCHAPv2.
EAP est maintenant correctement configuré, ouvrez maintenant le fichier ldap.attrmap et ajoutez les lignes suivantes:
checkItem LM-Password sambaLmPassword
checkItem NT-Password sambaNtPassword
En ajoutant ces lignes vous pourrez utiliser les attributs LDAP NT-Password et LM-Password avec l’authentification MS-CHAPv2
Maintenant que les attributs LDAP sont mappés, ouvrez sites-enabled/default:
authorize {
preprocess
mschap
suffix
eap {
ok = return
}
files
group {
ldap_1
}
}
authenticate {
Auth-Type MS-CHAP {
mschap
}
unix
Auth-Type LDAP {
ldap_1
}
Auth-Type eap {
eap {
handled = 1
}
if (handled && (Response-Packet-Type == Access-Challenge)) {
attr_filter.access_challenge.post-auth
handled # override the "updated" code from attr_filter
}
}
}
# sortie volontairement omise
post-proxy {
eap
}
Vous remarquerez quelques ajouts par rapport à la section précédente concernant LDAP. On doit activer EAP dans la section authorize. La sous section ok=return permet de définir de ne pas aller ailleurs si cette autorisation s’est bien déroulée.
La section authenticate contient maintenant en plus le type MS-CHAP et eap. quelques instructions et modules supplémentaires sont invoqués afin de parfaire l’échange au sein du tunnel.
La section post-proxy a été complétée, si vous utilisez le mode proxy sur votre serveur Radius, afin que l’échange EAP se termine correctement dans ce cas là.
Ouvrez maintenant le fichier sites-enabled/inner-tunnel
authorize {
mschap
suffix
update control {
Proxy-To-Realm := LOCAL
}
eap {
ok = return
}
files
group {
ldap_1
}
}
authenticate {
Auth-Type MS-CHAP {
mschap
}
unix
eap
}
post-proxy {
eap
}
La configuration est similaire ici au serveur par défaut. La section update control permet de forcer la mise à jour de la requête afin de définir que le Realm utilisé est LOCAL. Vous remarquerez qu’ici on n’utilise pas l’authentification LDAP, ceci est dû au fait que PEAP va s’appuyer sur le module MS-CHAP au sein du tunnel.
On aurait pu se passer de MS-CHAP et forcer l’authentification en LDAP ici, mais il aurait fallu que l’attribut userPassword de l’annuaire soit en clair, ce qui est fortement déconseillé !
Attention ! Utilisant le protocole d’authentification MSCHAP, il faut obligatoirement avoir le schéma et les attributs remplis dans votre annuaire !
Ceci conclut cette partie sur EAP. Cela permettra de faire du 802.1X statique au sein de votre réseau (en WiFi, via WPA/WPA2 Enterprise notamment).
La puissance de 802.1X réside dans l’attribution dynamique de VLAN, en fonction de catégories d’utilisateurs et/ou de permissions et de politique de sécurité.
L’ensemble de la configuration ne sera pas redétaillé ici, il suffit de reprendre la configuration sur EAP et de s’appuyer sur un annuaire LDAP. Afin de configurer l’attribution dynamique de VLANs, deux choix apparaissent.
Le premier, et le plus simple à mettre en oeuvre, est celui de l’annuaire qui founit la configuration 802.1X.
Sur votre annuaire LDAP, rajoutez le schéma radius adapté. Ouvrez ensuite le fichier ldap.attrmap et rajoutez l’ensemble des lignes suivantes:
checkItem Expiration radiusExpiration
checkItem NAS-IP-Address radiusNASIpAddress
replyItem Service-Type radiusServiceType
replyItem Framed-Protocol radiusFramedProtocol
replyItem Framed-IP-Address radiusFramedIPAddress
replyItem Framed-IP-Netmask radiusFramedIPNetmask
replyItem Framed-Route radiusFramedRoute
replyItem Framed-Routing radiusFramedRouting
replyItem Filter-Id radiusFilterId
replyItem Framed-MTU radiusFramedMTU
replyItem Framed-Compression radiusFramedCompression
replyItem Login-IP-Host radiusLoginIPHost
replyItem Login-Service radiusLoginService
replyItem Login-TCP-Port radiusLoginTCPPort
replyItem Callback-Number radiusCallbackNumber
replyItem Callback-Id radiusCallbackId
replyItem Framed-IPX-Network radiusFramedIPXNetwork
replyItem Class radiusClass
replyItem Session-Timeout radiusSessionTimeout
replyItem Idle-Timeout radiusIdleTimeout
replyItem Termination-Action radiusTerminationAction
replyItem Login-LAT-Service radiusLoginLATService
replyItem Login-LAT-Node radiusLoginLATNode
replyItem Login-LAT-Group radiusLoginLATGroup
replyItem Framed-AppleTalk-Link radiusFramedAppleTalkLink
replyItem Framed-AppleTalk-Network radiusFramedAppleTalkNetwork
replyItem Framed-AppleTalk-Zone radiusFramedAppleTalkZone
replyItem Port-Limit radiusPortLimit
replyItem Login-LAT-Port radiusLoginLATPort
replyItem Reply-Message radiusReplyMessage
replyItem Tunnel-Type radiusTunnelType
replyItem Tunnel-Medium-Type radiusTunnelMediumType
replyItem Tunnel-Private-Group-Id radiusTunnelPrivateGroupId
En ajoutant ce mappage d’attributs au serveur radius, celui-ci va lire les données de l’annuaire LDAP et les mapper à ses propres attributs. Les attributs qui nous intéressent pour le 802.1X sont les 3 derniers.
En positionnant les valeurs de Tunnel-Type à “VLAN”, Tunnel-Medium-Type à “IEEE-802” et en inscrivant l’ID du VLAN dans le champ Tunnel-Private-Group-Id, vous renverez l’ordre à votre équipement de commuter l’utilisateur dans le VLAN associé.
Ce technique a le mérite d’être simple, mais alourdit votre serveur d’annuaire d’autant d’entrées que d’utilisateurs, ce qui peut dans certains cas s’avérer gênant. Dans certains cas également, il se peut que l’annuaire ne soit pas sous votre contrôle mais soit externalisé ou mutualisé, auquel cas vous ne pouvez pas opérer à cette manipulation, c’est pourquoi il existe une seconde alternative.
Toujours dans ce fichier ldap.attrmap, ajoutez cette fois-ci uniquement cette ligne:
checkItem LDAP-Desc description
Cette entrée aura pour effet d’aller chercher le champ description de votre annuaire et de le mapper à l’attribut LDAP-Desc. Ce champ n’étant pas conventionnel, nous allons le déclarer dans le dictionnaire. Ouvrez le fichier dictionnary et ajoutez la ligne suivante en fin de fichier:
ATTRIBUTE LDAP-Desc 3000 string
Le dictionnaire définit des attributs. Ici on créée un attribut LDAP-Desc d’ID 3000 sous forme de chaîne de caractères.
Note: Les attributs radius d’ID 3000 à 4000 ne sont pas rediffusés vers le client radius.
Maintenant que nous relions l’attribut LDAP description à notre attribut radius nous allons pouvoir l’utiliser. Ouvrez maintenant le fichier sites-enabled/innel-tunnel.
post-auth {
if ("%{check:LDAP-Desc}" == "Administration") {
update reply {
Tunnel-Private-Group-Id = 15
}
}
elsif ("%{check:LDAP-Desc}" == "Recherche") {
update reply {
Tunnel-Private-Group-Id = 18
}
}
elsif ("%{check:LDAP-Desc}" == "Eleves") {
update reply {
Tunnel-Private-Group-Id = 72
}
}
else {
update reply {
Tunnel-Private-Group-Id = 37
}
}
update reply {
Tunnel-Type = "VLAN"
Tunnel-Medium-Type = "IEEE-802"
}
Post-Auth-Type REJECT {
attr_filter.access_reject
}
}
Ceci est la partie intéressante du 802.1X. Dans la section post-auth vous serez en mesure de scripter des éléments une fois l’authentification effectuée.
Dans le cas présent, on regarde la valeur de l’attribut radius LDAP-Desc, et suivant sa valeur, on définit un ID de VLAN (18 pour la recherche, 72 pour les élèves et 37 par défaut, si la valeur présente dans l’annuaire n’est pas connue). Avec la méthode update reply, on va ajouter/modifier un champ de la réponse à notre guise.
En sortie de phase, la réponse contiendra donc les deux définitions nécessaire au VLAN et l’ID du VLAN.
Ceci conclut notre partie sur le 802.1X et Freeradius. Vous êtes désormais en mesure de créer des Tunnels EAP avec attribution dynamique de VLAN, que ce soit en WiFi ou en filaire. Je vous convie à regarder la documentation de votre équipement afin de valider les fonctionnalités 802.1X.
Note: il faut que les VLAN soient connus de l’équipement pour que cela marche et il faut un bridge DotRadio/FastEthernet pour chaque VLAN qui sera attribué via le serveur Radius.
L’authentification par adresse MAC permet de n’autoriser que certaines machines à accéder au réseau, et à défaut de les mettre dans un vlan dit guest. Nous allons ici nous appuyer sur une base SQL pour effectuer l’authentification des adresses MAC et leur attribuer un VLAN.
Créez un serveur virtuel dédié à l’authentification mac ou le fichier de configuration principal si votre serveur n’utilise pas d’autre (/usr/local/etc/raddb/sites-enabled/mac-auth dans notre cas) et insérez le contenu suivant:
server mac-auth {
listen {
ipaddr = 0.0.0.0
port = 2812
type = auth
}
authorize {
preprocess
suffix
if(!EAP-Message || User-Name) {
sql
if(!ok) {
reject
}
else {
update control {
Auth-Type := Accept
}
}
}
else {
eap
}
expiration
logintime
}
authenticate {
eap
}
session {
radutmp
sql
}
post-auth {
sql
update reply {
User-Name = "%{request:User-Name}"
}
Post-Auth-Type REJECT {
sql
attr_filter.access_reject
}
}
preacct {
preprocess
}
accounting {
sql
}
} # mac-auth server block
Nous écoutons ici sur toutes les interfaces sur le port 2812 UDP, afin de se différencier des autres hosts, vous pouvez le changer à volonté. EAP pouvant être utilisé pour les requêtes, il a été ajouté à l’authentication et à l’authorization. Les tentatives d’authentification ayant échouées sont loguées et l’accouting est effectué ici.
Le script en rouge permet de switcher de façon propre entre EAP et l’authentification normale via SQL suivant le type de requête radius.
Votre serveur radius est maintenant relié à la base de données MySQL. Maintenant voyons comme gérer efficacement l’authentification en base. Tout d’abord, on doit définir qu’on accepte l’adresse MAC dans la table radcheck.
INSERT INTO radcheck (username,attribute,op,value) VALUES ('001122334455','Auth-Type',':=','Accept');
Cette requête SQL permet d’ajouter l’adresse MAC 00:11:22:33:44:55 et de l’autoriser au niveau radius. Ici nous souhaitons aller plus loin et attribuer les VLAN dynamiquement. On va donc créer un groupe au sein du radius qui permettra de gérer les VLAN. Dans un premier temps on met les adresses dans un groupe:
INSERT INTO radusergroup (username,groupname,priority) VALUES ('001122334455','ADMIN',0);
INSERT INTO radusergroup (username,groupname,priority) VALUES ('ffcc22aa4455','COMPTA',0);
INSERT INTO radusergroup (username,groupname,priority) VALUES ('eacc22bb4488','COMPTA',0);
La seconde fonction intéressante se situe dans radgroupreply, qui permet d’ajouter des attributs à la réponse pour des groupes. Nous allons donc le faire.
INSERT INTO radgroupreply (groupname,attribute,op,value) VALUES ('ADMIN','Tunnel-Private-Group-Id','=','18');
INSERT INTO radgroupreply (groupname,attribute,op,value) VALUES ('ADMIN','Tunnel-Type,'=','13');
INSERT INTO radgroupreply (groupname,attribute,op,value) VALUES ('ADMIN','Tunnel-Medium-Type','=','6');
INSERT INTO radgroupreply (groupname,attribute,op,value) VALUES ('COMPTA','Tunnel-Private-Group-Id','=','258');
INSERT INTO radgroupreply (groupname,attribute,op,value) VALUES ('COMPTA','Tunnel-Type,'=','13');
INSERT INTO radgroupreply (groupname,attribute,op,value) VALUES ('COMPTA','Tunnel-Medium-Type','=','6');
Cet ensemble de commandes permet d’ajouter le tag VLAN 18 aux machines faisant partie du groupe ADMIN et VLAN 256 aux machines du groupe COMPTA.
Sous FreeBSD:
service radiusd start
Sous Debian:
service freeradius start
Si vous avez besoin de vérifier la configuration, deux éléments essentiels sont présent au sein de la solution. Tout d’abord, vous pouvez mettre le service en mode Debug. Pour cela éteignez le et lancez la commande
radiusd -X
Ce mode d’allumage en premier plan va permettre d’affichier le suivi des requêtes entrantes sur votre serveur radius et ainsi pouvoir debuguer les problématiques d’algorithmes, de mot de passe, de modules…
Deuxième outil essentiel (hors authentification EAP), la commande radtest permettra de se connecter à un serveur radius afin de tester l’authentification.
radtest username password localhost:1812 0 radiusSecret
Ceci conclut ce tutoriel sur Freeradius, en espérant qu’il vous aura éclairé.