BLOG | NGINX

Utilisation de NGINX Plus et NGINX pour authentifier les utilisateurs d'applications avec LDAP

NGINX-Partie-de-F5-horiz-black-type-RGB
Vignette d'Owen Garrett
Owen Garrett
Publié le 22 juin 2015

Les clients nous demandent fréquemment comment ils peuvent utiliser NGINX Plus et NGINX pour sécuriser les ressources ou les applications protégées en authentifiant les utilisateurs qui les demandent. Aujourd'hui, nous annonçons une implémentation de référence d'un tel système d'authentification et la rendons disponible dans le référentiel NGINX, Inc. sur GitHub . Dans cet article, nous décrivons comment fonctionne l'implémentation, comment l'installer et comment 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 demandes d'authentification à un service externe. Dans l’implémentation de référence, ce service est un démon que nous appelons ldap‑auth . Il est écrit en Python et communique avec un serveur d'authentification LDAP (Lightweight Directory Access Protocol) – OpenLDAP par défaut, mais nous avons également testé le démon ldap-auth par rapport aux 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 « connecteur », que vous pouvez écrire dans d’autres langages, déployer avec différents systèmes d’authentification, ou les deux. L’équipe des services professionnels NGINX est disponible pour vous aider dans de telles adaptations.

Remarques :

  • L'implémentation de référence n'est pas destinée à une utilisation en production, mais uniquement comme modèle pour vos propres implémentations.
  • Pour faciliter la lecture, le reste 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 prérequis http_auth_request est inclus dans les packages NGINX Plus et dans les binaires NGINX prédéfinis .

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

Pour effectuer l'authentification, le module http_auth_request envoie une sous-requête HTTP au démon ldap-auth, qui agit comme intermédiaire et interprète la sous-requête pour le serveur LDAP. Il utilise HTTP pour la communication avec NGINX Plus et l'API appropriée pour la communication avec le serveur LDAP.

Nous partons du principe que si vous êtes intéressé par l’implémentation de référence, vous disposez déjà d’une application ou d’autres ressources que vous souhaitez protéger en exigeant une authentification. Cependant, pour 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. Il peut remplacer une application HTTP réelle lors des tests, en demandant les informations d'identification de l'utilisateur et en créant un cookie basé sur celles-ci.

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

Voici une description étape par étape du processus d’authentification dans l’implémentation de référence. Les détails sont déterminés par les paramètres du fichier de configuration nginx-ldap-auth.conf ; voir Configuration de l'implémentation de référence ci-dessous. Le diagramme sous les étapes résume le processus.

  1. Un client envoie une requête HTTP pour une ressource protégée hébergée sur un serveur pour lequel NGINX Plus agit comme proxy inverse.

  2. NGINX Plus (en particulier le module http_auth_request) transmet la requête au démon ldap-auth, qui répond avec le code HTTP401 car aucune information d'identification n'a été fournie.

  3. NGINX Plus transmet la demande à http://backend/login , qui correspond au démon backend. Il écrit l’URI de la demande d’origine dans l’en-tête X-Target de la demande transmise.

  4. Le démon backend envoie au client un formulaire de connexion (le formulaire est défini dans le code Python du démon). Comme configuré par la directive error_page , NGINX définit le code HTTP sur le formulaire de connexion sur200 .

  5. L'utilisateur remplit les champs Nom d'utilisateur et Mot de passe du formulaire et clique sur le bouton Connexion. Selon le code du formulaire, le client génère une requête HTTP POST dirigée vers /login , que NGINX Plus transmet au démon backend.

  6. Le démon backend construit une chaîne au format nom d'utilisateur : mot de passe , applique l'encodage Base64, génère un cookie appelé nginxauth avec sa valeur définie sur la chaîne encodée et envoie le cookie au client. Il définit l'indicateur httponly pour empêcher l'utilisation de JavaScript pour lire ou manipuler le cookie (protection contre la vulnérabilité de script intersite [XSS] ).

  7. Le client retransmet sa requête d’origine (de l’étape 1), en incluant cette fois le cookie dans le champ Cookie de l’en-tête HTTP. NGINX Plus transmet la demande 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 demande 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 HTTP200 à 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 :

         Bonjour le monde! URL demandée : URL
      

      Le fichier nginx-ldap-auth.conf inclut des directives pour la mise en cache des résultats de la tentative d'authentification ; pour désactiver la mise en cache, voir Mise en cache ci-dessous.

    • Si l’authentification échoue, le démon ldap-auth envoie du code HTTP401 à NGINX Plus. NGINX Plus transmet à nouveau la demande au démon backend (comme à l'étape 3) et le processus se répète.

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

Installation des composants

Le fichier de configuration NGINX Plus distribué 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 s'exécuter sur le même hôte, ce qui est suffisant à des fins de test. Le serveur LDAP peut également s'exécuter sur cet hôte pendant les tests.

Dans un déploiement réel, l'application back-end et le serveur d'authentification s'exécutent généralement chacun sur un hôte distinct, avec NGINX Plus sur un troisième hôte. Le démon ldap-auth ne consomme pas beaucoup de ressources dans la plupart des situations, il peut donc s'exécuter sur l'hôte NGINX Plus ou sur un autre hôte de votre choix.

  1. Créez un clone du dépôt GitHub .

  2. Si NGINX Plus n'est pas déjà en cours d'exécution, installez-le conformément aux instructions de votre système d'exploitation.

  3. Si un serveur LDAP n’est pas déjà en cours d’exécution, installez-en un 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 vous pouvez configurer un serveur à l'aide d'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 placerez dans le fichier de configuration NGINX dans Configuration de l'implémentation de référence .

  4. Sur l’hôte sur lequel le démon ldap-auth doit s’exécuter, installez le logiciel supplémentaire suivant. Nous vous recommandons d'utiliser les versions distribuées avec le système d'exploitation, au lieu de télécharger le logiciel à partir d'un référentiel open source.

    • Version 2 de Python. La version 3 n'est pas prise en charge.
    • Le module Python LDAP, python‑ldap (créé par le projet open source python-ldap.org ).
  5. Copiez les fichiers suivants de votre clone de référentiel vers les hôtes indiqués :

    • nginx-ldap-auth.conf – Fichier de configuration NGINX Plus qui inclut l’ensemble minimal de directives pour 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, n'oubliez pas de déplacer ou de renommer tous les fichiers de configuration par défaut installés avec NGINX Plus.
    • nginx-ldap-auth-daemon.py – Code Python pour le démon ldap-auth. Installez sur l'hôte de votre choix.
    • nginx-ldap-auth-daemon-ctl.sh – Exemple de script shell pour démarrer et 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 pour le démon qui, pendant les tests, remplace un serveur d’application backend. Installez sur l'hôte de votre choix.
  6. Modifiez le fichier de configuration NGINX Plus comme décrit dans 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 le fichier est syntaxiquement valide.

    root# nginx -t nginx : la syntaxe du fichier de configuration /etc/nginx/nginx.conf est correcte nginx : le test du fichier de configuration /etc/nginx/nginx.conf est réussi
    
  7. 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 recharger
    
  8. Exécutez les commandes suivantes sur les hôtes appropriés pour démarrer le démon ldap-auth et le démon backend.

    racine# nginx-ldap-auth-daemon-ctl.sh démarrer racine# python backend-sample-app.py
    
  9. Utilisez un navigateur Web pour accéder à http:// nginx-server-address :8081 . Vérifiez que le navigateur présente le formulaire d’authentification. Après avoir rempli le formulaire et l'avoir soumis, vérifiez que le serveur renvoie la réponse attendue aux informations d'identification valides. Comme indiqué ci-dessus, le démon backend renvoie le texte suivant :

       Bonjour le monde! URL demandée : URL
    

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

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

Paramètres du serveur LDAP

Tel qu'implémenté dans nginx-ldap-auth-daemon.py , le démon ldap-auth communique avec un serveur OpenLDAP, en transmettant des paramètres pour spécifier le compte utilisateur à authentifier. Pour éliminer le besoin de 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 qui sont ensuite utilisées pour définir les paramètres. Le tableau suivant répertorie les paramètres et les en-têtes.

Paramètre LDAP En-tête HTTP
basé sur X-Ldap-BaseDN
lier X-Ldap-BindDN
mot de passe de liaison X-LDAP-BindPass
nom du cookie Nom du cookie X
royaume Royaume X-Ldap
modèle Modèle X-Ldap
URL URL X-Ldap
  • (Obligatoire) Dans les directives suivantes, remplacez les valeurs en gras par les valeurs correctes pour votre déploiement de serveur LDAP. Notez en particulier que le fichier nginx-ldap-auth.conf utilise le port bien connu pour LDAPS, 636. Si vous changez le port en 389 (le port bien connu pour LDAP) ou un autre port LDAP, n'oubliez pas également de changer le nom du protocole de ldaps en ldap .

    # URL et port pour la connexion au serveur LDAP proxy_set_header X-Ldap-URL " ldaps :// example.com :636 "; # DN de base proxy_set_header X-Ldap-BaseDN " cn=Users,dc=test,dc=local "; # DN de liaison proxy_set_header X-Ldap-BindDN " cn=root,dc=test,dc=local "; # Mot de passe de liaison proxy_set_header X-Ldap-BindPass " secret ";
    
  • (Obligatoire si vous utilisez Active Directory au lieu d'OpenLDAP) Supprimez le commentaire de la directive suivante comme indiqué :

    proxy_set_header Modèle X-Ldap "(SAMAccountName=%(username)s)";
    
  • (Facultatif) L’implémentation de référence utilise l’authentification basée sur les cookies. Si vous utilisez plutôt l'authentification HTTP de base, commentez 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 de modèle que le démon ldap-auth transmet au serveur OpenLDAP par défaut, supprimez le commentaire de la directive suivante comme indiqué et modifiez la valeur :

    proxy_set_header Modèle X-Ldap " (cn=%(username)s) ";
    
  • (Facultatif) Si vous souhaitez modifier le nom du domaine par rapport à la valeur par défaut ( Restricted ), supprimez le commentaire et modifiez la directive suivante :

    proxy_set_header X-Ldap-Realm " Restreint ";
    

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 en amont :

backend en amont { serveur127.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 :

emplacement = /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 d’écoute (ou supprimez complètement l’adresse pour accepter le trafic de n’importe quel client). Vous pouvez également modifier le port sur lequel NGINX écoute à partir de 8081 si vous le souhaitez :

serveur { écouter127.0.0.1 :8081 ; # ... }

Mise en cache

Le fichier nginx-ldap-auth.conf permet la mise en cache des données et des informations d'identification. En option, vous pouvez modifier les paramètres suivants :

  • La directive proxy_cache_path dans le bloc de configuration http crée un répertoire de disque local appelé cache et alloue 10 Mo de mémoire partagée pour une zone appelée auth_cache , où les métadonnées sont stockées.

    chemin_cache_proxy 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 d’emplacement qui dirige le trafic vers le démon ldap-auth).

    emplacement = /auth-proxy { proxy_cache auth_cache ; # ... }
    
  • La directive proxy_cache_valid (dans le même bloc d'emplacement que proxy_cache ) spécifie que les réponses mises en cache marquées avec le code HTTP200 ou403 sont valables 10 minutes.

    emplacement = /auth-proxy { proxy_cache_valid 200 403 10m ; # ... }
    

Pour désactiver la mise en cache, commentez ces trois directives ainsi que la directive proxy_cache_key .

Personnalisation du système d'authentification

Comme mentionné ci-dessus, vous pouvez utiliser le démon ldap-auth comme modèle pour votre propre application qui accepte les requêtes du module http_auth_request. Si vous écrivez une application en Python pour communiquer avec un type de serveur d’authentification différent (non LDAP), écrivez une nouvelle classe de gestionnaire d’authentification pour remplacer LDAPAuthHandler dans le script nginx-ldap-auth-daemon.py .

Remarque sur la sécurité

Le démon backend utilise l'encodage Base64 sur le nom d'utilisateur et le mot de passe dans le cookie. Base64 est une forme très faible de brouillage, rendant les informations d'identification vulnérables à l'extraction et à l'utilisation abusive. Pour que l’authentification serve réellement à quelque chose, vous devez utiliser un cryptage plus sophistiqué dans votre application back-end.


« Cet article de blog peut faire référence à des produits qui ne sont plus disponibles et/ou qui ne sont plus pris en charge. Pour obtenir les informations les plus récentes sur les produits et solutions F5 NGINX disponibles, explorez notre famille de produits NGINX . NGINX fait désormais partie de F5. Tous les liens NGINX.com précédents redirigeront vers un contenu NGINX similaire sur F5.com."