BLOG | NGINX

Distribución segura de claves privadas SSL con NGINX

NGINX - Parte de F5 - horizontal, negro, tipo RGB
Miniatura de Owen Garrett
Owen Garrett
Publicado el 2 de abril de 2019

Esta publicación de blog describe varios métodos para distribuir de forma segura las claves privadas SSL que NGINX utiliza al alojar sitios web encriptados con SSL. Explica:

Para muchas implementaciones, el enfoque estándar es suficiente. Los dos enfoques más sofisticados analizados en esta publicación bloquean otras formas en las que un atacante puede obtener claves privadas SSL. También veremos un par de técnicas más en publicaciones de seguimiento:

  • Uso de almacenes secretos de terceros como HashiCorp Vault para distribuir contraseñas de forma segura
  • Automatizar el aprovisionamiento de certificados desde Vault al almacén de clave-valor de NGINX Plus, de modo que el material de clave privada nunca se almacene en el disco

Los enfoques presentados en esta publicación se aplican a los usuarios que necesitan administrar sus propias claves y crear su propia estrategia de distribución segura de claves. No son necesarios para los usuarios que ejecutan NGINX en entornos que ya se integran con un almacén secreto, como Kubernetes .

Esta publicación se aplica tanto a NGINX Open Source como a NGINX Plus. Para facilitar la lectura, haremos referencia a NGINX en todo momento.

Editor: Esta publicación es la primera de una serie sobre cómo proteger las claves privadas SSL en NGINX. Consulte también las demás publicaciones de la serie:

 

¿Por qué proteger la clave privada SSL?

SSL/TLS se utiliza para autenticar, cifrar y verificar la integridad de las transacciones de red. Los sitios web se autentican mediante un certificado público firmado por una autoridad de certificación (CA) y demuestran que poseen el certificado realizando cálculos utilizando la clave privada correspondiente (que debe mantenerse en secreto).

Si la clave privada se ve comprometida (se divulga a otra entidad), existen dos riesgos principales.

  • Riesgo 1: Suplantación de identidad . Un atacante que tenga la clave privada puede interceptar el tráfico de la red y luego montar un ataque Mitm ( hombre en el medio ). Este ataque captura y descifra todo el tráfico, quizás incluso modificándolo, sin que los clientes o el sitio web se den cuenta.
  • Riesgo 2: Descifrado . Un atacante que tenga la clave privada y haya registrado el tráfico de la red podrá luego descifrar el tráfico de la red sin conexión. Tenga en cuenta que este ataque no se puede utilizar contra conexiones que utilizan un cifrado de secreto directo perfecto (PFS).

Si la clave privada se ve comprometida, su único recurso es comunicarse con la CA y solicitar que se revoque su certificado; luego debe confiar en que los clientes verifiquen y respeten el estado de revocación.

Además, es una buena práctica utilizar certificados con tiempos de expiración cortos (por ejemplo, los certificados Let's Encrypt expiran después de 90 días). Poco antes de que expire un certificado, es necesario generar una nueva clave privada y obtener un nuevo certificado de la CA. Esto reduce su exposición en caso de que la clave privada se vea comprometida.

El límite de seguridad de NGINX

¿Qué personas y procesos pueden acceder a las claves privadas SSL en NGINX?

En primer lugar, cualquier usuario que obtenga acceso root al servidor que ejecuta NGINX puede leer y utilizar todos los recursos que utiliza el propio NGINX. Por ejemplo, existen métodos conocidos para extraer la clave privada SSL de la memoria de un proceso en ejecución.

Por lo tanto, no importa cómo se almacene y distribuya la clave privada, no es posible protegerla de un atacante con privilegios de root en el servidor host.

Luego, cualquier usuario que pueda modificar y confirmar la configuración de NGINX puede usar ese poder de muchas maneras: para abrir el acceso proxy a servicios internos, para eludir las medidas de autenticación, etc. Él o ella puede modificar la configuración de NGINX para obtener acceso root (o equivalente) al servidor, aunque herramientas como SELinux y AppArmor ayudan a mitigar esa posibilidad.

Por lo tanto, generalmente no es posible proteger la clave privada de un atacante que pueda modificar y confirmar la configuración de NGINX.

Afortunadamente, cualquier organización competente cuenta con sólidos procesos de seguridad para dificultar que un atacante obtenga privilegios de root o modifique la configuración de NGINX.

Sin embargo, hay otras dos formas en que un atacante con menos privilegios podría obtener acceso a la clave privada:

  • Un usuario podría tener una razón legítima para necesitar ver la configuración de NGINX, o podría obtener acceso a una base de datos de configuración o una copia de seguridad. Las claves privadas de NGINX normalmente se almacenan en la configuración.
  • Un usuario podría obtener acceso al sistema de archivos del servidor NGINX, quizás a través de un hipervisor o una copia de seguridad del sistema. Cualquier dato almacenado en el sistema de archivos, incluido el material de clave privada, es potencialmente accesible.

Los procesos descritos en este documento sellan estos dos métodos de ataque.

Configuración estándar de NGINX

Comenzamos repasando cómo es una configuración típica de NGINX con SSL/TLS:

servidor { escuchar 443 ssl; nombre_servidor a.dev0; certificado_ssl ssl/a.dev0.crt; clave_certificado_ssl ssl/a.dev0.key; ubicación / { devolver 200 "Hola desde el servicio A\n"; } }

El certificado público SSL ( a.dev0.crt ) y la clave privada ( a.dev0.key ) se almacenan en el sistema de archivos, en /etc/nginx/ssl/ . La clave privada solo la lee el proceso maestro NGINX, que normalmente se ejecuta como root , por lo que puede establecer los permisos de acceso más estrictos posibles:

root@web1:/etc/nginx/ssl# ls -l a.dev0.key -r-------- 1 root root 1766 15 ago 16:32 a.dev0.key

La clave privada debe estar disponible en todo momento; el proceso maestro NGINX la lee cada vez que se inicia el software NGINX, se recarga la configuración o se realiza una verificación de sintaxis ( nginx -t ).

Para obtener más información sobre la configuración de SSL/TLS, consulte la Guía de administración de NGINX Plus .

Implicaciones de seguridad de la configuración estándar

Como se señaló anteriormente, la clave privada SSL puede ser leída por un atacante que obtenga acceso root al contenedor, la máquina virtual o el servidor que ejecuta el software NGINX.

Cifrado de claves privadas SSL

NGINX admite claves privadas cifradas, utilizando algoritmos seguros como AES256:

root@web1:/etc/nginx/ssl# mv a.dev0.key a.dev0.key.plain root@web1:/etc/nginx/ssl# openssl rsa -aes256 -in a.dev0.key.plain -out a.dev0.key escribiendo clave RSA Ingrese frase de contraseña PEM: contraseña segura Verificando - Ingrese frase de contraseña PEM: contraseña segura nuevamente

Cuando inicia NGINX, o recarga o prueba la configuración de NGINX, NGINX solicita la contraseña de descifrado de forma interactiva:

root@web1:/etc/nginx# nginx -t Ingrese la frase de contraseña PEM: contraseña segura nginx: la sintaxis del archivo de configuración /etc/nginx/nginx.conf es correcta nginx: la prueba del archivo de configuración /etc/nginx/nginx.conf es exitosa

Uso de un archivo de contraseña SSL

Ingresar contraseñas de forma interactiva es incómodo y difícil de automatizar, pero puede configurar NGINX para utilizar una lista de contraseñas almacenadas en un archivo separado denominado mediante la directiva ssl_password_file . Cuando NGINX necesita leer una clave privada, intenta descifrarla utilizando cada una de las contraseñas del archivo por turno. Si ninguna de las contraseñas es válida, NGINX se niega a iniciarse.

archivo_contraseña_ssl /var/lib/nginx/ssl_passwords.txt;

El archivo ssl_password_file debe distribuirse por separado de la configuración y sólo puede ser leído por el usuario root . Puede considerarse como un token de autorización que se coloca en servidores confiables. NGINX solo puede descifrar las claves privadas cuando se ejecuta en un servidor con el token de autorización.

Implicaciones de seguridad de las claves cifradas en un archivo separado

Este método reduce la superficie de ataque al hacer que la configuración de NGINX por sí sola sea inútil para un atacante. El atacante también debe obtener el contenido del archivo ssl_password_file .

Si un atacante obtiene acceso root al sistema de archivos donde se almacena el ssl_password_file (por ejemplo, desde una copia de seguridad o a través del sistema host), puede leer el archivo y usar las contraseñas para descifrar las claves privadas SSL.

Puede reducir este riesgo almacenando el archivo ssl_password_file en un disco RAM o tmpfs . Este almacenamiento generalmente es menos accesible para un atacante externo (por ejemplo, se borra cuando se reinicia el servidor) y puede excluirse de las copias de seguridad del sistema. Debe asegurarse de que el archivo de contraseña se inicialice al iniciar el sistema.

Distribuir listas de contraseñas SSL de forma más segura

El proceso a continuación describe una forma más segura de distribuir listas de contraseñas SSL, desde un punto de distribución central.

Cada vez que NGINX necesita descifrar una clave SSL, consulta el punto de distribución central y utiliza las contraseñas sin almacenarlas nunca en el disco local. Para autenticarse con el servidor de contraseñas central, la instancia NGINX utiliza un token que puede revocar en cualquier momento para cortar el acceso a las contraseñas.

Creación de un punto central de distribución de contraseñas

Comience por crear un punto de distribución de contraseñas (PDP). Para esta implementación sencilla, utilizamos un servicio HTTPS para entregar la lista de contraseñas, autenticadas por nombre de usuario y contraseña:

$ curl -u dev0:mypassword https://pdpserver.local/ssl_passwords.txt contraseña1 contraseña2 ...

Luego puede habilitar o revocar el acceso agregando o quitando tokens de autenticación en el PDP según sea necesario. Puede implementar el servidor de distribución de contraseñas utilizando un servidor web como NGINX y usar cualquier tipo de tokens de autenticación que sea apropiado.

A continuación, debemos configurar NGINX para recuperar las contraseñas del PDP. Comenzamos creando un script de shell llamado conector.sh con el siguiente contenido:

#!/bin/sh
# Uso: conector.sh

CONECTOR=$1
CREDS=$2
PDP_URL=$3

[ -e $CONECTOR ] && /bin/rm -f $CONECTOR

mkfifo $CONECTOR; chmod 600 $CONECTOR

mientras sea verdadero; hacer
curl -s -u $CREDS -k $PDP_URL -o $CONECTOR
hecho

El script debe ejecutarse como un proceso en segundo plano, invocado de la siguiente manera:

raíz@web1:~# ./connector.sh /var/run/nginx/ssl_passwords \dev0:micontraseña https://pdpserver.local/ssl_passwords.txt &

El conector se conecta a la ruta local especificada ( /var/run/nginx/ssl_passwords ) y usted utiliza la directiva ssl_password_file para configurar NGINX para acceder a esa ruta:

archivo_contraseñas_ssl /var/run/nginx/contraseñas_ssl;

Pruebe el conector leyendo la ruta del conector:

root@web1:~# cat /var/run/nginx/ssl_passwords contraseña1 contraseña2 ...

Verifique que NGINX pueda leer la contraseña y descifrar las claves SSL:

root@web1:~# nginx -t nginx: la sintaxis del archivo de configuración /etc/nginx/nginx.conf es correcta nginx: la prueba del archivo de configuración /etc/nginx/nginx.conf es exitosa

Puede utilizar el enfoque PDP central para distribuir de forma segura cualquier recurso que NGINX normalmente lee desde el disco, por ejemplo, claves privadas individuales u otros datos confidenciales.

Implicaciones de seguridad de un PDP

Esta solución tiene varias ventajas en comparación con el almacenamiento de contraseñas SSL en el disco:

  • Las contraseñas SSL nunca se almacenan en el sistema de archivos del servidor , por lo que un atacante que tenga acceso al sistema de archivos no puede acceder a ellas directamente.
  • Las contraseñas se distribuyen desde un punto de acceso central , lo que hace que sea más fácil realizar la supervisión y la auditoría.
  • El acceso a servidores individuales se puede controlar de forma centralizada . Por ejemplo, una vez que se da de baja un servidor, se revoca su token de acceso.

Tenga en cuenta que un usuario que tenga acceso al sistema de archivos puede potencialmente extraer las credenciales utilizadas para acceder al PDP. Es importante revocar estas credenciales cuando ya no sean necesarias.

resumen

Hay muchas formas de proteger las claves privadas SSL contra la divulgación, con niveles crecientes de seguridad y complejidad:

  • Para la gran mayoría de las organizaciones, es suficiente restringir el acceso a los entornos que ejecutan NGINX para que usuarios no autorizados no puedan obtener acceso root ni ver la configuración de NGINX.
  • Para algunos entornos, puede que no sea posible restringir completamente el acceso a la configuración de NGINX, por lo que se puede utilizar un archivo de contraseña SSL.
  • En casos limitados, las organizaciones podrían desear asegurarse de que las claves y contraseñas nunca se almacenen en el disco. El proceso del punto de distribución de contraseñas ilustra una prueba de concepto para esta solución.

Las otras publicaciones de esta serie describen pasos adicionales que puede seguir para proteger las claves SSL:

Pruebe NGINX Plus usted mismo: comience hoy mismo su prueba gratuita de 30 días o contáctenos para analizar sus casos de uso .


"Esta publicación de blog puede hacer referencia a productos que ya no están disponibles o que ya no reciben soporte. Para obtener la información más actualizada sobre los productos y soluciones F5 NGINX disponibles, explore nuestra familia de productos NGINX . NGINX ahora es parte de F5. Todos los enlaces anteriores de NGINX.com redirigirán a contenido similar de NGINX en F5.com.