BLOG | NGINX

Protección de claves privadas SSL en NGINX con HashiCorp Vault

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

En la primera publicación de esta serie , describimos varios enfoques para mejorar la seguridad de sus claves privadas SSL. La publicación finalizó con una demostración de un punto de distribución de contraseñas remoto (PDP) utilizado para compartir de forma segura contraseñas de cifrado con instancias NGINX.

Los sistemas de gestión de secretos como HashiCorp Vault funcionan de manera similar a ese PDP de muestra:

  • Utilizan un servicio de secretos central (o altamente disponible y distribuido) al que se accede mediante HTTPS u otra API.
  • Los clientes se autentican mediante tokens de autenticación u otros medios.
  • Los tokens se pueden revocar según sea necesario para controlar el acceso al secreto.

En esta publicación, mostramos cómo configurar HashiCorp Vault para distribuir contraseñas SSL. Para mayor seguridad, puede configurar un módulo de seguridad de hardware (HSM) externo .

Para eliminar por completo el almacenamiento en disco de pares de claves y certificados SSL, consulte la tercera publicación de esta serie, Uso del almacén de clave-valor NGINX Plus para proteger claves SSL efímeras desde HashiCorp Vault . Explica cómo generar claves SSL efímeras desde HashiCorp Vault y almacenarlas en la memoria en el almacén de clave-valor NGINX Plus.

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.

Uso de HashiCorp Vault para proteger las claves privadas SSL

Las instrucciones de esta sección configuran un servidor PDP central que utiliza Vault para distribuir contraseñas SSL. Se basan en las instrucciones de DigitalOcean ; modifíquelas según sea necesario para cumplir con sus propias políticas de Vault.

En nuestro ejemplo, cada servidor web remoto tiene un token de autenticación único. Estos tokens se pueden usar para acceder a secretos en la ruta secret/webservers/ de Vault, y almacenamos las contraseñas SSL en secret/webservers/ssl_passwords .

Veremos cómo proteger los tokens y cómo revocar tokens de autenticación individuales cuando sea necesario.

Descargar, instalar e inicializar HashiCorp Vault en el servidor PDP

  1. Siga las instrucciones de DigitalOcean para descargar y extraer Vault en su servidor PDP. Estamos usando el siguiente archivo de muestra /etc/vault.hcl para hacer que Vault sea accesible de forma remota y para deshabilitar TLS (para facilitar su uso durante las pruebas):

    backend "archivo" { ruta = "/var/lib/vault"
    }
    listener "tcp" {
    dirección = "0.0.0.0:8200"
    tls_disable = 1
    }
    
  2. Inicie Vault utilizando los scripts de inicio (si los creó) o manualmente:

    usuario@pdp:~$ sudo /usr/local/bin/vault server -config=/etc/vault.hcl
    
  3. Inicializar Vault y obtener el token raíz inicial:

    usuario@pdp:~$ export VAULT_ADDR=http://localhost:8200 usuario@pdp:~$ vault init -key-shares=3 -key-threshold=2 usuario@pdp:~$ vault operator unseal Token raíz inicial: 86c5c2a4-8ab2-24dd-1816-48449c83114e
    
  4. Necesitamos proporcionar el token raíz inicial en muchos de los siguientes comandos. Para mayor comodidad, lo asignamos a la variable de shell root_token :

    usuario@pdp:~$ root_token=86c5c2a4-8ab2-24dd-1816-48449c83114e
    

Guarda los secretos

  1. Siguiendo trabajando en el servidor PDP, crea un archivo temporal llamado /tmp/ssl_passwords.txt con las contraseñas en él.

  2. Guarde este archivo como secreto en Vault y verifique que puede recuperarlo:

    usuario@pdp:~$ VAULT_TOKEN=$root_token vault kv put secreto/servidores web/contraseñas_ssl valor=@/tmp/ssl_passwords.txt usuario@pdp:~$ VAULT_TOKEN=$root_token vault kv get -campo=valor secreto/servidores web/contraseñas_ssl contraseña1 contraseña2 ...
    
  3. Por seguridad, elimine /tmp/ssl_passwords.txt .

  4. Cree una especificación de política en un archivo llamado web.hcl con el siguiente contenido:

    ruta "secreto/servidores web/*" {
    capacidades = ["leer"]
    }
    
  5. Cargue la política en Vault y nómbrela web :

    usuario@pdp:~$ VAULT_TOKEN=$root_token política de bóveda escribir web web.hcl
    
  6. Cree un nuevo token de autenticación, asócielo con la política web y, opcionalmente, incluya el parámetro display-name para darle un nombre fácil de usar. Tome nota de los valores de token y token_accessor ; los utilizará en comandos posteriores:

    usuario@pdp:~$ VAULT_TOKEN=$root_token token de bóveda crear -policy=web -display-name=webserver1 Valor de la clave --- ----- token dcf75ffd-a245-860f-6960-dc9e834d3385 token_accessor 0c1d6181-7adf-7b42-27be-b70cfa264048
    

    El servidor web NGINX utiliza este token para recuperar las contraseñas SSL. La política web evita que el servidor web recupere secretos fuera de la ruta secret/webservers/* .

Verificar que el servidor web pueda recuperar el token

  1. Trabajando en el servidor web NGINX, instale el binario Vault.
  2. Declare la ubicación del servidor Vault remoto (aquí, http://pdp:8200 ) y luego verifique que la máquina del servidor web pueda recuperar las contraseñas SSL usando el token:

    usuario@web1:~$ export VAULT_ADDR=http://pdp:8200 usuario@web1:~$ VAULT_TOKEN=dcf75ffd-a245-860f-6960-dc9e834d3385 vault kv get -field=valor secreto/webservers/ssl_passwords contraseña1 contraseña2 ...
    

Configurar el conector NGINX Vault en el servidor web

  1. Como parte de la configuración del PDP de muestra en la primera publicación , creamos un script de shell llamado conector.sh en el host NGINX (máquina del servidor web). Aquí lo modificamos para usar Vault:

    #!/bin/sh
    # Uso: conector_v.sh
    
    CONECTOR=$1
    CREDS=$2
    
    [ -e $CONECTOR ] && /bin/rm -f $CONECTOR
    
    mkfifo $CONECTOR; chmod 600 $CONECTOR
    
    exportar VAULT_ADDR=http://pdp:8200
    exportar VAULT_TOKEN=$CREDS
    
    while true; do
    vault kv get -field=value secret/webservers/ssl_passwords > $CONECTOR
    sleep 0.1 # condición de carrera, asegura el EOF
    done
    
  2. Ejecute el script como un proceso en segundo plano, invocado de la siguiente manera:

    raíz@web1:~# ./connector_v.sh /var/run/nginx/ssl_passwords \dcf75ffd-a245-860f-6960-dc9e834d3385 &
    
  3. Pruebe el conector leyendo la ruta del conector:

    root@web1:~$ cat /var/run/nginx/ssl_passwords contraseña1 contraseña2 ...
    
  4. Configure NGINX para leer el archivo ssl_passwords al iniciarse y utilizar el contenido como contraseñas para descifrar las claves privadas cifradas. Puede incluir la directiva ssl_password_file en un bloque de servidor (como el creado para la configuración estándar en la primera publicación) o en el contexto http para aplicarlo a múltiples servidores virtuales:

    archivo_contraseñas_ssl /var/run/nginx/contraseñas_ssl;
    
  5. 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
    

Revocar el token de autenticación de un servidor web

Puede revocar el acceso fácilmente si el servidor web se ve comprometido o cuando se desmantela. Para ello, puede revocar directamente el token de autenticación utilizado por el servidor web:

usuario@pdp:~$ VAULT_TOKEN=$root_token revocación de token de bóveda dcf75ffd-a245-860f-6960-dc9e834d3385

Los tokens de Vault son elementos de datos confidenciales y muchos flujos de trabajo de Vault no almacenan copias de los tokens que se emiten a un cliente autenticado. Si se filtra una copia de un token, un atacante puede hacerse pasar por el cliente.

En cambio, es común administrar un token activo utilizando su descriptor de acceso , que otorga derechos limitados sobre el token y no se puede utilizar para recuperar el valor del token. En lugar de almacenar tokens cuando se emiten, almacene su descriptor de acceso correspondiente.

Si necesita determinar el descriptor de acceso para el token de autenticación de un servidor web, ejecute el comando vault list para recuperar la lista de descriptores de acceso y el comando vault token lookup en cada descriptor de acceso para encontrar el que tiene el nombre para mostrar y la política correspondientes:

usuario@pdp:~$ VAULT_TOKEN=$root_token lista de bóveda /auth/token/accessors Claves ---- 83be5a73-9025-1221-cb70-4b0e8a3ba8df 0c1d6181-7adf-7b42-27be-b70cfa264048 f043b145-7a63-01db-ea85-9f22f413c55e usuario@pdp:~$ VAULT_TOKEN=$root_token búsqueda de token de bóveda -accessor 0c1d6181-7adf-7b42-27be-b70cfa264048 Valor de la clave --- ----- ... nombre-para-mostrar servidor-web1 ... política web ...

Luego puedes revocar el token usando su accesor:

usuario@pdp:~$ VAULT_TOKEN=$root_token revocación de token de bóveda -accessor 0c1d6181-7adf-7b42-27be-b70cfa264048

Implicaciones de seguridad

El uso de Vault tiene un perfil de seguridad similar al del PDP de muestra descrito en la primera publicación . Las claves privadas SSL solo se pueden obtener si se obtiene la contraseña correspondiente y, para ello, un atacante necesita conocer el valor de un token de autenticación actual.

El beneficio principal de usar Vault es automatizar y escalar el almacén de secretos.

Uso de un HSM externo para administrar claves privadas

Ninguna de las soluciones que hemos cubierto hasta ahora en la serie protege la clave privada cuando un atacante obtiene acceso root al servidor NGINX. Si un atacante puede acceder a la memoria de ejecución de NGINX o generar un volcado de núcleo, existen técnicas bien conocidas para escanear la memoria del proceso y localizar datos de clave privada.

Los módulos de seguridad de hardware externos (HSM) solucionan este problema almacenando las claves privadas SSL en hardware externo a prueba de manipulaciones. Ofrecen descifrado como servicio y NGINX accede a ese servicio cada vez que necesita realizar una operación SSL que requiere la clave.

El servidor NGINX nunca ve los datos de la clave privada SSL. Un atacante que obtiene acceso root al servidor no puede obtener la clave privada SSL, pero puede descifrar datos a pedido accediendo al servicio de descifrado HSM usando las credenciales NGINX.

Configuración de NGINX para acceder a un HSM

NGINX delega todas las operaciones de clave privada SSL a una biblioteca de cifrado llamada OpenSSL. Los dispositivos HSM de terceros pueden ponerse a disposición de NGINX mediante el uso del motor OpenSSL del proveedor de HSM.

La configuración de NGINX es específica para cada HSM del proveedor, pero generalmente sigue una ruta sencilla:

  • Configure NGINX para utilizar el motor OpenSSL del proveedor en lugar del motor de software predeterminado:

    motor de clave de certificado ssl :motor hsm del proveedor:...;
    
  • En lugar de utilizar la clave privada real, configure NGINX para utilizar la clave “falsa” proporcionada por el proveedor. Esta clave contiene un identificador que identifica la clave real en el dispositivo HSM:

    clave_de_certificado_ssl ssl/vendor.private.key;
    

    La clave también puede contener las credenciales para acceder al dispositivo HSM, o las credenciales pueden proporcionarse mediante una configuración adicional específica del proveedor.

  • (Opcional) Aplique cualquier ajuste deseado, como aumentar la cantidad de procesos de trabajo de NGINX, para maximizar el rendimiento de NGINX y el HSM.

Para ver un ejemplo de configuración de HSM, consulte la documentación de CloudHSM de Amazon .

Implicaciones de seguridad

Los HSM externos son un método altamente seguro para almacenar claves privadas SSL. Un atacante con acceso root al servidor NGINX puede aprovechar las credenciales de NGINX para descifrar datos arbitrarios utilizando el HSM, pero no puede obtener la clave privada sin cifrar. Un HSM hace que sea mucho más difícil para un atacante suplantar la identidad de un sitio web o descifrar datos arbitrarios sin conexión.

CONCLUSIÓN

Es esencial garantizar que los datos secretos, como la clave privada SSL, estén completamente protegidos porque las consecuencias de su divulgación son muy graves.

Para muchas organizaciones con procesos de seguridad adecuados implementados, es suficiente almacenar la clave privada en los balanceadores de carga del frontend y luego limitar y auditar todo el acceso a esos servidores (la configuración estándar descrita en la primera publicación).

Para las organizaciones que necesitan implementar la configuración de NGINX con frecuencia, las medidas de esta publicación y la primera se pueden utilizar para limitar los usuarios o entidades que pueden ver los datos de la clave privada.

En la tercera publicación de esta serie, Uso del almacén de clave-valor de NGINX Plus para proteger claves SSL efímeras de HashiCorp Vault , explicamos cómo automatizar el aprovisionamiento de claves y certificados de Vault al almacén de clave-valor de NGINX Plus, mediante la API de NGINX Plus .

Tenga en cuenta nuevamente que ninguno de estos métodos reduce la necesidad de proteger completamente las instancias NGINX en ejecución contra el acceso remoto o la manipulación de la configuración.

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.