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:
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:
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.
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.
¿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:
Los procesos descritos en este documento sellan estos dos métodos de ataque.
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 .
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.
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
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.
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.
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.
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.
Esta solución tiene varias ventajas en comparación con el almacenamiento de contraseñas SSL en el disco:
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.
Hay muchas formas de proteger las claves privadas SSL contra la divulgación, con niveles crecientes de seguridad y complejidad:
root
ni ver la configuración de NGINX.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.