En la primera entrada de esta serie, describimos varios métodos para mejorar la seguridad de sus claves privadas SSL. La entrada concluyó con una demostración de un punto remoto de distribución de contraseñas (PDP), utilizado para compartir de forma segura contraseñas de cifrado con instancias de NGINX.
Los sistemas de gestión de secretos como HashiCorp Vault funcionan de forma similar al PDP del ejemplo:
- Utilizan un servicio de gestión de secretos centralizado (o distribuido y de alta disponibilidad) al que se accede mediante HTTPS u otra API
- Los clientes se autentican mediante tokens de autenticación u otros medios
- Los tokens pueden revocarse según sea necesario para controlar el acceso al secreto
En este artículo, mostramos cómo configurar HashiCorp Vault para distribuir contraseñas SSL. Para aumentar aún más la seguridad, puede configurar un módulo de seguridad de hardware externo (HSM).
Para eliminar por completo el almacenamiento en disco de los pares de certificado y clave SSL, consulte 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». En ella se explica cómo generar claves SSL efímeras a partir de HashiCorp Vault y almacenarlas en memoria en el almacén de clave-valor de NGINX Plus.
Este artículo se aplica tanto a NGINX Open Source como a NGINX Plus. Para facilitar la lectura, nos referiremos a NGINX en todo el artículo.
Uso de HashiCorp Vault para proteger las claves privadas SSL
Las instrucciones de esta sección configuran un servidor PDP central mediante Vault para distribuir contraseñas SSL. Se basan en las instrucciones de DigitalOcean; modifíquelas según sea necesario para cumplir sus propias políticas de Vault.
En nuestro ejemplo, cada servidor web remoto tiene un token de autenticación único. Estos tokens se pueden utilizar para acceder a los secretos de 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
- Siga las instrucciones de DigitalOcean para descargar y extraer Vault en su servidor PDP. Utilizamos el siguiente archivo de ejemplo /etc/vault.hcl para permitir el acceso remoto a Vault y deshabilitar TLS (para facilitar las pruebas):
backend "file" { path = "/var/lib/vault"
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_disable = 1
}- Inicie Vault mediante los scripts de inicio (si los ha creado) o manualmente:
user@pdp:~$ sudo /usr/local/bin/vault server -config=/etc/vault.hcl- Inicializa Vault y obtén el token raíz inicial:
user@pdp:~$ export VAULT_ADDR=http://localhost:8200
user@pdp:~$ vault init -key-shares=3 -key-threshold=2
user@pdp:~$ vault operator unseal
Initial Root Token: 86c5c2a4-8ab2-24dd-1816-48449c83114e- Necesitamos proporcionar el token raíz inicial en muchos de los comandos siguientes. Para mayor comodidad, lo asignamos a la variable de shell «
root_token»:
user@pdp:~$ root_token=86c5c2a4-8ab2-24dd-1816-48449c83114eAlmacenar los secretos
- Mientras sigues trabajando en el servidor PDP, crea un archivo temporal llamado /tmp/ssl_passwords.txt que contenga las contraseñas.
- Guarda este archivo como un secreto en Vault y comprueba que puedes recuperarlo:
user@pdp:~$ VAULT_TOKEN=$root_token vault kv put secret/webservers/ssl_passwords value=@/tmp/ssl_passwords.txt
user@pdp:~$ VAULT_TOKEN=$root_token vault kv get -field=value secret/webservers/ssl_passwords
password1
password2
...- Por seguridad, elimina /tmp/ssl_passwords.txt.
- Cree una especificación de política en un archivo llamado web.hcl con el siguiente contenido:
path "secret/webservers/*" {
capabilities = ["read"]
}- Carga la política en Vault y asígnale el nombre «
web»:
user@pdp:~$ VAULT_TOKEN=$root_token vault policy write web web.hcl- Crea un nuevo token de autenticación, asócialo a la política
webe incluye, si lo deseas, el parámetrodisplay-namepara asignarle un nombre descriptivo. Anota los valores detokenytoken_accessor; los utilizarás en los comandos posteriores:
user@pdp:~$ VAULT_TOKEN=$root_token vault token create -policy=web -display-name=webserver1
Key Value
--- -----
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
webimpide que el servidor web recupere secretos fuera de la ruta secret/webservers/*.
Verificar que el servidor web puede recuperar el token
- En el servidor web NGINX, instale el binario de Vault.
- Declara la ubicación del servidor Vault remoto (en este caso, http://pdp:8200), y después comprueba que la máquina del servidor web pueda recuperar las contraseñas SSL mediante el token:
user@web1:~$ export VAULT_ADDR=http://pdp:8200user@web1:~$ VAULT_TOKEN=dcf75ffd-a245-860f-6960-dc9e834d3385 vault kv get -field=value secret/webservers/ssl_passwords
password1
password2
...Configurar el conector de Vault de NGINX en el servidor web
- Como parte de la configuración del PDP de ejemplo en la primera publicación, creamos un script de shell llamado connector.sh en el host de NGINX (la máquina del servidor web). A continuación, lo modificamos para que utilice Vault:
#!/bin/sh
# Usage: connector_v.sh
CONNECTOR=$1
CREDS=$2
[ -e $CONNECTOR ] && /bin/rm -f $CONNECTOR
mkfifo $CONNECTOR; chmod 600 $CONNECTOR
export VAULT_ADDR=http://pdp:8200
export VAULT_TOKEN=$CREDS
while true; do
vault kv get -field=value secret/webservers/ssl_passwords > $CONNECTOR
sleep 0.1 # race condition, ensures EOF
done- Ejecute el script como un proceso en segundo plano de la siguiente manera:
root@web1:~# ./connector_v.sh /var/run/nginx/ssl_passwords \dcf75ffd-a245-860f-6960-dc9e834d3385 &- Pruebe el conector leyendo desde la ruta del conector:
root@web1:~$ cat /var/run/nginx/ssl_passwordspassword1
password2
...- Configure NGINX para que lea el archivo ssl_passwords al iniciarse y utilice su contenido como contraseñas para descifrar claves privadas cifradas. Puede incluir la directiva
ssl_password_fileen un bloqueserver(como el creado para la configuración estándar en la primera publicación) o en el contextohttppara aplicarla a varios servidores virtuales:
ssl_password_file /var/run/nginx/ssl_passwords;- Compruebe que NGINX pueda leer la contraseña y descifrar las claves SSL:
root@web1:~# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successfulRevocación del token de autenticación de un servidor web
Puedes revocar fácilmente el acceso si el servidor web se ve comprometido o cuando se retira del servicio. Para ello, puedes revocar directamente el token de autenticación utilizado por el servidor web:
user@pdp:~$ VAULT_TOKEN=$root_token vault token revoke dcf75ffd-a245-860f-6960-dc9e834d3385Los tokens de Vault son datos confidenciales, y muchos flujos de trabajo de Vault no almacenan copias de los tokens emitidos a un cliente autenticado. Si se filtra una copia de un token, un atacante puede suplantar al cliente.
En su lugar, es habitual gestionar un token activo mediante su descriptor de acceso, que otorga permisos limitados sobre el token y no permite recuperar su valor. En vez de almacenar los tokens cuando se emiten, almacene el descriptor de acceso correspondiente.
Si necesita determinar el descriptor de acceso del token de autenticación de un servidor web, ejecute el comando vault list para obtener la lista de descriptores de acceso y, a continuación, ejecute el comando vault token lookup con cada descriptor hasta encontrar el que tenga el nombre para mostrar y la política pertinentes:
user@pdp:~$ VAULT_TOKEN=$root_token vault list /auth/token/accessors
Keys
----
83be5a73-9025-1221-cb70-4b0e8a3ba8df
0c1d6181-7adf-7b42-27be-b70cfa264048
f043b145-7a63-01db-ea85-9f22f413c55e
user@pdp:~$ VAULT_TOKEN=$root_token vault token lookup -accessor 0c1d6181-7adf-7b42-27be-b70cfa264048
Key Value
--- -----
...
display-name webserver1
...
policy web
...A continuación, puedes revocar el token mediante su descriptor de acceso:
user@pdp:~$ VAULT_TOKEN=$root_token vault token revoke -accessor 0c1d6181-7adf-7b42-27be-b70cfa264048Implicaciones de seguridad
El uso de Vault presenta un perfil de seguridad similar al del PDP de ejemplo descrito en la primera publicación. Las claves privadas SSL solo pueden obtenerse si se consigue la contraseña correspondiente y, para ello, un atacante debe conocer el valor de un token de autenticación vigente.
La principal ventaja de usar Vault es automatizar y escalar el almacén de secretos.
Uso de un HSM externo para gestionar claves privadas
Ninguna de las soluciones que hemos abordado hasta ahora en esta serie protege la clave privada cuando un atacante obtiene acceso de usuario root al servidor NGINX. Si un atacante puede acceder a la memoria de ejecución de NGINX o generar un volcado de memoria, existen técnicas bien conocidas para analizar la memoria del proceso y localizar los datos de la clave privada.
Los módulos de seguridad de hardware (HSM) externos solucionan este problema almacenando las claves privadas SSL en hardware externo a prueba de manipulaciones. Ofrecen el descifrado como servicio, al que NGINX accede siempre que necesita realizar una operación SSL que requiere la clave.
El servidor NGINX nunca tiene acceso a los datos de la clave privada SSL. Un atacante que obtenga acceso root al servidor no podrá obtener la clave privada SSL, pero sí descifrar datos bajo demanda accediendo al servicio de descifrado del HSM con las credenciales de NGINX.
Configuración de NGINX para acceder a un HSM
NGINX delega todas las operaciones con claves privadas SSL en una biblioteca criptográfica denominada OpenSSL. Los dispositivos HSM de terceros pueden ponerse a disposición de NGINX mediante el motor OpenSSL del proveedor del HSM.
La configuración de NGINX es específica para el HSM de cada proveedor, pero generalmente sigue un proceso sencillo:
- Configure NGINX para que utilice el motor OpenSSL del proveedor en lugar del motor de software predeterminado:
ssl_certificate_key engine:vendor-hsm-engine:...;- En lugar de utilizar la clave privada real, configure NGINX para que use la clave «falsa» proporcionada por el proveedor. Esta clave contiene un identificador que permite localizar la clave real en el dispositivo HSM:
ssl_certificate_key ssl/vendor.private.key;- La clave también puede contener las credenciales para acceder al dispositivo HSM, o bien estas pueden proporcionarse mediante una configuración adicional específica del proveedor.
- (Opcional) Aplique los ajustes que desee, como aumentar el número de procesos de trabajo de NGINX, para maximizar el rendimiento de NGINX y del HSM.
Para ver un ejemplo de configuración de un HSM, consulte la documentación de CloudHSM de Amazon.
Implicaciones de seguridad
Los HSM externos son un método muy seguro para almacenar claves privadas SSL. Un atacante con acceso de usuario root al servidor NGINX puede utilizar las credenciales de NGINX para descifrar datos arbitrarios mediante el HSM, pero no puede obtener la clave privada sin cifrar. Un HSM dificulta considerablemente que un atacante suplante un sitio web o descifre datos arbitrarios sin conexión.
Conclusión
Es fundamental garantizar que los datos confidenciales, como la clave privada SSL, estén totalmente protegidos, ya que las consecuencias de su divulgación son muy graves.
Para muchas organizaciones que cuentan con procesos de seguridad adecuados, basta con almacenar la clave privada en los balanceadores de carga del frontend y, a continuación, limitar y auditar todos los accesos a esos servidores (la «configuración estándar» descrita en la primera publicación).
Para las organizaciones que necesitan implementar con frecuencia la configuración de NGINX, las medidas descritas en esta publicación y en la primera pueden utilizarse para limitar los usuarios o entidades que pueden ver los datos de la clave privada.
En la tercera entrada 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 desde Vault al almacén de clave-valor de NGINX Plus mediante la API de NGINX Plus.
Cabe recordar que ninguno de estos métodos reduce la necesidad de proteger por completo las instancias de NGINX en ejecución frente al acceso remoto o la manipulación de la configuración.
Prueba NGINX Plus – empieza hoy mismo tu prueba gratuita de 30 días o ponte en contacto con nosotros para hablar sobre tus casos de uso.
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.