Los clientes nos preguntan con frecuencia cómo pueden utilizar NGINX Plus y NGINX para proteger recursos o aplicaciones mediante la autenticación de los usuarios que solicitan acceder a ellos. Hoy anunciamos una implementación de referencia de un sistema de autenticación de este tipo, que ponemos a disposición en el repositorio de NGINX, Inc. en GitHub. En este artículo explicamos cómo funciona la implementación, cómo instalarla y cómo utilizarla como modelo para su propio sistema de autenticación.
La solución aprovecha el módulo ngx_http_auth_request_module de NGINX Plus y NGINX, que reenvía las solicitudes de autenticación a un servicio externo. En la implementación de referencia, ese servicio es un demonio al que llamamos ldap‑auth. Está escrito en Python y se comunica con un servidor de autenticación mediante el protocolo ligero de acceso a directorios (LDAP), OpenLDAP de forma predeterminada, aunque también hemos probado el demonio ldap‑auth con las configuraciones predeterminadas de Active Directory de Microsoft® Windows® Server (tanto en la versión 2003 como en la 2012).
El demonio ldap‑auth sirve como modelo para su propia aplicación «conector», que puede escribir en otros lenguajes, implementar con distintos sistemas de autenticación o ambas cosas. El equipo de Servicios Profesionales de NGINX está disponible para ayudarle con estas adaptaciones.
Notas:
- La implementación de referencia no está pensada para su uso en producción, sino únicamente como modelo para sus propias implementaciones.
- Para facilitar la lectura, en el resto de este artículo se hace referencia a NGINX Plus, pero la implementación de referencia también funciona con NGINX Open Source. El módulo http_auth_request necesario se incluye tanto en los paquetes de NGINX Plus como en los binarios precompilados de NGINX.
Cómo funciona la autenticación en la implementación de referencia
Para realizar la autenticación, el módulo http_auth_request envía una subsolicitud HTTP al demonio ldap‑auth, que actúa como intermediario e interpreta la subsolicitud para el servidor LDAP; utiliza HTTP para comunicarse con NGINX Plus y la API correspondiente para comunicarse con el servidor LDAP.
Suponemos que, si le interesa la implementación de referencia, ya dispone de una aplicación u otros recursos que desea proteger mediante autenticación. No obstante, para facilitar las pruebas de la implementación de referencia, proporcionamos un demonio de backend de ejemplo, también escrito en Python, que escucha en el puerto 9000. Durante las pruebas, puede sustituir a una aplicación HTTP real solicitando las credenciales del usuario y creando una cookie a partir de ellas.

A continuación se describe paso a paso el proceso de autenticación en la implementación de referencia. Los detalles vienen determinados por los ajustes del archivo de configuración nginx-ldap-auth.conf; consulte Configuración de la implementación de referencia más adelante. El diagrama de flujo que aparece después de los pasos resume el proceso.
- Un cliente envía una solicitud HTTP de un recurso protegido alojado en un servidor para el que NGINX Plus actúa como proxy inverso.
- NGINX Plus (concretamente, el módulo http_auth_request) reenvía la solicitud al demonio ldap‑auth, que responde con el código HTTP
401porque no se proporcionaron credenciales. - NGINX Plus reenvía la solicitud a http://backend/login, que corresponde al demonio de backend. Escribe el URI de la solicitud original en la cabecera
X-Targetde la solicitud reenviada. - El demonio de backend envía al cliente un formulario de inicio de sesión (el formulario está definido en el código Python del demonio). Según la configuración de la directiva
error_page, NGINX establece el código HTTP del formulario de inicio de sesión en200. - El usuario rellena los campos Nombre de usuario y Contraseña del formulario y hace clic en el botón Iniciar sesión. Según el código del formulario, el cliente genera una solicitud HTTP
POSTdirigida a /login, que NGINX Plus reenvía al demonio de backend. - El demonio de backend crea una cadena con el formato
username:password, aplica la codificación Base64, genera una cookie denominada nginxauth cuyo valor se establece en la cadena codificada y envía la cookie al cliente. Establece la marcahttponlypara impedir que se use JavaScript para leer o manipular la cookie (lo que protege frente a la vulnerabilidad de secuencias de comandos entre sitios [XSS]). - El cliente vuelve a enviar su solicitud original (del paso 1), esta vez incluyendo la cookie en el campo
Cookiede la cabecera HTTP. NGINX Plus reenvía la solicitud al demonio ldap‑auth (como en el paso 2). - El demonio ldap‑auth descodifica la cookie y envía el nombre de usuario y la contraseña al servidor LDAP en una solicitud de autenticación.
- La siguiente acción depende de si el servidor LDAP autentica correctamente al usuario:
- Si la autenticación se realiza correctamente, el demonio ldap‑auth envía el código HTTP
200a NGINX Plus. NGINX Plus solicita el recurso al demonio de backend. En la implementación de referencia, el demonio de backend devuelve el siguiente texto:
- Si la autenticación se realiza correctamente, el demonio ldap‑auth envía el código HTTP
Hello, world! Requested URL: URL- El archivo nginx-ldap-auth.conf incluye directivas para almacenar en caché los resultados del intento de autenticación; para deshabilitar el almacenamiento en caché, consulte Almacenamiento en caché más abajo.
- Si la autenticación falla, el demonio ldap‑auth envía el código HTTP
401a NGINX Plus. NGINX Plus reenvía la solicitud al demonio de backend (como en el paso 3) y el proceso se repite.

Instalación de los componentes
El archivo de configuración de NGINX Plus distribuido con la implementación de referencia, nginx-ldap-auth.conf, configura todos los componentes excepto el servidor LDAP (es decir, NGINX Plus, el cliente, el demonio ldap‑auth y el demonio de backend) para que se ejecuten en el mismo host, lo cual resulta adecuado para realizar pruebas. El servidor LDAP también puede ejecutarse en ese host durante las pruebas.
En una implementación real, la aplicación de backend y el servidor de autenticación suelen ejecutarse cada uno en un host independiente, mientras que NGINX Plus se ejecuta en un tercer host. En la mayoría de las situaciones, el demonio ldap-auth no consume muchos recursos, por lo que puede ejecutarse en el host de NGINX Plus o en cualquier otro host que elija.
- Cree un clon del repositorio de GitHub.
- Si NGINX Plus aún no está en ejecución, instálelo siguiendo las instrucciones correspondientes a su sistema operativo.
- Si aún no hay ningún servidor LDAP en ejecución, instale y configure uno. De forma predeterminada, el demonio ldap‑auth se comunica con OpenLDAP, aunque también se admiten Microsoft Windows Active Directory 2003 y 2012. Si utiliza el servidor LDAP únicamente para probar la implementación de referencia, puede usar la imagen de Docker del servidor OpenLDAP disponible en GitHub, o bien configurar un servidor siguiendo instrucciones como Cómo instalar y configurar OpenLDAP y phpLDAPadmin en Ubuntu 16.04. Anote los valores que establezca para el DN base, el DN de enlace y la contraseña de enlace. Deberá introducirlos en el archivo de configuración de NGINX, en Configuración de la implementación de referencia.
- En el host donde se vaya a ejecutar el demonio ldap‑auth, instale el siguiente software adicional. Recomendamos utilizar las versiones distribuidas con el sistema operativo en lugar de descargar el software de un repositorio de código abierto.
- Python versión 2. La versión 3 no es compatible.
- El módulo LDAP de Python, python‑ldap (creado por el proyecto de código abierto python-ldap.org).
- Copie los siguientes archivos del clon de su repositorio en los hosts indicados:
- nginx-ldap-auth.conf – Archivo de configuración de NGINX Plus que incluye el conjunto mínimo de directivas para probar la implementación de referencia. Instálelo en el host de NGINX Plus (en el directorio /etc/nginx/conf.d si utiliza el esquema de configuración convencional). Para evitar conflictos de configuración, recuerde mover o cambiar el nombre de cualquier archivo de configuración predeterminado instalado con NGINX Plus.
- nginx-ldap-auth-daemon.py – Código Python para el demonio ldap‑auth. Instálelo en el host que prefiera.
- nginx-ldap-auth-daemon-ctl.sh – Script de shell de ejemplo para iniciar y detener el demonio. Instálelo en el mismo host que el demonio ldap‑auth.
- backend-sample-app.py – Código Python del demonio que, durante las pruebas, sustituye a un servidor de aplicaciones backend. Instálelo en el host que prefiera.
- Modifique el archivo de configuración de NGINX Plus como se describe en Configuración de la implementación de referencia a continuación. Después de realizar los cambios, ejecute el comando
nginx-tpara comprobar que la sintaxis del archivo sea válida.
root# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful- Inicie NGINX Plus. Si NGINX Plus ya está en ejecución, ejecute el siguiente comando para volver a cargar el archivo de configuración:
root# nginx -s reload- Ejecute los siguientes comandos en los hosts correspondientes para iniciar el demonio ldap‑auth y el demonio de backend.
root# nginx-ldap-auth-daemon-ctl.sh start
root# python backend-sample-app.py- Utilice un navegador web para acceder a http://nginx-server-address:8081. Compruebe que el navegador muestra el formulario de autenticación. Después de rellenar y enviar el formulario, compruebe que el servidor devuelve la respuesta esperada al introducir credenciales válidas. Como se ha indicado anteriormente, el demonio del backend devuelve el siguiente texto:
Hello, world! Requested URL: URLConfiguración de la implementación de referencia
Realice los siguientes cambios en el archivo nginx-ldap-auth.conf. Algunos son obligatorios y otros opcionales, tal como se indica.
Configuración del servidor LDAP
Tal como se implementa en nginx-ldap-auth-daemon.py, el demonio ldap‑auth se comunica con un servidor OpenLDAP y le pasa parámetros para especificar qué cuenta de usuario se debe autenticar. Para evitar tener que modificar el código Python, el archivo nginx-ldap-auth.conf contiene directivas proxy_set_header que establecen valores en la cabecera HTTP, los cuales se utilizan posteriormente para definir los parámetros. En la tabla siguiente se muestra la correspondencia entre los parámetros y las cabeceras.
Parámetro LDAP Cabecera HTTPbasedn X-Ldap-BaseDNbinddn X-Ldap-BindDNbindpasswd X-Ldap-BindPasscookiename X-CookieNamerealm X-Ldap-Realmtemplate X-Ldap-Templateurl X-Ldap-URL
- (Obligatorio) En las siguientes directivas, sustituya los valores en negrita por los valores correctos para la implementación de su servidor LDAP. Tenga especialmente en cuenta que el archivo nginx-ldap-auth.conf utiliza el puerto estándar de LDAPS, el 636. Si cambia el puerto al 389 (el puerto estándar de LDAP) o a otro puerto LDAP, recuerde cambiar también el nombre del protocolo de
ldapsaldap.
# 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";- (Obligatorio si se utiliza Active Directory en lugar de OpenLDAP) Quite el comentario de la siguiente directiva tal como se muestra:
proxy_set_header X-Ldap-Template "(SAMAccountName=%(username)s)";- (Opcional) La implementación de referencia utiliza autenticación basada en cookies. Si utiliza en su lugar la autenticación básica HTTP, comente las siguientes directivas tal como se muestra:
#proxy_set_header X-CookieName "nginxauth";
#proxy_set_header Cookie nginxauth=$cookie_nginxauth;- (Opcional) Si desea cambiar el valor del parámetro
templateque el demonio ldap‑auth envía de forma predeterminada al servidor OpenLDAP, quite el comentario de la siguiente directiva como se muestra y cambie el valor:
proxy_set_header X-Ldap-Template "(cn=%(username)s)";- (Opcional) Si desea cambiar el nombre del dominio respecto al valor predeterminado (Restricted), quite el comentario de la siguiente directiva y modifíquela:
proxy_set_header X-Ldap-Realm "Restricted";Dirección IP del demonio de backend
Si el demonio de backend no se ejecuta en el mismo host que NGINX Plus, cambie su dirección IP en el bloque de configuración upstream:
upstream backend { server 127.0.0.1:9000;
}Dirección IP del demonio ldap‑auth
Si el demonio ldap‑auth no se ejecuta en el mismo host que NGINX Plus, cambie la dirección IP en esta directiva proxy_pass:
location = /auth-proxy { proxy_pass http://127.0.0.1:8888;
# ...
}Dirección IP y puerto en los que escucha NGINX
Si el cliente no se ejecuta en el mismo host que NGINX Plus, cambie la dirección IP en esta directiva listen (o elimine por completo la dirección para aceptar tráfico de cualquier cliente). Si lo desea, también puede cambiar el puerto 8081 en el que escucha NGINX:
server { listen 127.0.0.1:8081;
# ...
}Almacenamiento en caché
El archivo nginx-ldap-auth.conf permite almacenar en caché tanto los datos como las credenciales. Si lo desea, puede cambiar las siguientes opciones:
- La directiva
proxy_cache_pathdel bloque de configuraciónhttpcrea un directorio de disco local denominado cache y asigna 10 MB de memoria compartida a una zona denominada auth_cache, donde se almacenan los metadatos.
proxy_cache_path cache/ keys_zone=auth_cache:10m;- Si cambia el nombre de la zona de memoria compartida, también debe cambiarlo en la directiva «
proxy_cache» (en el bloque «location» que dirige el tráfico al demonio ldap‑auth).
location = /auth-proxy {
proxy_cache auth_cache;
# ...
}- La directiva
proxy_cache_valid(en el mismo bloquelocationqueproxy_cache) especifica que las respuestas almacenadas en caché marcadas con el código HTTP200o403son válidas durante 10 minutos.
location = /auth-proxy { proxy_cache_valid 200 403 10m;
# ...
}Para deshabilitar el almacenamiento en caché, comenta estas tres directivas, además de la directiva proxy_cache_key.
Personalización del sistema de autenticación
Como se ha mencionado anteriormente, puede utilizar el demonio ldap‑auth como modelo para su propia aplicación que acepte solicitudes del módulo http_auth_request. Si escribe una aplicación en Python para comunicarse con un tipo diferente de servidor de autenticación (que no sea LDAP), cree una nueva clase de gestión de autenticación que sustituya a LDAPAuthHandler en el script nginx-ldap-auth-daemon.py.
Nota sobre la seguridad
El demonio del backend utiliza codificación Base64 para el nombre de usuario y la contraseña de la cookie. Base64 es una forma de ofuscación muy débil, por lo que las credenciales son vulnerables a su extracción y uso indebido. Para que la autenticación cumpla realmente su función, debe utilizar un cifrado más sofisticado en su aplicación backend.
Sobre el autor

Artículos relacionados del blog
Únete a F5 NGINX en AppWorld 2024
Descubre las numerosas razones para asistir al evento insignia de F5, que incluirá un emocionante anuncio sobre la cartera de productos NGINX.
Rotación de certificados SSL/TLS sin reinicios en NGINX Open Source
La función de diccionario compartido permite configurar NGINX sin necesidad de reiniciarlo al renovar los certificados SSL/TLS.
Exposición de APIs en Kubernetes
La unidad 2 de Microservices March 2022 se centra en cómo exponer tus API en Kubernetes. Aquí tienes enlaces a los recursos que necesitas: la retransmisión en directo del 14 de marzo, artículos de blog y otros recursos de preparación, y el laboratorio práctico «Protege las API de Kubernetes mediante la limitación de solicitudes».
NGINX Sprint 2.0: visión clara, código renovado y nuevos compromisos con el código abierto
Hoy, en NGINX Sprint 2.0, anunciamos cómo respaldaremos nuestra visión del futuro de las aplicaciones modernas con una mayor presencia en la comunidad de código abierto, incluida la participación en el proyecto comunitario Kubernetes, nuevos proyectos de software de código abierto y la arquitectura de referencia para aplicaciones modernas.
Presentamos NGINX Plus R22
NGINX Plus R22 incorpora nuevas funcionalidades, como la compatibilidad con OCSP para verificar la revocación de certificados en TLS mutuo, el uso de varios proveedores de identidad OIDC en una configuración, el seguimiento en tiempo real de la limitación de solicitudes y conexiones en el panel de NGINX Plus y mejoras en NGINX JavaScript.
Presentamos NGINX Plus R17
NGINX Plus R17 incorpora compatibilidad con la limitación de velocidad en dos fases y con TLS 1.3, la versión más reciente del protocolo Transport Layer Security. La configuración de OpenID Connect es más sencilla y NGINX ModSecurity WAF es el doble de rápido que antes. También se ha actualizado el módulo JavaScript de NGINX.