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.
Actuellement, eap
est un mode d'authentification par défaut, si bien que tout certificat présenté, s'il est authentique et non révoqué, sera accepté sans autre contrainte. Si nous trouvons un moyen pour que eap
ne soit utilisé 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é.
Nous verrons que lorsque le client est configuré pour utiliser eap-tls
, il présente son cetificat, dans tous les cas de figure. Dans ce certificat, il y a le nom de l'utilisateur. Exemple :
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 20 (0x14)
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=FR, ST=France, L=Marseille, O=Maison, OU=Reseau_maison, CN=root_maison_CA/emailAddress=chris@maison.mrs
Validity
Not Before: Jan 6 12:17:58 2009 GMT
Not After : Nov 13 12:17:58 2016 GMT
Subject: C=FR, ST=France, L=Marseille, O=Maison, OU=Reseau_maison, CN=user1/emailAddress=user1@maison.mrs
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (4096 bit)
...
Si nous trouvons un moyen d'expliquer à notre FreeRADIUS que seuls les utilisateurs référencés dans un groupe particulier pourront utiliser EAP
, ceci devrait résoudre notre problème.
Pour rappel, nous avons actuellement dans /etc/freeradius/sites-avalable/default
les directives suivantes :
authorize { preprocess eap { ok = return } sql } authenticate { Auth-Type CHAP { chap } eap }
Nous allons simplifier /etc/freeradius/sites-avalable/default
comme suit :
authorize { preprocess sql } ...
De cette manière, eap
ne sera plus autorisé par défaut et, sans informations supplémentaires, plus aucun certificat ne sera accepté puisque eap-tls
ne sera plus reconnu comme un moyen d'authentification valide.
Voici ce qu'il va se passer lorsque user1
va présenter son certificat :
rad_recv: Access-Request packet from host 192.168.1.254 port 1285, id=0, length=199 Message-Authenticator = 0xcb9362792c3a93b83a28b6153462c2db Service-Type = Framed-User User-Name = "user1\000" Framed-MTU = 1488 Called-Station-Id = "00-0F-3D-AB-66-E8:maisonwifi" Calling-Station-Id = "00-1F-3C-4B-07-9C" NAS-Identifier = "D-Link Access Poi" NAS-Port-Type = Wireless-802.11 Connect-Info = "CONNECT 54Mbps 802.11g" EAP-Message = 0x0200000e016c61702d70726f6673 NAS-IP-Address = 192.168.1.254 NAS-Port = 1 NAS-Port-Id = "STA port # 1" +- entering group authorize ++[preprocess] returns ok expand: %{User-Name} -> user1 rlm_sql (sql): sql_set_user escaped user --> 'user1' rlm_sql (sql): Reserving sql socket id: 3 expand: SELECT id, username, attribute, value, op FROM radcheck WHERE username = '%{SQL-User-Name}' ORDER BY id -> SELECT id, username, attribute, value, op FROM radcheck WHERE username = 'user1' ORDER BY id expand: SELECT groupname FROM radusergroup WHERE username = '%{SQL-User-Name}' ORDER BY priority -> SELECT groupname FROM radusergroup WHERE username = 'user1' ORDER BY priority rlm_sql (sql): Released sql socket id: 3 rlm_sql (sql): User user1 not found ++[sql] returns notfound auth: No authenticate method (Auth-Type) configuration found for the request: Rejecting the user auth: Failed to validate the user. Login incorrect: [user1\000/] (from client dwl2100ap port 1 cli 00-1F-3C-4B-07-9C) Delaying reject of request 10 for 1 seconds Going to the next request Waking up in 0.9 seconds. Sending delayed reject for request 10 Sending Access-Reject of id 0 to 192.168.1.254 port 1285 Waking up in 3.9 seconds.
Il n'y a pas de mot de passe, il n'y a pas d'autre méthode d'authentification, le client est rejeté.
La notion de groupes existe dans radius
. Si nous créons un groupe d'utilisateurs qui ont EAP
comme méthode d'authentification, et que nous plaçons dans ce groupe les noms des clients qui ont un certificat en cours de validité, ça devrait fonctionner.
Dans la table radgroupcheck
, nous créons un groupe que nous appellerons « wifiGroup » auquel nous accordons le type d'authentification EAP
:
mysql> INSERT INTO radgroupcheck(GroupName,Attribute,op,Value) VALUES ('wifiGroup','Auth-Type',':=','EAP'); Query OK, 1 row affected (0.00 sec)
Il nous reste maintenant à associer dans la table usergroup
l'utilisateur « user1 » au groupe « wifiGroup » :
mysql> INSERT INTO usergroup(UserName,GroupName) VALUES ('user1','wifiGroup'); Query OK, 1 row affected (0.00 sec)
Et à vérifier que notre méthode fonctionne :
ad_recv: Access-Request packet from host 192.168.1.254 port 1287, id=5, length=1703 Message-Authenticator = 0x5a717acfbd03837c04baa4ff01be6399 Service-Type = Framed-User User-Name = "user1\000" Framed-MTU = 1488 State = 0x411d49f94518440d3eeebef8b48bd82c Called-Station-Id = "00-0F-3D-AB-66-E8:maisonwifi" Calling-Station-Id = "00-1F-3C-4B-07-9C" NAS-Identifier = "D-Link Access Poi" NAS-Port-Type = Wireless-802.11 Connect-Info = "CONNECT 54Mbps 802.11g" EAP-Message = 0x020505d20dc000000a901603010a600b00075000074d00074a308207463082052ea003020102020114300d06092a864886f70d0101050500308199310b3009060355040613024652310f300d060355040813064672616e636531123010060355040713094d61727365696c6c65310c300a060355040a1303454d453110300e060355040b130752657365617578311430120603550403140b526f6f745f454d455f4341312f302d06092a864886f70d0109011620736572766963652e696e666f40656d652d656e736569676e656d656e742e6672301e170d3039303130363132313735385a170d3136313131333132313735385a308185310b30090603 EAP-Message = 0x55040613024652310f300d060355040813064672616e636531123010060355040713094d61727365696c6c65310c300a060355040a1303454d453110300e060355040b13075265736561757831123010060355040313096c61702d70726f6673311d301b06092a864886f70d010901160e63616c65636140656d652e6f726730820222300d06092a864886f70d01010105000382020f003082020a02820201009e200fbbd6d82d2e6187673e7d4ca8fbd7696a564c550e782a40030cf67af8509402a4085765c329804c850bc7f629c0bff57690f7aa879422bb7ebf47cd3efa7e7bd3d6f8ad3c4718e1ba584f73d50fb146fde97aa3d52501b746b63c EAP-Message = 0x597d42670715fb9f0dc758c3efca14ea6efdc1ace976f9dc5346205c04e0b42de56aa643dec29cd0e8aa37223b78748490e089790962226f930d756851fb3fe720be5c65d06fa57c6c1f01a2cf45dd5613ff543d68fe5a10fd94c377e42cb665d7dd8413ce97bae64a00316a8947d33251e0c87b5a514c63854301548305c3ca82b1066f3d59e1be77a96031c08c1dc0606ab45fc4122d6bd7ba5e109c5b36b8529fe7c8e0faae713ebcc143baba93374d78de699814170794caa720559840589f7b71d3390667b20c7a39bf312e68ca48b2a9ea45cab51fdd3451b2753c7d9be63109f8d33bf51993ff0778f4fded95f834d81fe7f499d8e8e025867a EAP-Message = 0x8b9b1ecb74502381f8ce29f3b94ef2808da6438ec64cca64a2644ea659e747b6287bd674b5fcaa4efbcedb4d4b8146c2d831ab675844e2856512f5e5b385c4a7403cc7871114a0c5d645663dfb17f38e3f842c20c688fba23303d1b7b3982d811c9e14af8dfc13129e5d5a3646712f35cacdd850bfe300b0d954cfc041024c2e5adf0f3c2589479df978c1685f8eaf7c6525e70fb9058d2aae777ceb8d9880734d040a51b6d90203010001a38201a9308201a530090603551d1304023000301106096086480186f84201010404030204b0302b06096086480186f842010d041e161c54696e7943412047656e6572617465642043657274696669636174 EAP-Message = 0x65301d0603551d0e0416041447069b70658e7d9f0f4ffe350b37543da59b7f1f3081ce0603551d230481c63081c380143cabad8ef6977ba1e75c1ec13a2221e66e91f252a1819fa4819c308199310b3009060355040613024652310f300d060355040813064672616e636531123010060355040713094d61727365696c6c65310c300a060355040a1303454d453110300e060355040b130752657365617578311430120603550403140b526f6f745f454d455f4341312f302d06092a864886f70d0109011620736572766963652e696e666f40656d652d656e736569676e656d656e742e667282090083382b812e0c60d7302b0603551d120424302281 EAP-Message = 0x20736572766963652e696e666f40656d652d656e736569676e656d656e742e667230190603551d1104123010810e63616c65636140656d652e6f7267300b0603551d0f0404030205a030130603551d25040c300a06082b06010505070302300d06092a864886f70d010105050003820201006ba84b0aa33cf563f4581aa849ce83c46cd8dfdcb87c3c57487b26d46dad9683e29e03edcbe5633e2b2b263b9a9f30c18678317a8e6f2db9d6e3961b74af15f45f93b1f8ffbf76f0d598b433c7a025e15777e19053d22fd62934dc5ae268c6d7f839a59f0e6922ff861fce27683d89 NAS-IP-Address = 192.168.1.254 NAS-Port = 1 NAS-Port-Id = "STA port # 1" +- entering group authorize ++[preprocess] returns ok expand: %{User-Name} -> user1 rlm_sql (sql): sql_set_user escaped user --> 'user1' rlm_sql (sql): Reserving sql socket id: 1 expand: SELECT id, username, attribute, value, op FROM radcheck WHERE username = '%{SQL-User-Name}' ORDER BY id -> SELECT id, username, attribute, value, op FROM radcheck WHERE username = 'user1' ORDER BY id expand: SELECT groupname FROM radusergroup WHERE username = '%{SQL-User-Name}' ORDER BY priority -> SELECT groupname FROM radusergroup WHERE username = 'user1' ORDER BY priority expand: SELECT id, groupname, attribute, Value, op FROM radgroupcheck WHERE groupname = '%{Sql-Group}' ORDER BY id -> SELECT id, groupname, attribute, Value, op FROM radgroupcheck WHERE groupname = 'wifiUsers' ORDER BY id rlm_sql (sql): User found in group wifiUsers expand: SELECT id, groupname, attribute, value, op FROM radgroupreply WHERE groupname = '%{Sql-Group}' ORDER BY id -> SELECT id, groupname, attribute, value, op FROM radgroupreply WHERE groupname = 'wifiUsers' ORDER BY id rlm_sql (sql): Released sql socket id: 1 ++[sql] returns ok rad_check_password: Found Auth-Type EAP auth: type "EAP" +- entering group authenticate rlm_eap: Request found, released from the list rlm_eap: EAP/tls rlm_eap: processing type tls rlm_eap_tls: Authenticate rlm_eap_tls: processing TLS ....Passons sur la suite, notre utilisateur
user1
va maintenant disposer de l'authentification de type EAP
et le reste va se passer convenablement pour lui.
Cette méthode finalement fort simple nous permet en agissant sur le contenu de la table usergroup
d'autoriser ou non un utilisateur présentant un certificat valide sur la bonne foi du nom (CN) présenté par le client, CN qui se trouve dans le certificat. Il nous est désormais possible d'interdire l'accès à un utilisateur disposant d'un certificat en cours de validité, sans avoir besoin de passer par un certificat de révocations.
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 largement préférable, ne serait-ce qu'à cause des fuites (toujours possibles) de login/passwords.