Authentification LAN 802.1X avec FreeRADIUS, OpenLDAP et MFA Duo Security
Important
|
Article en cours de rédaction Je reprends tout un tas d’articles et de LABs en projets et mis en standby. Principalement des LABs autour de l’authentification, Radius, etc… |
Authentification LAN 802.1X avec FreeRADIUS, OpenLDAP et MFA Duo Security
Introduction
Cet article détaille la configuration d’une authentification réseau filaire ou sans-fil robuste basée sur le standard 802.1X. Nous utiliserons FreeRADIUS comme serveur RADIUS, OpenLDAP comme annuaire centralisé pour les utilisateurs et les informations d’identification, et nous ajouterons une couche de sécurité supplémentaire avec l’authentification multifacteur (MFA) fournie par Duo Security.
L’objectif est de permettre aux utilisateurs de se connecter au réseau en utilisant leurs identifiants LDAP habituels, avec une validation supplémentaire via l’application Duo Mobile (Push, code) ou d’autres méthodes supportées par Duo.
Nous aborderons la configuration de FreeRADIUS pour interroger OpenLDAP, puis l’intégration de Duo Security via son Authentication Proxy, que nous déploierons à l’aide de Docker pour plus de flexibilité.
Architecture Cible :
- Client 802.1X (PC, portable) tente de se connecter au réseau.
- Commutateur/Point d’accès (NAS - Network Access Server) intercepte la demande et la relaie au serveur RADIUS (ici, le Duo Authentication Proxy).
- Duo Authentication Proxy reçoit la requête RADIUS.
- Il effectue l’authentification primaire en relayant la demande à FreeRADIUS.
- FreeRADIUS reçoit la demande du Duo Proxy.
- Il interroge OpenLDAP pour valider l’identité et les informations d’autorisation de l’utilisateur (via le module
rlm_ldap
). - FreeRADIUS répond au Duo Proxy (succès/échec de l’authentification primaire).
- Il interroge OpenLDAP pour valider l’identité et les informations d’autorisation de l’utilisateur (via le module
- Duo Authentication Proxy (si l’authentification primaire réussit) :
- Il contacte l’API Duo Security Cloud pour lancer l’authentification secondaire (MFA).
- Il gère l’interaction MFA avec l’utilisateur (Push, code, etc.).
- Il renvoie la réponse finale (Access-Accept / Access-Reject) au Commutateur/Point d’accès.
- Commutateur/Point d’accès autorise ou refuse l’accès au réseau au client.
Prérequis
- Un serveur OpenLDAP fonctionnel avec des utilisateurs définis.
- Un serveur avec FreeRADIUS (version 3.x recommandée) installé.
- Un compte Duo Security (avec une intégration de type “RADIUS Application” configurée pour obtenir une Integration key, Secret key, et API hostname).
- Docker et Docker Compose installés sur la machine hébergeant le Duo Authentication Proxy (peut être la même que FreeRADIUS ou une machine distincte).
- Des certificats TLS valides pour sécuriser les communications EAP (PEAP, EAP-TTLS) et la connexion LDAP.
Partie 1 : Configuration de FreeRADIUS et OpenLDAP
Cette section reprend les étapes classiques d’intégration FreeRADIUS/OpenLDAP. Assurez-vous que ces étapes sont fonctionnelles avant d’ajouter Duo.
Note
|
Les chemins peuvent varier légèrement selon votre distribution Linux. Cet exemple utilise les chemins standards de Debian/Ubuntu pour FreeRADIUS 3.x) |
-
Configurer le module LDAP (
rlm_ldap
)Modifiez le fichier
/etc/freeradius/3.0/mods-available/ldap
:Fichier ini
ldap { server = 'ldap.votre-domaine.lan' # Ou adresse IP # identity = 'cn=admin,dc=votre-domaine,dc=lan' # DN de connexion si nécessaire # password = 'votre_mot_de_passe_admin_ldap' # Mot de passe si nécessaire basedn = 'ou=people,dc=votre-domaine,dc=lan' # Base de recherche des utilisateurs filter = '(uid=%{%{Stripped-User-Name}:-%{User-Name}})' # Filtre pour trouver l'utilisateur # TLS Configuration - FORTEMENT RECOMMANDÉ tls { start_tls = yes # Utilisez 'yes' pour StartTLS (port 389), 'no' pour LDAPS (port 636) si ldap { ... server = "ldaps://..." } ca_file = /etc/freeradius/3.0/certs/ca.pem # Chemin vers le certificat de l'autorité de certification # certificate_file = /etc/freeradius/3.0/certs/client.pem # Certificat client si requis par LDAP # private_key_file = /etc/freeradius/3.0/certs/client.key # Clé privée client # require_cert = "demand" # Vérifie le certificat du serveur LDAP } # Attributs RADIUS à récupérer depuis LDAP si nécessaire # dictionary_mapping = ${confdir}/ldap.attrmap # Attribut contenant le mot de passe (souvent userPassword) password_attribute = userPassword }
sudo ln -s /etc/freeradius/3.0/mods-available/ldap /etc/freeradius/3.0/mods-enabled/
-
Configurer les Clients RADIUS (NAS) Modifiez
/etc/freeradius/3.0/clients.conf
pour déclarer vos commutateurs ou points d’accès :Fichier ini
client mon_switch { ipaddr = 192.168.1.10 # IP du switch secret = mon_secret_radius # Secret partagé nas_type = other } client mon_ap { ipaddr = 192.168.1.11 # IP du point d'accès secret = un_autre_secret # Secret partagé nas_type = other }
-
Configurer l’authentification EAP Modifiez
/etc/freeradius/3.0/mods-available/eap
:- Assurez-vous que
default_eap_type
est défini sur un type sécurisé commepeap
outtls
. - Configurez les sections
peap
et/outtls
. - Spécifiez les chemins vers vos certificats serveur (clé privée, certificat, CA) dans la section
tls-config tls-common
. Ces certificats sont présentés aux clients lors de la négociation EAP.Fichier ini
eap { default_eap_type = peap timer_expire = 60 ignore_unknown_eap_types = no cisco_accounting_username_bug = no # Types EAP supportés peap { # Utiliser la config TLS par défaut tls_config = tls-common # Phase 2 d'authentification (souvent MSCHAPv2) default_eap_type = mschapv2 virtual_server = "inner-tunnel" # Référence au serveur virtuel pour la phase 2 } ttls { tls_config = tls-common default_eap_type = mschapv2 # Ou PAP pour TTLS/PAP virtual_server = "inner-tunnel" } # Configuration TLS commune tls-config tls-common { private_key_file = ${certdir}/server.key # Votre clé privée serveur certificate_file = ${certdir}/server.pem # Votre certificat serveur ca_file = ${cadir}/ca.pem # L'autorité de certification # dh_file = ${certdir}/dh # Paramètres Diffie-Hellman check_crl = yes # Vérifier les listes de révocation # ... autres options TLS ... } # ... autres configurations EAP ... }
- Assurez-vous que
-
Modifier les Sites Virtuels (
default
etinner-tunnel
)Modifiez
/etc/freeradius/3.0/sites-available/default
et/etc/freeradius/3.0/sites-available/inner-tunnel
.- Dans
default
, sectionauthorize
, décommentez ou ajoutezldap
pour récupérer les infos utilisateur eteap
pour gérer l’EAP. - Dans
default
, sectionauthenticate
, configurezAuth-Type EAP { eap }
. - Dans
inner-tunnel
, sectionauthorize
, décommentez ou ajoutezldap
. - Dans
inner-tunnel
, sectionauthenticate
, décommentezAuth-Type LDAP { ldap }
.
Exemple simplifié (
sites-available/default
):Fichier ini
server default { # ... authorize { # ... filter_username preprocess # Charger les infos depuis LDAP ldap # Initialiser EAP eap { ok = return updated = return } # ... autres modules ... # expiration # logintime # pap # Si vous supportez PAP directement (non-EAP) } authenticate { # Gérer l'authentification EAP Auth-Type EAP { eap } # Gérer l'authentification PAP (si supporté) # Auth-Type PAP { # pap # Ou ldap si PAP est validé directement contre LDAP # } # ... autres types d'authentification ... } # ... sections preacct, accounting, session, post-auth ... }
sites-available/inner-tunnel
):Fichier ini
server inner-tunnel { # ... authorize { # ... # Nécessaire pour récupérer les détails utilisateur dans le tunnel ldap # Authentification interne (ex: MSCHAPv2) mschap # ... } authenticate { # Valider les identifiants via LDAP Auth-Type LDAP { ldap } # Gérer l'authentification interne (MS-CHAP, PAP dans TTLS, etc.) # Auth-Type MS-CHAP { # mschap # } # Auth-Type PAP { # pap # Valide le mot de passe via le module PAP (souvent après LDAP) # } # ... } # ... }
Activez les sites (si ce n’est pas déjà fait) :
sudo ln -s /etc/freeradius/3.0/sites-available/default /etc/freeradius/3.0/sites-enabled/ sudo ln -s /etc/freeradius/3.0/sites-available/inner-tunnel /etc/freeradius/3.0/sites-enabled/
- Dans
-
Redémarrer FreeRADIUS et Tester
sudo systemctl restart freeradius.service # Tester en mode debug pour voir les logs détaillés sudo freeradius -X
Utilisez
radtest
oueapol_test
pour vérifier que l’authentification EAP contre LDAP fonctionne.
Partie 2 : Intégration de Duo Security avec Docker
Nous allons utiliser le Duo Authentication Proxy comme serveur RADIUS principal auquel les NAS se connecteront. Ce proxy gérera l’interaction avec Duo Cloud et relaiera l’authentification primaire à notre serveur FreeRADIUS/LDAP configuré ci-dessus.
-
Préparer la Configuration du Duo Auth Proxy
Créez un répertoire pour la configuration et les logs du proxy, par exemple
/opt/duoauthproxy/
. Créez un fichierauthproxy.cfg
dans/opt/duoauthproxy/conf/
.Fichier ini
# /opt/duoauthproxy/conf/authproxy.cfg [main] # Clés fournies par l'application RADIUS dans votre console Duo Admin ikey = VOTRE_IKEY_DUO skey = VOTRE_SKEY_DUO api_host = VOTRE_API_HOST_DUO # Permet les appels même si le certificat Duo n'est pas vérifiable (NON RECOMMANDÉ en production) # http_proxy=your_proxy.example.com:8080 # Si vous utilisez un proxy HTTP sortant failmode = safe # 'safe': Accès autorisé si Duo indisponible, 'secure': Accès refusé # Section pour le serveur RADIUS primaire (votre FreeRADIUS/LDAP) [radius_server_auto] ikey = RKEY_POUR_FREERADIUS # Une clé unique pour cette section (inventez-la) skey = SECRET_PARTAGE_FREERADIUS # Doit correspondre au secret défini dans FreeRADIUS pour le proxy Duo api_host = api-XXXXXXXX.duosecurity.com # Votre API Host Duo (peut être différent de celui de [main]) radius_ip_1 = ADRESSE_IP_FREERADIUS # IP de votre serveur FreeRADIUS radius_secret_1 = SECRET_PARTAGE_FREERADIUS # Secret que FreeRADIUS attend du proxy Duo port = 1812 # Port standard RADIUS Auth # Section définissant comment le proxy écoute les requêtes RADIUS des NAS [radius_client] # Cette section utilise les configurations de [main] et [radius_server_auto] # Assurez-vous que le port n'est pas déjà utilisé (ex: si FreeRADIUS tourne sur le même hôte) # Si FreeRADIUS et Duo Proxy sont sur le même hôte, changez le port d'écoute de l'un des deux. # Ici, on suppose que Duo Proxy écoute sur 1812 et FreeRADIUS sur un autre port ou IP. port = 1812 # Interface d'écoute (optionnel, 0.0.0.0 par défaut) # interface = 0.0.0.0 failmode = safe # Ou secure # Vous pouvez ajouter des sections [ad_client] ou [ldap_client] si vous voulez que # le proxy contacte directement AD/LDAP pour la phase 1, mais ici on utilise [radius_server_auto] # pour pointer vers notre FreeRADIUS existant.
-
Configurer FreeRADIUS pour accepter le Duo Auth Proxy comme Client
Ajoutez une entrée pour le Duo Auth Proxy dans
/etc/freeradius/3.0/clients.conf
sur votre serveur FreeRADIUS :client duo_proxy { ipaddr = ADRESSE_IP_DUO_PROXY # IP de la machine/conteneur Docker hébergeant le proxy secret = SECRET_PARTAGE_FREERADIUS # Le même secret que dans authproxy.cfg [radius_server_auto] nas_type = other }
Rechargez FreeRADIUS :
sudo systemctl reload freeradius.service
-
Créer le Dockerfile pour Duo Authentication Proxy
Créez un fichier nommé
Dockerfile
dans le répertoire/opt/duoauthproxy/
:Fichier Dockerfile
# Utiliser une image Python légère comme base FROM python:3.9-slim LABEL maintainer="Votre Nom <votre.email@example.com>" LABEL description="Duo Security Authentication Proxy" ARG DUO_PROXY_VERSION=latest # Vous pouvez fixer une version spécifique, ex: 5.2.0 # ARG DUO_PROXY_VERSION=5.2.0 # Variables d'environnement pour le chemin d'installation ENV DUO_PROXY_DIR /opt/duoauthproxy # Dépendances système nécessaires pour la compilation et l'exécution RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential \ libffi-dev \ libssl-dev \ python3-dev \ # Potentiellement d'autres dépendances si vous utilisez des modules spécifiques (ex: ldaps) # libsasl2-dev \ # libldap2-dev \ && rm -rf /var/lib/apt/lists/* # Créer le répertoire d'installation et de configuration/logs dans l'image RUN mkdir -p ${DUO_PROXY_DIR}/conf ${DUO_PROXY_DIR}/log # Installer le Duo Authentication Proxy via pip # Utiliser l'argument pour spécifier la version RUN pip install --no-cache-dir duoauthproxy==${DUO_PROXY_VERSION} \ || pip install --no-cache-dir duoauthproxy # Fallback si la version n'est pas spécifiée ou 'latest' # Copier le fichier de configuration local dans l'image COPY conf/authproxy.cfg ${DUO_PROXY_DIR}/conf/authproxy.cfg # Créer un utilisateur non-privilégié pour exécuter le proxy RUN useradd --system --home ${DUO_PROXY_DIR} --shell /usr/sbin/nologin duo_proxy # Ajuster les permissions RUN chown -R duo_proxy:duo_proxy ${DUO_PROXY_DIR} \ && chmod 600 ${DUO_PROXY_DIR}/conf/authproxy.cfg # Sécuriser le fichier de config # Définir l'utilisateur USER duo_proxy # Définir le répertoire de travail WORKDIR ${DUO_PROXY_DIR} # Exposer le port RADIUS (si vous utilisez [radius_client]) # Note: Ce port doit être mappé lors du `docker run` ou dans docker-compose.yml EXPOSE 1812/udp # Commande par défaut pour lancer le proxy CMD ["/usr/local/bin/authproxy", "--config", "/opt/duoauthproxy/conf/authproxy.cfg"] # Alternative pour lancer en mode foreground avec logs sur stdout/stderr (préférable pour Docker) # CMD ["/usr/local/bin/authproxy_run"]
-
Créer un fichier
docker-compose.yml
(Optionnel mais recommandé)Créez un fichier
docker-compose.yml
dans/opt/duoauthproxy/
:Fichier docker-compose
version: '3.7' services: duoauthproxy: build: context: . # dockerfile: Dockerfile # Par défaut, cherche Dockerfile dans le contexte args: # Spécifiez la version si vous le souhaitez # DUO_PROXY_VERSION: 5.2.0 DUO_PROXY_VERSION: latest container_name: duo_auth_proxy hostname: duo-proxy volumes: # Monter le fichier de configuration pour le modifier sans reconstruire - ./conf/authproxy.cfg:/opt/duoauthproxy/conf/authproxy.cfg:ro # Read-only recommandé # Monter le répertoire de logs pour persistance - ./log:/opt/duoauthproxy/log ports: # Mapper le port RADIUS de l'hôte vers le conteneur - "1812:1812/udp" # Mapper d'autres ports si nécessaire (ex: LDAPS 636 si le proxy contacte LDAP directement) restart: unless-stopped # Optionnel: Définir un réseau spécifique si nécessaire # networks: # - proxy_network # networks: # proxy_network: # driver: bridge ```
-
Construire et Lancer le Conteneur
Depuis le répertoire
/opt/duoauthproxy/
:# Construire l'image (si vous utilisez docker-compose) sudo docker-compose build # Lancer le conteneur en arrière-plan sudo docker-compose up -d # Afficher les logs sudo docker-compose logs -f
Partie 3 : Mettre à jour la Configuration des NAS
Vous devez maintenant reconfigurer vos commutateurs et points d’accès (NAS) pour qu’ils envoient les requêtes RADIUS à l’adresse IP du serveur Docker hébergeant le Duo Authentication Proxy, et utilisent le secret partagé défini dans la section [radius_client]
implicite de authproxy.cfg
(qui est souvent dérivé de [radius_server_auto]
ou configuré spécifiquement si vous ajoutez une section secret
à [radius_client]
).
- Serveur RADIUS : IP de l’hôte Docker.
- Port RADIUS : 1812 (ou celui que vous avez mappé).
- Secret Partagé : Le secret que le NAS utilisera pour parler au Duo Proxy. Important : Par défaut,
[radius_client]
ne définit pas son propre secret et le comportement peut varier. Il est plus sûr de définir explicitement le secret attendu des NAS, soit en ajoutantsecret = VOTRE_SECRET_NAS
à[radius_client]
, soit en faisant correspondre le secret du NAS auradius_secret_1
de[radius_server_auto]
. Consultez la documentation Duo pour le comportement exact. Pour plus de clarté, il est souvent préférable d’avoir un secret entre NAS et Proxy, et un autre entre Proxy et FreeRADIUS.
Partie 4 : Test Final
- Vérifiez les Logs : Surveillez les logs de FreeRADIUS (
/var/log/freeradius/radius.log
oufreeradius -X
) et les logs du conteneur Duo Proxy (docker-compose logs -f
). - Test Client : Essayez de vous connecter au réseau (Wi-Fi ou filaire) avec un client configuré pour 802.1X (PEAP ou TTLS).
- Flux Attendu :
- Le client initie la connexion EAP.
- Le NAS relaie à Duo Proxy (IP Hôte Docker:1812).
- Duo Proxy relaie à FreeRADIUS (IP FreeRADIUS:1812 - ou le port où FreeRADIUS écoute réellement).
- FreeRADIUS valide via LDAP.
- FreeRADIUS répond au Duo Proxy.
- Duo Proxy contacte Duo Cloud -> Envoi d’une notification Push (ou attente de code).
- Utilisateur approuve/saisit le code.
- Duo Proxy reçoit la confirmation de Duo Cloud.
- Duo Proxy envoie Access-Accept au NAS.
- Le NAS autorise l’accès au client.
Conclusion
Vous disposez maintenant d’une solution d’authentification réseau 802.1X renforcée, utilisant votre annuaire OpenLDAP existant et la sécurité additionnelle de l’authentification multifacteur Duo. Le déploiement du Duo Authentication Proxy via Docker simplifie la gestion et l’isolement de ce composant critique. N’oubliez pas de maintenir à jour FreeRADIUS, le Duo Proxy et les dépendances système pour garantir la sécurité et la stabilité de votre infrastructure.