[ Accueil ] [ FreeRADIUS ] [ Pour les VLANs ] [ Pour WPA2 ] [ Révocations ]
Dans notre solution globale, nous gérons le réseau filaire par une authentification de type "login/password" où l'adresse MAC joue le rôle des deux composants. Nous disposons d'une base de données MySQL (ou Postgresql) qui recense toutes les adresses MAC connues. Nous avons pu tester son bon fonctionnement en utilisant un "login/password" introduit dans la base de données.
En ce qui concerne le réseau Wi-Fi, nous avons confié à EAP l'authentification, via le protocole TLS. Nous avons vu que, dans ce cas, tout se passe par l'intermédiaire des certificats, et qu'il n'y a aucune information dans la base de données.
Comment faire alors si pour une raison ou une autre, nous devions être amenés à bloquer un utilisateur disposant d'un certificat en cours de validité ? Il peut y avoir plusieurs raisons qui pourraient amener à cette résolution, comme :
Dans notre configuration actuelle, ce type de situation ne peut être géré, il nous faut trouver une solution, si possible pas trop complexe à maintenir.
Deux voies sont à explorer :
TinyCA sait générer simplement des certificats de révocation, et FreeRADIUS peut être configuré assez simplement pour en tenir compte. Cette solution offre cependant deux gros défauts pour la maintenance :
Cette solution n'est clairement pas facile à gérer.
Si nous trouvons un moyen pour que le certificat client ne soit accepté que si l'utilisateur est référencé dans la base, les choses deviendraient beaucoup plus simples, il suffirait d'ajouter ou de supprimer une ligne dans la base pour suspendre, temporairement ou non, un compte d'utilisateur, même si le certificat est encore en cours de validité.
Cette solution nous obligera à créer une ligne par utilisateur Wi-Fi dans notre base de données, en plus du certificat, mais nous permettra de gérer nettement plus facilement les impondérables.
Pour arriver à ce résultat, il va nous falloir entrer plus en profondeur dans le fonctionnement de RADIUS. Dans notre configuration très simple, nous ne définissons pas de type d'authentification approprié à chaque requête. Le résultat est que pour chaque requête, tous les types d'authentification possibles sont testés, si l'un d'entre eux renvoie "Accept", l'autorisation est donnée.
Actuellement, nous avons :
authorize { preprocess eap sql }
C'est à dire que nous autoriserons les connexions soit par EAP, soit par la base de données sql, et nous n'avons défini nulle part de façon explicite le mode d'authentification pour un utilisateur donné. Le résultat est que :
Que se passerait-il, si nous trouvions le moyen de fixer le mode d'authentification par défaut ?
Ceci peut se réaliser par l'intermédiaire du fichier "users", à la condition d'ajouter "files" dans la section "authorize" de radiusd.conf. Si nous arrivons à forcer le serveur à rejeter par défaut toute authentification, puis à l'autoriser à utiliser un mode particulier pour un utilisateur donné, nous serons proches de la solution.
Nous mettons dans "users" la simple ligne "DEFAULT Auth-Type := Reject". Par défaut, l'autorisation devrait ainsi être refusée à tout le monde. :
# cat users
DEFAULT Auth-Type := Reject
Le problème étant maintenant d'attribuer un type d'authentification correct aux utilisateurs Wi-Fi connus. Il faut le faire avant de définir le mode par défaut. Fort heureusement, les autorisations sont lues séquentiellement dans la section "authorize".
authorize {
preprocess
sql
files
eap
}
A part que, avec cette écriture, lorsque l'on sort d'un module on entre dans le suivant, quelle que soit la réponse du module précédent, pourvu qu'il n'y ait pas eu de "Reject". Ici, même si SQL accorde un "Auth-Type := EAP" à un utilisateur connu, cette valeur sera écrasée par le Auth-Type par défaut du fichier "users"; et donc personne ne sera autorisé, ce n'est pas ce que nous voulons.
Si nous plaçons files avant sql, ça ne fonctionnera pas non plus, puisque le type d'authentification "Reject" sera rencontré en premier, mettant fin à la procédure.
Fort heureusement, le mode "fail-over" va venir à notre secours sous cette forme :
authorize { preprocess redundant { sql files eap } }
Ainsi, lorsqu'un utilisateur est trouvé dans la base sql, soit il sera authentifié en mode Local, si son mot de passe est indiqué (pour les autorisations depuis les adresses MAC), soit, si un mode d'authentification de type TLS lui est attribué, EAP fonctionnera.
Si en revanche aucun mode d'authentification n'est attribué, c'est le mode par défaut qui passera et, même avec un certificat valide, l'utilisateur devrait être rejeté.
Essayons un "login/password":
Sending Access-Request of id 25 to 127.0.0.1 port 1812
User-Name = "test0"
User-Password = "userpassword"
NAS-IP-Address = 255.255.255.255
NAS-Port = 0
rad_recv: Access-Accept packet from host 127.0.0.1:1812, id=25, length=20
C'est bon. Essayons maintenant le Wi-Fi avec un certificat valide, présentant le nom d'utilisateur userwifi1, non répertorié dans la base des utilisateurs, l'authentification échouera. Si maintenant nous ajoutons ceci dans la base :
# echo "INSERT INTO radcheck(UserName,Attribute,op,Value) VALUES ('userwifi1','Auth-Type',':=','EAP');" \ | mysql -u root -p radius
L'authentification eap devrait réussir. Voyons un "best-of" des logs de freeradius lancé en mode "debug" :
rad_recv: Access-Request packet from host 192.168.10.3:1046, id=19, length=163
User-Name = "userwifi1"
NAS-IP-Address = 192.168.10.3
Connect-Info = "CONNECT 802.11"
Called-Station-Id = "000f3dab9ac9"
Calling-Station-Id = "000fb572abe0"
NAS-Identifier = "00-0f-b5-72-ab-e0"
NAS-Port-Type = Wireless-802.11
NAS-Port = 1
NAS-Port-Id = "1"
Framed-MTU = 1400
EAP-Message = 0x0201001201636c6e74302e6274732e656d65
Message-Authenticator = 0x417f19394ab35a5eda42ffb628855e41
rlm_sql (sql): Reserving sql socket id: 3
rlm_sql (sql): Released sql socket id: 3
Sending Access-Challenge of id 19 to 192.168.10.3 port 1046
EAP-Message = 0x010200060d20
Message-Authenticator = 0x00000000000000000000000000000000
State = 0xee660260336863b8917d0c319918e83e
...
...
...
error=0
--> User-Name = userwifi1
--> BUF-Name = root_maison_CA
--> subject = /C=FR/ST=France/L=Marseille/O=Maison/OU=Reseau_maison/CN=root_maison_CA/emailAddress=user1@maison.mrs
--> issuer = /C=FR/ST=France/L=Marseille/O=Maison/OU=Reseau_maison/CN=root_maison_CA/emailAddress=user1@maison.mrs
--> verify return:1
chain-depth=0,
error=0
--> User-Name = userwifi1
--> BUF-Name = userwifi1
--> subject = /C=FR/ST=France/L=Marseille/O=Maison/OU=Reseau_maison/CN=userwifi1/emailAddress=userwifi1
--> issuer = /C=FR/ST=France/L=Marseille/O=Maison/OU=Reseau_maison/CN=root_maison_CA/emailAddress=user1@maison.mrs
--> verify return:1
rlm_eap: SSL error error:00000000:lib(0):func(0):reason(0)
Sending Access-Challenge of id 26 to 192.168.10.3 port 1046
EAP-Message = 0x010900350d800000002b1403010001011603010020bea471f3b5...
Message-Authenticator = 0x00000000000000000000000000000000
State = 0xf22d9e05e6fc415b67c3b36def7a809d
rad_recv: Access-Request packet from host 192.168.10.3:1046, id=27, length=169
User-Name = "userwifi1"
NAS-IP-Address = 192.168.10.3
Connect-Info = "CONNECT 802.11"
Called-Station-Id = "000f3dab9ac9"
Calling-Station-Id = "000fb572abe0"
NAS-Identifier = "00-0f-b5-72-ab-e0"
NAS-Port-Type = Wireless-802.11
NAS-Port = 1
NAS-Port-Id = "1"
Framed-MTU = 1400
State = 0xf22d9e05e6fc415b67c3b36def7a809d
EAP-Message = 0x020900060d00
Message-Authenticator = 0x1a08bc62c3852a0b6436c016ba81dfd6
rlm_sql (sql): Reserving sql socket id: 0
rlm_sql (sql): Released sql socket id: 0
Sending Access-Accept of id 27 to 192.168.10.3 port 1046
MS-MPPE-Recv-Key = 0xd6a70248ae96a9e5621d6053bad74de70db8b358ad3e79bcda1351ec50375873
MS-MPPE-Send-Key = 0xf418a1cf92136b7e5b948dd0fbf51a0b7a95b06456abc4e15c4df200e57cc29c
EAP-Message = 0x03090004
Message-Authenticator = 0x00000000000000000000000000000000
User-Name = "userwifi1"
Vérifions tout de même que si l'utilisateur est supprimé de la table "radcheck", l'authentification va échouer :
mysql> select * from radcheck; +----+---------------+---------------+----+--------------+---------+ | id | UserName | Attribute | op | Value | Comment | +----+---------------+---------------+----+--------------+---------+ | 1 | test0 | User-Password | == | userpassword | NULL | | 11 | userwifi1 | Auth-Type | := | EAP | NULL | +----+---------------+---------------+----+--------------+---------+ 2 rows in set (0.00 sec)
mysql> delete from radcheck where id = 11; Query OK, 1 row affected (0.00 sec)
Le log de freeradius deviendra beaucoup plus court :
rad_recv: Access-Request packet from host 192.168.10.3:1046, id=28, length=163 User-Name = "userwifi1" NAS-IP-Address = 192.168.10.3 Connect-Info = "CONNECT 802.11" Called-Station-Id = "000f3dab9ac9" Calling-Station-Id = "000fb572abe0" NAS-Identifier = "00-0f-b5-72-ab-e0" NAS-Port-Type = Wireless-802.11 NAS-Port = 1 NAS-Port-Id = "1" Framed-MTU = 1400 EAP-Message = 0x0201001201636c6e74302e6274732e656d65 Message-Authenticator = 0x0c3f20db2c9341cac65bff1c4bf17e37 rlm_sql (sql): Reserving sql socket id: 3 rlm_sql (sql): User userwifi1 not found in radcheck rlm_sql (sql): User userwifi1 not found in radgroupcheck rlm_sql (sql): Released sql socket id: 3 rlm_sql (sql): User not found Sending Access-Reject of id 28 to 192.168.10.3 port 1046
Nous n'avons plus trop besoin de gérer de certificats de révocation.
Ce que nous venons de voir va nous contraindre à mélanger dans la même table les utilisateurs qui disposent d'une authentification de type CHAP (réseau filaire) et EAP (réseau Wi-Fi). Les tables "radgroupcheck" et "usergroup" vont nous aider à séparer les deux types d'utilisateurs, dans des tables différentes.
L'idée est la suivante. Nous allons créer un groupe d'utilisateur nommé "wifiGroup" (dans la table "radgroupcheck"), auquel nous allons appliquer l'attribut "Auth-Type := EAP". Il suffira ensuite d'intégrer nos utilisateurs Wi-Fi dans ce groupe (dans la table "usergroup"), pour qu'ils héritent de l'attribut.
mysql> INSERT INTO radgroupcheck(GroupName,Attribute,op,Value) VALUES ('wifiGroup','Auth-Type',':=','EAP'); Query OK, 1 row affected (0.00 sec) mysql> INSERT INTO usergroup(UserName,GroupName) VALUES ('userwifi1','wifiGroup'); Query OK, 1 row affected (0.00 sec)
Freeradius considèrera que tous les membres du groupe "wifiGroup" doivent être identifiés via EAP, et les membres de ce groupe sont tous définis dans la table "usergroup". De cette manière, il sera plus facile de gérer les deux types d'utilisateurs.
Nous sommes loin d'avoir vu tout ce qu'il est possible de faire avec RADIUS, mais nous avons réalisé ce que nous voulions faire.
Dans le cas du réseau filaire, il est également possible d'attribuer un ID de VLAN différent suivant l'utilisateur authentifié, de même qu'il est possible de remplacer EAP-TLS par PEAP, si l'on dispose par exemple d'un annuaire ActiveDirectory et que l'on souhaite que les clients Wi-Fi soient authentifiés avec leur "login/password" du réseau Microsoft, plutôt que par un certificat. La machine qui héberge FreeRadius doit alors être intégrée au domaine Microsoft et pouvoir interroger l'annuaire ActiveDirectory. A mon sens, EAP-TLS reste préférable.