Authentification multifacteur RADIUS pour VPN et Wi-Fi : TOTP 2FA avec le serveur RADIUS Casdoor
Pour placer l'authentification multifacteur devant un VPN avec RADIUS, la passerelle VPN envoie le nom d'utilisateur et le mot de passe au serveur RADIUS via PAP, le serveur vérifie le mot de passe et répond avec un Access-Challenge, le client affiche une invite, et l'utilisateur saisit le code 2FA d'une application d'authentificateur dans une seconde requête. Casdoor fournit un serveur RADIUS qui fait exactement cela pour les utilisateurs ayant configuré TOTP, afin qu'une passerelle capable d'afficher une invite Access-Challenge (FortiGate SSL VPN est celle dont le fournisseur documente cette fonctionnalité) obtienne un mot de passe plus un code 2FA sans logiciel supplémentaire. Le Wi-Fi avec WPA2/WPA3-Enterprise est différent : 802.1X s'exécute sur EAP, qui n'a pas de place pour un code saisi, donc Casdoor dispose d'une option pour ignorer le code pour ces clients.
Si vous souhaitez des informations générales sur RADIUS lui-même et sa comparaison avec LDAP pour les équipements réseau, lisez d'abord RADIUS vs LDAP. Cet article concerne la partie MFA : ce qui circule sur le câble, quels clients peuvent transporter un second facteur, et comment l'activer dans Casdoor.
Quels clients peuvent faire du MFA RADIUS avec Casdoor
Le tableau indique ce que chaque fournisseur documente. "Prise en charge du challenge" signifie que le client affiche l'invite Access-Challenge à l'utilisateur et renvoie la réponse. Lorsque la page du fournisseur que nous avons consultée ne le précise pas, le tableau l'indique au lieu de deviner.
| Client | Méthode d'authentification RADIUS à utiliser avec Casdoor | Prise en charge d'Access-Challenge | Notes |
|---|---|---|---|
| FortiGate SSL VPN | PAP (définissez la méthode sur PAP, ou laissez Default, qui essaie PAP en premier) | Oui, selon Fortinet | Fortinet indique que SSL VPN transmet le challenge au client et attend la réponse |
| FortiGate IPsec VPN (y compris FortiClient) | PAP | Non transmis par défaut | La solution de Fortinet nécessite MS-CHAP sur le serveur RADIUS, que Casdoor ne prend pas en charge ; utilisez SSL VPN ou ignorez MFA |
| Cisco ASA (AnyConnect / Secure Client) | PAP, la valeur par défaut de l'ASA pour tous les types de connexion | Non spécifié dans le guide de configuration RADIUS de l'ASA | N'activez pas password-management sur le tunnel group : cela bascule l'ASA vers MS-CHAPv2 |
| OpenVPN Access Server | PAP (il propose aussi CHAP et MS-CHAPv2) | Non spécifié sur la page des paramètres RADIUS | La comptabilité est un interrupteur distinct, port par défaut 1813 |
| pfSense (serveur d'authentification RADIUS, utilisé par son OpenVPN) | PAP (aussi MD5-CHAP, MS-CHAPv1, MS-CHAPv2) | Non spécifié dans la documentation Netgate | Les exemples OTP de Netgate placent le code dans le champ mot de passe, ce que Casdoor n'accepte pas |
| WireGuard | Aucune | Non applicable | Les pairs s'authentifient uniquement avec des clés publiques, il n'y a donc pas de connexion pour que RADIUS la vérifie |
| Wi-Fi, WPA2/WPA3-Enterprise (802.1X) | EAP (PEAP, EAP-TTLS etc.) | Pas d'invite de code saisi | Casdoor n'implémente pas EAP ; voir la section Wi-Fi |
Lorsqu'une cellule indique "non spécifié", testez avec le vrai client VPN avant le déploiement, et vérifiez que l'invite apparaît et que le code passe.
Pourquoi seul PAP peut transporter le mot de passe vérifié par Casdoor
RADIUS dispose de plusieurs méthodes pour envoyer un mot de passe, et elles déterminent ce que le serveur est capable de vérifier.
Avec PAP, le client place le mot de passe dans l'attribut User-Password, masqué par un hachage MD5 du secret partagé et de l'authenticator de la requête (RFC 2865, section 5.2). Le serveur inverse cette opération avec le même secret, obtient le mot de passe en clair, et peut le vérifier contre un hachage stocké ou une liaison LDAP. Casdoor lit User-Password et effectue la même vérification de mot de passe que sur sa page de connexion.
Avec CHAP, le client n'envoie jamais le mot de passe. Il envoie un hachage du mot de passe et un défi aléatoire. La RFC 2865 indique clairement que CHAP nécessite le mot de passe de l'utilisateur en clair sur le serveur pour recalculer ce hachage. MS-CHAPv2 a la même structure avec un hachage NT. Un fournisseur d'identité qui stocke les mots de passe sous forme de hachages à sens unique (l'organisation intégrée de Casdoor utilise bcrypt) ne peut vérifier ni l'un ni l'autre. Le serveur RADIUS de Casdoor ne lit que User-Password, donc une requête CHAP ou MS-CHAPv2 arrive sans mot de passe et est rejetée.
Comme le masquage PAP repose uniquement sur MD5 avec le secret partagé, utilisez un secret long et aléatoire, maintenez RADIUS sur un réseau privé ou un VPN entre la passerelle et Casdoor, et activez l'attribut Message-Authenticator sur le client. Casdoor vérifie Message-Authenticator lorsqu'une requête le contient et signe sa réponse dans ce cas, ce qui constitue la mitigation contre Blast-RADIUS (CVE-2024-3596). Les détails sont disponibles dans la documentation du serveur RADIUS.
Access-Challenge vs ajout du code au mot de passe
Il existe deux méthodes courantes pour transmettre un code 2FA via RADIUS.
- Access-Challenge. Le serveur vérifie le mot de passe, puis répond avec
Access-Challenge, un attributStateet unReply-Message. Le client affiche le message, l'utilisateur saisit le code, et le client envoie une nouvelleAccess-Requestavec le code dansUser-Passwordet le mêmeState. La section 4.4 de la RFC 2865 précise également ce qui se produit sur un client sans support des défis : il DOIT traiter l'Access-Challengecomme unAccess-Reject. - Code ajouté au mot de passe. L'utilisateur tape
password123456dans le seul champ de mot de passe, et le serveur sépare les six derniers chiffres. Cette méthode fonctionne avec n'importe quel client, c'est pourquoi les produits conçus pour les anciennes passerelles la proposent.
Casdoor implémente uniquement la première méthode. Voici le flux dans son serveur RADIUS (radius/server.go) :
- La première
Access-Requestdoit contenir le mot de passe correct. Un utilisateur ayant activé MFA reçoitAccess-Challenge, unStatealéatoire, et leReply-Messageplease enter OTP. - Le
Stateest valide pendant 120 secondes et ne peut être utilisé qu'une seule fois. Il est lié à l'organisation et au nom d'utilisateur de la première requête. - La deuxième
Access-Requestdoit contenir ceStateet le code TOTP à six chiffres provenant de l'application d'authentification de l'utilisateur dansUser-Password. Casdoor vérifie le code contre le secret TOTP de l'utilisateur et répondAccess-AcceptouAccess-Reject. - Les codes incorrects comptent dans la limite de tentatives échouées de connexion de l'application de l'utilisateur (5 tentatives et un gel de 15 minutes par défaut), séparément des mots de passe incorrects.
Deux conséquences en découlent. Un client qui ne peut faire que « mot de passe plus code dans un seul champ » échouera, car Casdoor vérifie la chaîne entière comme étant le mot de passe. Et seul TOTP fonctionne via RADIUS : les codes SMS et e-mail nécessitent que Casdoor envoie un message après l'étape du mot de passe, ce que le serveur RADIUS ne fait pas. Un utilisateur dont la seule méthode MFA est SMS ou e-mail recevra le défi puis un rejet, donc demandez aux utilisateurs RADIUS de configurer une application d'authentification.
Wi-Fi : 802.1X et WPA-Enterprise
Sur Wi-Fi avec WPA2-Enterprise ou WPA3-Enterprise, le point d'accès ne collecte pas lui-même un mot de passe. Il relaie une conversation EAP entre le dispositif (le supplicant) et le serveur RADIUS, et RADIUS transporte les paquets EAP dans les attributs EAP-Message. Dans cette configuration, Access-Challenge est déjà utilisé : chaque aller-retour de l'échange EAP est une paire Access-Request et Access-Challenge (RFC 3579). La RFC 3579 stipule également qu'un message contenant EAP-Message ne doit pas inclure Reply-Message, donc il n'y a pas de champ pour « please enter OTP » et pas de dialogue sur le téléphone ou l'ordinateur portable pour saisir un code.
Deux points pratiques pour Casdoor :
- Le serveur RADIUS de Casdoor n'implémente pas EAP. Un point d'accès ne peut pas lui parler directement pour WPA-Enterprise. Vous avez besoin d'un serveur EAP devant qui termine le tunnel TLS et transfère une requête PAP simple. FreeRADIUS peut faire cela avec EAP-TTLS et PAP comme méthode interne, proxifiant la requête interne vers un autre serveur RADIUS, et les dispositifs doivent être configurés en TTLS avec PAP à l'intérieur. PEAP avec MS-CHAPv2, le défaut sur de nombreux dispositifs, ne fonctionnera pas avec Casdoor pour la raison mentionnée dans la section PAP.
- Pour ces utilisateurs, activez Skip MFA for RADIUS sur l'organisation. Casdoor accepte alors les utilisateurs ayant MFA après la seule vérification du mot de passe. MFA sur la page de connexion web n'est pas affecté.
Ports, secret partagé et accounting
La RFC 2865 assigne le port UDP 1812 à l'authentification RADIUS, et la RFC 2866 assigne 1813 à l'accounting. Casdoor écoute sur un seul port UDP, radiusServerPort, et gère à la fois Access-Request et Accounting-Request dessus. Donc dirigez l'accounting de la passerelle vers le même port que l'authentification (1812 par défaut), pas vers 1813, sinon les paquets d'accounting n'iront nulle part. Si Casdoor tourne dans un conteneur, publiez le port en UDP, par exemple -p 1812:1812/udp.
Le secret partagé est une valeur unique pour tous les clients, radiusSecret. Chaque passerelle qui communique avec Casdoor l'utilise.
Pour l'accounting, Casdoor enregistre les messages Start, Interim-Update et Stop dans sa base de données (table radius_accounting), avec l'ID de session, la durée de session, l'adresse NAS, l'IP cadrée et les compteurs d'octets et de paquets. Il ne fait cela que pour les organisations où RADIUS est activé.
Configurer Casdoor
1. Définissez les options RADIUS. Dans conf/app.conf, ou comme variables d'environnement portant les mêmes noms :
radiusServerPort = 1812
radiusDefaultOrganization = "my-company"
radiusSecret = "a-long-random-string-shared-with-the-gateway"
radiusDefaultOrganization est l'organisation que Casdoor utilise lorsqu'une requête n'a pas d'attribut Class. Si votre passerelle ne peut pas ajouter d'attribut Class à ses requêtes, ce paramètre décide quelles utilisateurs de quelle organisation se connectent via RADIUS. Toutes les clés sont listées dans la référence de configuration.
2. Activez RADIUS pour l'organisation. Sur la page de modification de l'organisation, activez Enable RADIUS. Il est désactivé par défaut et seuls les administrateurs globaux peuvent le modifier. Tant qu'il est désactivé, Casdoor rejette chaque Access-Request pour cette organisation et ignore sa comptabilisation.
3. Décidez de la MFA pour RADIUS. Laissez Skip MFA for RADIUS désactivé pour les passerelles VPN qui prennent en charge Access-Challenge. Activez-le pour une organisation dont les clients RADIUS ne peuvent pas répondre à un défi (challenge), comme le Wi-Fi WPA-Enterprise.
4. Configurez les utilisateurs avec TOTP. Les utilisateurs configurent une application d'authentification depuis leur page de profil, comme décrit dans l'authentification multi-facteurs. Pour la rendre obligatoire, ajoutez l'élément TOTP avec la règle Required sous les éléments MFA de l'organisation. Notez l'ordre : un utilisateur qui doit encore configurer la MFA requise, ou qui doit changer son mot de passe d'abord, est rejeté via RADIUS tant qu'il n'a pas terminé cela sur la page de connexion Casdoor.
5. Testez depuis la ligne de commande. radclient de FreeRADIUS envoie des requêtes PAP et affiche la réponse :
echo 'User-Name = "alice", User-Password = "her-password"' \
| radclient -x casdoor.example.com:1812 auth a-long-random-string-shared-with-the-gateway
Pour un utilisateur avec TOTP, vous devriez voir Access-Challenge avec un State et le Reply-Message. Renvoyez le code avec ce State dans les 120 secondes :
echo 'User-Name = "alice", User-Password = "123456", State = 0x...' \
| radclient -x casdoor.example.com:1812 auth a-long-random-string-shared-with-the-gateway
Collez la valeur State de la première réponse à la place de 0x.... Un Access-Accept signifie que la configuration est correcte, et la passerelle est la prochaine étape.
Si vous souhaitez également que Casdoor utilise un serveur RADIUS externe comme second facteur pour sa propre connexion web, c'est la direction opposée et cela est couvert par le fournisseur MFA RADIUS.
Références
- RFC 2865: Remote Authentication Dial In User Service (RADIUS)
- RFC 2866: Comptabilité RADIUS
- RFC 3579: Prise en charge EAP par RADIUS
- Fortinet : Différence dans le traitement des défis Access-RADIUS entre SSL VPN et IPsec VPN
- FortiOS 7.6.5 : Configuration d'un serveur RADIUS
- Cisco ASA 9.22 : Serveurs RADIUS pour AAA
- OpenVPN Access Server : Authentification
- pfSense : Serveurs d'authentification RADIUS
- WireGuard
- Serveur virtuel
inner-tunnelde FreeRADIUS - Serveur RADIUS Casdoor