Utiliser NGINX Plus et NGINX pour authentifier les utilisateurs d’applications avec LDAP

NGINX | 22 juin 2015

Nos clients nous demandent souvent comment utiliser NGINX Plus et NGINX pour sécuriser des ressources ou des applications protégées en authentifiant les utilisateurs qui souhaitent y accéder. Aujourd’hui, nous annonçons la mise à disposition d’une implémentation de référence d’un tel système d’authentification dans le dépôt de NGINX, Inc. sur GitHub. Dans cet article, nous expliquons le fonctionnement de cette implémentation, son installation et la manière de l’utiliser comme modèle pour votre propre système d’authentification.

La solution tire parti du module ngx_http_auth_request_module de NGINX Plus et NGINX, qui transmet les requêtes d’authentification à un service externe. Dans l’implémentation de référence, ce service est un démon que nous appelons ldap‑auth. Écrit en Python, il communique avec un serveur d’authentification utilisant le protocole LDAP (Lightweight Directory Access Protocol), à savoir OpenLDAP par défaut. Nous avons également testé le démon ldap‑auth avec les configurations par défaut de Microsoft® Windows® Server Active Directory (versions 2003 et 2012).

Le démon ldap‑auth sert de modèle pour votre propre application de « connexion », que vous pouvez écrire dans d’autres langages, déployer avec différents systèmes d’authentification, ou les deux. L’équipe Services professionnels de NGINX peut vous aider à réaliser de telles adaptations.

Remarques :

  • L’implémentation de référence n’est pas destinée à être utilisée en production, mais uniquement à servir de modèle pour vos propres implémentations.
  • Pour faciliter la lecture, la suite de cet article fait référence à NGINX Plus, mais l’implémentation de référence fonctionne également avec NGINX Open Source. Le module http_auth_request requis est inclus à la fois dans les packages NGINX Plus et dans les binaires NGINX précompilés.

Fonctionnement de l’authentification dans l’implémentation de référence

Pour procéder à l’authentification, le module http_auth_request envoie une sous-requête HTTP au démon ldap‑auth, qui joue le rôle d’intermédiaire et interprète la sous-requête pour le serveur LDAP. Il utilise HTTP pour communiquer avec NGINX Plus et l’API appropriée pour communiquer avec le serveur LDAP.

Nous partons du principe que, si l’implémentation de référence vous intéresse, vous disposez déjà d’une application ou d’autres ressources que vous souhaitez protéger en exigeant une authentification. Toutefois, afin de faciliter le test de l’implémentation de référence, nous fournissons un exemple de démon backend, également écrit en Python, qui écoute sur le port 9000. Lors des tests, il peut remplacer une véritable application HTTP en demandant les identifiants de l’utilisateur et en créant un cookie à partir de ceux-ci.

L’implémentation de référence de NGINX Plus pour l’authentification LDAP comprend le démon ldap-auth et un exemple de démon backend

Voici une description détaillée, étape par étape, du processus d’authentification dans l’implémentation de référence. Les paramètres du fichier de configuration nginx-ldap-auth.conf en déterminent les détails ; consultez la section « Configuration de l’implémentation de référence » ci-dessous. L’organigramme situé sous les étapes résume le processus.

  1. Un client envoie une requête HTTP pour accéder à une ressource protégée hébergée sur un serveur pour lequel NGINX Plus fait office de proxy inverse.
  2. NGINX Plus (plus précisément, le module http_auth_request) transmet la requête au démon ldap‑auth, qui répond avec le code HTTP 401 car aucun identifiant n’a été fourni.
  3. NGINX Plus transmet la requête à http://backend/login, qui correspond au démon backend. Il inscrit l’URI de la requête d’origine dans l’en-tête X-Target de la requête transmise.
  4. Le démon backend envoie au client un formulaire de connexion (ce formulaire est défini dans le code Python du démon). Conformément à la configuration de la directive error_page, NGINX définit le code HTTP du formulaire de connexion sur 200.
  5. L’utilisateur renseigne les champs Nom d’utilisateur et Mot de passe du formulaire, puis clique sur le bouton Connexion. Conformément au code du formulaire, le client génère une requête HTTP POST à destination de /login, que NGINX Plus transmet au démon backend.
  6. Le démon backend construit une chaîne au format « username:password », l’encode en Base64, génère un cookie nommé « nginxauth » dont la valeur correspond à la chaîne encodée, puis envoie le cookie au client. Il définit l’attribut « httponly » afin d’empêcher JavaScript de lire ou de manipuler le cookie (ce qui protège contre la vulnérabilité de type cross-site scripting [XSS]).
  7. Le client renvoie sa requête initiale (de l’étape 1), en incluant cette fois le cookie dans le champ Cookie de l’en-tête HTTP. NGINX Plus transmet la requête au démon ldap‑auth (comme à l’étape 2).
  8. Le démon ldap‑auth décode le cookie et envoie le nom d’utilisateur et le mot de passe au serveur LDAP dans une requête d’authentification.
  9. L’action suivante dépend de la réussite ou non de l’authentification de l’utilisateur par le serveur LDAP :
    • Si l’authentification réussit, le démon ldap‑auth envoie le code HTTP « 200 » à NGINX Plus. NGINX Plus demande la ressource au démon backend. Dans l’implémentation de référence, le démon backend renvoie le texte suivant :
   Hello, world! Requested URL: URL
  • Le fichier nginx-ldap-auth.conf contient des directives permettant de mettre en cache les résultats de la tentative d’authentification. Pour désactiver la mise en cache, consultez la section « Mise en cache » ci-dessous.
  • Si l’authentification échoue, le démon ldap‑auth envoie le code HTTP 401 à NGINX Plus. NGINX Plus transmet à nouveau la requête au démon backend (comme à l’étape 3), et le processus se répète.

Dans l’implémentation de référence de NGINX Plus pour l’authentification LDAP, le démon ldap-auth sert d’intermédiaire entre NGINX Plus et le serveur LDAP

Installation des composants

Le fichier de configuration NGINX Plus fourni avec l’implémentation de référence, nginx-ldap-auth.conf, configure tous les composants autres que le serveur LDAP (c’est-à-dire NGINX Plus, le client, le démon ldap‑auth et le démon backend) pour qu’ils s’exécutent sur le même hôte, ce qui convient aux tests. Le serveur LDAP peut également s’exécuter sur cet hôte pendant les tests.

Dans un déploiement réel, l’application backend et le serveur d’authentification s’exécutent généralement chacun sur un hôte distinct, tandis que NGINX Plus s’exécute sur un troisième hôte. Dans la plupart des cas, le démon ldap-auth consomme peu de ressources. Il peut donc s’exécuter sur l’hôte NGINX Plus ou sur un autre hôte de votre choix.

  1. Clonez le dépôt GitHub.
  2. Si NGINX Plus n’est pas déjà en cours d’exécution, installez-le en suivant les instructions correspondant à votre système d’exploitation.
  3. Si aucun serveur LDAP n’est déjà en cours d’exécution, installez-en et configurez-en un. Par défaut, le démon ldap‑auth communique avec OpenLDAP, mais Microsoft Windows Active Directory 2003 et 2012 sont également pris en charge. Si vous utilisez le serveur LDAP uniquement pour tester l’implémentation de référence, vous pouvez utiliser l’image Docker du serveur OpenLDAP disponible sur GitHub, ou configurer un serveur en suivant des instructions telles que Comment installer et configurer OpenLDAP et phpLDAPadmin sur Ubuntu 16.04. Notez les valeurs que vous définissez pour le DN de base, le DN de liaison et le mot de passe de liaison. Vous les ajouterez au fichier de configuration NGINX dans la section Configuration de l’implémentation de référence.
  4. Sur l’hôte où le démon ldap‑auth doit s’exécuter, installez les logiciels supplémentaires suivants. Nous vous recommandons d’utiliser les versions fournies avec le système d’exploitation plutôt que de télécharger les logiciels depuis un dépôt open source.
    • Python version 2. La version 3 n’est pas prise en charge.
    • Le module LDAP pour Python, « python‑ldap » (créé par le projet open source python-ldap.org).
  5. Copiez les fichiers suivants depuis votre clone du dépôt vers les hôtes indiqués :
    • nginx-ldap-auth.conf – Fichier de configuration NGINX Plus qui comprend l’ensemble minimal de directives permettant de tester l’implémentation de référence. Installez-le sur l’hôte NGINX Plus (dans le répertoire /etc/nginx/conf.d si vous utilisez le schéma de configuration conventionnel). Pour éviter les conflits de configuration, pensez à déplacer ou à renommer tous les fichiers de configuration par défaut installés avec NGINX Plus.
    • nginx-ldap-auth-daemon.py – Code Python du démon ldap‑auth. Installez-le sur l’hôte de votre choix.
    • nginx-ldap-auth-daemon-ctl.sh – Exemple de script shell permettant de démarrer et d’arrêter le démon. Installez-le sur le même hôte que le démon ldap‑auth.
    • backend-sample-app.py – Code Python du démon qui, lors des tests, fait office de serveur d’application backend. Installez-le sur l’hôte de votre choix.
  6. Modifiez le fichier de configuration de NGINX Plus comme décrit dans la section « Configuration de l’implémentation de référence » ci-dessous. Après avoir effectué vos modifications, exécutez la commande nginx -t pour vérifier que la syntaxe du fichier est valide.
root# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
  1. Démarrez NGINX Plus. Si NGINX Plus est déjà en cours d’exécution, exécutez la commande suivante pour recharger le fichier de configuration :
root# nginx -s reload
  1. Exécutez les commandes suivantes sur les hôtes appropriés pour démarrer le démon ldap‑auth et le démon backend.
root# nginx-ldap-auth-daemon-ctl.sh start
root# python backend-sample-app.py
  1. Utilisez un navigateur web pour accéder à http://nginx-server-address:8081. Vérifiez que le navigateur affiche le formulaire d’authentification. Après avoir rempli et envoyé le formulaire, vérifiez que le serveur renvoie la réponse attendue lorsque les identifiants sont valides. Comme indiqué précédemment, le démon backend renvoie le texte suivant :
   Hello, world! Requested URL: URL

Configuration de l’implémentation de référence

Apportez les modifications suivantes dans le fichier nginx-ldap-auth.conf. Certaines sont obligatoires et d’autres facultatives, comme indiqué.

Paramètres du serveur LDAP

Comme implémenté dans nginx-ldap-auth-daemon.py, le démon ldap‑auth communique avec un serveur OpenLDAP en lui transmettant des paramètres qui indiquent le compte utilisateur à authentifier. Afin d’éviter d’avoir à modifier le code Python, le fichier nginx-ldap-auth.conf contient des directives proxy_set_header qui définissent des valeurs dans l’en-tête HTTP, lesquelles sont ensuite utilisées pour définir les paramètres. Le tableau suivant présente la correspondance entre les paramètres et les en-têtes.

Paramètre LDAP En-tête HTTPbasedn X-Ldap-BaseDNbinddn X-Ldap-BindDNbindpasswd X-Ldap-BindPasscookiename X-CookieNamerealm X-Ldap-Realmtemplate X-Ldap-Templateurl X-Ldap-URL

  • (Obligatoire) Dans les directives suivantes, remplacez les valeurs en gras par les valeurs correspondant au déploiement de votre serveur LDAP. Notez en particulier que le fichier nginx-ldap-auth.conf utilise le port standard de LDAPS, 636. Si vous remplacez ce port par le port 389 (le port standard de LDAP) ou par un autre port LDAP, pensez également à remplacer le nom du protocole ldaps par ldap.
# URL and port for connecting to the LDAP server
proxy_set_header X-Ldap-URL "ldaps://example.com:636";
 
# Base DN
proxy_set_header X-Ldap-BaseDN "cn=Users,dc=test,dc=local";
 
# Bind DN
proxy_set_header X-Ldap-BindDN "cn=root,dc=test,dc=local";
 
# Bind password
proxy_set_header X-Ldap-BindPass "secret";
  • (Obligatoire si vous utilisez Active Directory au lieu d’OpenLDAP) Décommentez la directive suivante comme indiqué :
proxy_set_header X-Ldap-Template "(SAMAccountName=%(username)s)";
  • (Facultatif) L’implémentation de référence utilise une authentification basée sur les cookies. Si vous utilisez plutôt l’authentification HTTP Basic, mettez en commentaire les directives suivantes comme indiqué :
#proxy_set_header X-CookieName "nginxauth";
#proxy_set_header Cookie nginxauth=$cookie_nginxauth;
  • (Facultatif) Si vous souhaitez modifier la valeur du paramètre « template » que le démon ldap-auth transmet par défaut au serveur OpenLDAP, supprimez la mise en commentaire de la directive suivante comme indiqué, puis modifiez sa valeur :
proxy_set_header X-Ldap-Template "(cn=%(username)s)";
  • (Facultatif) Si vous souhaitez remplacer le nom du domaine d’authentification par sa valeur par défaut (Restricted), décommentez et modifiez la directive suivante :
proxy_set_header X-Ldap-Realm "Restricted";

Adresse IP du démon backend

Si le démon backend ne s’exécute pas sur le même hôte que NGINX Plus, modifiez son adresse IP dans le bloc de configuration upstream :

upstream backend {    server 127.0.0.1:9000;
 }

Adresse IP du démon ldap‑auth

Si le démon ldap‑auth ne s’exécute pas sur le même hôte que NGINX Plus, modifiez l’adresse IP dans cette directive « proxy_pass » :

location = /auth-proxy {    proxy_pass http://127.0.0.1:8888;
    # ...
}

Adresse IP et port sur lesquels NGINX écoute

Si le client ne s’exécute pas sur le même hôte que NGINX Plus, modifiez l’adresse IP dans cette directive listen (ou supprimez complètement l’adresse pour accepter le trafic provenant de n’importe quel client). Vous pouvez également remplacer le port 8081 sur lequel NGINX écoute par un autre port si vous le souhaitez :

server {    listen 127.0.0.1:8081;
    # ...
 }

Mise en cache

Le fichier nginx-ldap-auth.conf permet de mettre en cache les données et les identifiants. Vous pouvez éventuellement modifier les paramètres suivants :

  • La directive « proxy_cache_path » du bloc de configuration http crée un répertoire nommé « cache » sur le disque local et alloue 10 Mo de mémoire partagée à une zone appelée « auth_cache », dans laquelle les métadonnées sont stockées.
proxy_cache_path cache/ keys_zone=auth_cache:10m;
  • Si vous modifiez le nom de la zone de mémoire partagée, vous devez également le modifier dans la directive « proxy_cache » (dans le bloc « location » qui dirige le trafic vers le démon ldap‑auth).
location = /auth-proxy {
    proxy_cache auth_cache;
    # ...
}
  • La directive proxy_cache_valid (dans le même bloc location que proxy_cache) indique que les réponses mises en cache associées au code HTTP 200 ou 403 sont valides pendant 10 minutes.
location = /auth-proxy {    proxy_cache_valid 200 403 10m;
    # ...
}

Pour désactiver la mise en cache, mettez en commentaire ces trois directives ainsi que la directive « proxy_cache_key ».

Personnalisation du système d’authentification

Comme indiqué précédemment, vous pouvez utiliser le démon ldap‑auth comme modèle pour votre propre application acceptant les requêtes du module http_auth_request. Si vous développez une application en Python pour communiquer avec un autre type de serveur d’authentification (non LDAP), créez une nouvelle classe de gestionnaire d’authentification pour remplacer LDAPAuthHandler dans le script nginx-ldap-auth-daemon.py.

Remarque concernant la sécurité

Le démon backend encode en Base64 le nom d’utilisateur et le mot de passe stockés dans le cookie. Le Base64 est une forme de brouillage très peu sécurisée, qui rend les identifiants vulnérables à l’extraction et à une utilisation abusive. Pour que l’authentification soit réellement utile, vous devez utiliser un chiffrement plus sophistiqué dans votre application backend.


Partager

À propos de l’auteur

Owen Garrett
Owen GarrettDirecteur senior de la gestion des produits

Autres articles de Owen Garrett

Articles de blog associés

Tendances actuelles des technologies cloud natives, de l’ingénierie de plateforme et de l’IA
NGINX | 13/10/2025

Tendances actuelles des technologies cloud natives, de l’ingénierie de plateforme et de l’IA

Découvrez les principaux enseignements tirés des réponses à l’enquête annuelle F5 NGINX sur les dernières tendances en matière de technologies cloud natives, de sécurité, d’ingénierie de plateforme et d’IA.

Quels contrôleurs Ingress NGINX sont affectés par les vulnérabilités CVE-2022-4886, CVE-2023-5043 et CVE-2023-5044 ?
NGINX | 03/11/2023

Quels contrôleurs Ingress NGINX sont affectés par les vulnérabilités CVE-2022-4886, CVE-2023-5043 et CVE-2023-5044 ?

Lorsque de nouvelles CVE sont signalées, il est facile de ne plus savoir si elles concernent un outil de contrôleur Ingress NGINX particulier, car il existe plusieurs projets. Cet article présente les CVE et explique comment distinguer les différents projets de contrôleurs Ingress afin de dissiper toute confusion.

Votre API est-elle en temps réel ? Testez sa latence avec l’outil rtapi de NGINX
NGINX | 11/03/2020

Votre API est-elle en temps réel ? Testez sa latence avec l’outil rtapi de NGINX

Votre API répond-elle aux requêtes en moins de 30 ms ? Si ce n’est pas le cas, il ne s’agit pas d’une API en temps réel offrant la faible latence exigée par la grande majorité des organisations. Mesurez la latence de votre API avec l’outil rtapi de NGINX et découvrez comment NGINX peut l’aider à offrir une réactivité en temps réel.

Un testeur d’expressions régulières pour NGINX et NGINX Plus
NGINX | 11/06/2019

Un testeur d’expressions régulières pour NGINX et NGINX Plus

Le testeur d’expressions régulières (regex) pour NGINX et NGINX Plus vous évite de tâtonner en vous indiquant si une expression régulière utilisée dans un bloc location ou map correspond aux valeurs comme prévu. Il génère la configuration appropriée et affiche les valeurs des groupes de capture.

Caches partagés avec les clusters de cache NGINX Plus, partie 1
NGINX | 24/01/2017

Caches partagés avec les clusters de cache NGINX Plus, partie 1

Optimisez la capacité de votre cache web en le répartissant entre plusieurs serveurs de cache web NGINX ou NGINX Plus. Découvrez comment procéder dans cet article.

Introduction aux microservices
NGINX | 19/05/2015

Introduction aux microservices

Les microservices suscitent actuellement beaucoup d’intérêt. Cet article de blog est le premier d’une série de sept consacrée à la conception, au développement et au déploiement de microservices.