En esta guía, se proporcionan instrucciones para configurar NGINX para que use una clave de Cloud HSM para la descarga de TLS en Debian 11 (Bullseye). Es posible que debas modificar estos comandos para que funcionen con tu distribución de Linux o SO.
Casos de uso
El uso de una clave de Cloud HSM con NGINX para la descarga de TLS ayuda a abordar las siguientes necesidades de seguridad empresarial:
- Quieres que tu servidor web NGINX transfiera las operaciones criptográficas de TLS a Cloud HSM.
- No quieres almacenar la clave privada de tu certificado en el sistema de archivos local de la instancia de Compute Engine que aloja tu aplicación web.
- Debes cumplir con los requisitos reglamentarios en los que las aplicaciones públicas necesitan que sus certificados estén protegidos por un HSM que tenga certificación de nivel 3 del estándar FIPS 140-2.
- Deseas usar NGINX para crear un proxy inverso con finalización de TLS para proteger tu aplicación web.
Antes de comenzar
Antes de continuar, completa los pasos que se indican en Usa una clave de Cloud HSM con OpenSSL.
Una vez que se complete la configuración de OpenSSL, asegúrate de tener instalada una versión reciente de nginx
:
sudo apt-get update
sudo apt-get install libengine-pkcs11-openssl opensc nginx
Recomendaciones de configuración de seguridad
Protege la instancia que aloja NGINX con las siguientes recomendaciones:
Sigue las instrucciones para crear y habilitar cuentas de servicio en instancias destinadas a alojar NGINX.
- Asigna los siguientes roles:
roles/cloudkms.signerVerifier
roles/cloudkms.viewer
- Asigna los siguientes roles:
Configura las políticas de la organización de la siguiente manera para limitar las IP externas y la creación de claves de cuentas de servicio.
constraints/compute.vmExternalIpAccess
constraints/iam.disableServiceAccountKeyCreation
Crear una subred personalizada que habilite el Acceso privado a Google
Configura reglas de firewall.
- Crea reglas de firewall de IAP solo para SSH.
Crea una VM de Linux y configúrala de la siguiente manera:
- Selecciona la cuenta de servicio correcta que creaste antes.
- Selecciona la red que creaste anteriormente.
- Agrega las etiquetas apropiadas para cualquier regla de firewall.
- Asegúrate de que la subred tenga el campo “IP externa” configurado como
none
.
Otorga a tu identidad el rol de usuario de túnel protegido con IAP (
roles/iap.tunnelResourceAccessor
) en la instancia.- Lee Configuración de IAP para el procesamiento a fin de obtener más información.
Crea y configura una clave de firma alojada en Cloud KMS
En las siguientes secciones, se detallan los pasos necesarios para crear y configurar una clave de firma alojada en Cloud KMS.
Crea una clave de firma alojada en Cloud KMS
Crea una clave de firma EC-P256-SHA256
de Cloud KMS en tu proyecto de Google Cloud, en el llavero de claves que configuraste antes para OpenSSL:
gcloud kms keys create NGINX_KEY \
--keyring "KEY_RING" --project "PROJECT_ID" \
--location "LOCATION" --purpose "asymmetric-signing" \
--default-algorithm "ec-sign-p256-sha256" --protection-level "hsm"
Establece una conexión SSH a tu VM con IAP
Establece una conexión SSH a tu VM con IAP con el siguiente comando:
gcloud compute ssh INSTANCE \
--zone ZONE --tunnel-through-iap
Si tienes un problema, confirma que usaste la marca --tunnel-through-iap
.
Además, confirma que tienes el rol Usuario de túnel protegido con IAP (roles/iap.tunnelResourceAccessor
) en la instancia para la identidad autenticada con gcloud CLI.
Cómo crear un certificado con OpenSSL
Para un entorno de producción, crea una solicitud de firma de certificado (CSR). Obtén más información mediante la lectura del ejemplo para generar una CSR. Proporciona la CSR a tu autoridad certificadora (AC) para que pueda crear un certificado por ti. Usa el certificado proporcionado por tu AC en las secciones posteriores.
Por ejemplo, puedes generar un certificado autofirmado con la clave de firma alojada en Cloud KMS. Para hacerlo, OpenSSL te permite usar los URI de PKCS #11 en lugar de una ruta de acceso normal, que identifica la clave por su etiqueta (para las claves de Cloud KMS, la etiqueta es el nombre de la CryptoKey).
openssl req -new -x509 -days 3650 -subj '/CN=CERTIFICATE_NAME/' \
DIGEST_FLAG -engine pkcs11 -keyform engine \
-key PKCS_KEY_TYPE=KEY_IDENTIFIER > CA_CERT
Reemplaza lo siguiente:
CERTIFICATE_NAME
: un nombre para el certificadoDIGEST_FLAG
: Es el algoritmo de resumen que usa la clave de firma asimétrica. Usa-sha256
,-sha384
o-sha512
, según la clave.PKCS_KEY_TYPE
: Es el tipo de identificador que se usa para identificar la clave. Para usar la versión más reciente de la clave, usapkcs11:object
con el nombre de la clave. Para usar una versión de clave específica, usapkcs11:id
con el ID de recurso completo de la versión de clave.KEY_IDENTIFIER
: Es un identificador para la clave. Si usaspkcs11:object
, usa el nombre de la clave, por ejemplo,NGINX_KEY
. Si usaspkcs11:id
, utiliza el ID de recurso completo de la clave o versión de clave, por ejemplo,projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/NGINX_KEY/cryptoKeyVersions/KEY_VERSION
.CA_CERT
: Es la ruta de acceso en la que deseas guardar el archivo del certificado.
Si el comando falla, es posible que PKCS11_MODULE_PATH
se haya configurado de forma incorrecta o que no tengas los permisos correctos para usar la clave de firma de Cloud KMS.
Ahora debería tener un certificado que se vea así:
-----BEGIN CERTIFICATE-----
...
...
...
-----END CERTIFICATE-----
Instala el certificado para NGINX
Ejecuta los siguientes comandos para crear una ubicación y colocar tu certificado público:
sudo mkdir /etc/ssl/nginx
sudo mv CA_CERT /etc/ssl/nginx
Configura tu entorno para usar la biblioteca PKCS #11
En las siguientes secciones, se detallan los pasos necesarios para preparar y probar tu entorno.
Prepara parámetros de configuración de bibliotecas para NGINX
Permite que NGINX registre sus operaciones de motor de PKCS #11 con la biblioteca con lo siguiente:
sudo mkdir /var/log/kmsp11
sudo chown www-data /var/log/kmsp11
Crea un archivo de configuración de biblioteca vacía con los permisos adecuados para NGINX.
sudo touch /etc/nginx/pkcs11-config.yaml
sudo chmod 744 /etc/nginx/pkcs11-config.yaml
Edita el archivo de configuración vacío y agrega la configuración necesaria como se muestra en el siguiente fragmento:
# cat /etc/nginx/pkcs11-config.yaml
---
tokens:
- key_ring: "projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING"
log_directory: "/var/log/kmsp11"
Prueba la configuración de OpenSSL
Ejecuta el siguiente comando:
openssl engine -tt -c -v pkcs11
Deberías ver un resultado similar al siguiente:
(pkcs11) pkcs11 engine
[RSA, rsaEncryption, id-ecPublicKey]
[ available ]
SO_PATH, MODULE_PATH, PIN, VERBOSE, QUIET, INIT_ARGS, FORCE_LOGIN
Configura NGINX para usar Cloud HSM
Edita algunos archivos NGINX para permitir la descarga de TLS. Primero, edita el archivo /etc/nginx/nginx.conf
en dos lugares a fin de agregar algunas directivas para configurar NGINX para que use PKCS #11.
Después del bloque event
y antes del bloque http
, agrega las siguientes directivas:
ssl_engine pkcs11;
env KMS_PKCS11_CONFIG=/etc/nginx/pkcs11-config.yaml;
En el mismo archivo /etc/nginx/nginx.conf
, configura las directivas SSL para usar tu certificado y su clave privada en Cloud HSM. En el bloque http
, agrega los siguientes atributos:
ssl_certificate "/etc/ssl/nginx/CA_CERT";
ssl_certificate_key "engine:pkcs11:PKCS_KEY_TYPE=KEY_IDENTIFIER";
ssl_protocols TLSv1.2 TLSv1.3; # Consider changing the default to only TLS1.2 or newer
# Consider defining the `ssl_ciphers` to use ciphers approved by your security teams and handle
# appropriate client compatibility requirements.
Tu archivo /etc/nginx/nginx.conf
debería verse de la siguiente manera:
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
ssl_engine pkcs11;
env KMS_PKCS11_CONFIG=/etc/nginx/pkcs11-config.yaml;
http {
#...
#...
# SSL configuration
ssl_certificate "/etc/ssl/nginx/CA_CERT";
ssl_certificate_key "engine:pkcs11:pkcs11:object=NGINX_KEY";
ssl_protocols TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
# ssl_ciphers YOUR_CIPHERS
ssl_prefer_server_ciphers on;
#...
#...
}
Configura NGINX para que detecte el tráfico TLS
Edita el archivo /etc/nginx/sites-enabled/default
para detectar el tráfico TLS.
Quita el comentario de la configuración de SSL en el bloque server
.
El cambio resultante debería verse como el siguiente ejemplo:
server {
listen 80 default_server;
listen [::]:80 default_server;
# SSL configuration
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
# ...
# ...
}
Proporciona variables de entorno al servicio NGINX
Ejecuta el siguiente comando:
sudo systemctl edit nginx.service
En el editor resultante, agrega las siguientes líneas y reemplaza LIBPATH
por el valor de la ubicación en la que instalaste libkmsp11.so
:
[Service]
Environment="GRPC_ENABLE_FORK_SUPPORT=1"
Environment="KMS_PKCS11_CONFIG=/etc/nginx/pkcs11-config.yaml"
Environment="PKCS11_MODULE_PATH=LIBPATH/libkmsp11-1.0-linux-amd64/libkmsp11.so"
Después de configurar estos valores, deberás ejecutar el siguiente comando para que estén disponibles:
sudo systemctl daemon-reload
Reinicia NGINX con descarga de TLS
Ejecuta el siguiente comando para que NGINX se reinicie y use la configuración actualizada:
sudo systemctl start nginx
Test NGINX usa la descarga de TLS en tu Cloud HSM
Usa openssl s_client
para probar la conexión con tu servidor NGINX mediante la ejecución del siguiente comando:
openssl s_client -connect localhost:443
El cliente debe completar el protocolo de enlace SSL y hacer una pausa. El cliente espera una entrada de tu parte, como se muestra a continuación:
# completes SSL handshake
# ...
# ...
# ...
Verify return code: 18 (self signed certificate)
# ...
Max Early Data: 0
---
read R BLOCK
# When the client pauses, it’s waiting for instructions.
# Have the client get the index.html file in the root path (“/”), by typing the following:
GET /
# Press enter.
# You should now see the default NGINX index.html file.
Tus registros de auditoría ahora deberían mostrar operaciones en tu clave NGINX_KEY
.
Para ver los registros, navega a Cloud Logging en tu consola de Cloud.
En el proyecto que estuviste usando, agrega el siguiente filtro:
resource.type="cloudkms_cryptokeyversion"
Después de ejecutar la consulta, deberías ver las operaciones de clave asimétrica en tu clave NGINX_KEY
.
Configuración opcional
Es posible que debas crear un balanceador de cargas de red de transferencia externo para exponer tu servidor NGINX con una IP externa.
Si necesitas usar NGINX como un proxy inverso con balanceo de cargas, considera actualizar el archivo de configuración de NGINX. Obtén más información sobre cómo configurar NGINX como un proxy inverso. Para ello, consulta HA totalmente activa para NGINX Plus en Google Cloud Platform.
Próximos pasos
Ya configuraste tu servidor NGINX para que use la descarga de TLS en Cloud HSM.