Usa una clave de Cloud HSM para entregar tráfico de Apache

En esta guía, se proporcionan instrucciones para configurar un servidor Apache a fin de usar una clave de Cloud HSM para la firma de TLS en Debian 11 (Bullseye). Es posible que debas modificar estos comandos para que funcionen con tu SO o distribución de Linux.

Puedes encontrar una versión de este instructivo basada en un modelo de Terraform en el repositorio de GitHub de kms-solutions.

Antes de comenzar

Como requisito, completa la configuración documentada en Configuración de OpenSSL.

Una vez que se complete la configuración de OpenSSL, asegúrate de instalar una versión reciente de Apache:

sudo apt-get update
sudo apt-get install apache2

Configuración

Crea una clave de firma alojada en Cloud KMS

Crea una clave de firma EC-P256-SHA256 de Cloud KMS en tu proyecto deGoogle Cloud , en el llavero de claves que configuraste antes para OpenSSL:

gcloud kms keys create "KEY_NAME" --keyring "KEY_RING" \
  --project "PROJECT_ID" --location "LOCATION" \
  --purpose "asymmetric-signing" --default-algorithm "ec-sign-p256-sha256" \
  --protection-level "hsm"

Crea un certificado autofirmado con OpenSSL

Genera un certificado autofirmado con la clave de firma alojada en Cloud KMS. Puedes usar OpenSSL para usar un URI PKCS #11 en lugar de una ruta de acceso al archivo y así identificar la clave por su etiqueta. En la biblioteca PKCS #11 de Cloud KMS, la etiqueta de clave es el nombre de CryptoKey.

openssl req -new -x509 -days 3650 -subj '/CN=CERTIFICATE_NAME/' \
  DIGEST_FLAG -engine pkcs11 -keyform engine \
  -key PKCS_KEY_TYPE=KEY_IDENTIFIER > PATH_TO_CERTIFICATE

Reemplaza lo siguiente:

  • CERTIFICATE_NAME: un nombre para el certificado
  • DIGEST_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, usa pkcs11:object con el nombre de la clave. Para usar una versión de clave específica, usa pkcs11:id con el ID de recurso completo de la versión de clave.
  • KEY_IDENTIFIER: Es un identificador para la clave. Si usas pkcs11:object, usa el nombre de la clave, por ejemplo, KEY_NAME. Si usas pkcs11:id, usa el ID de recurso completo de la clave o la versión de la clave, por ejemplo, projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY_NAME/cryptoKeyVersions/KEY_VERSION.
  • PATH_TO_CERTIFICATE: Es la ruta de acceso en la que deseas guardar el archivo del certificado.

Si este comando falla, es posible que PKCS11_MODULE_PATH se haya configurado de forma incorrecta o que no tengas los permisos adecuados para usar la clave de firma de Cloud KMS.

Ahora debería tener un certificado que se vea así:

-----BEGIN CERTIFICATE-----
...
...
...
-----END CERTIFICATE-----

Configura el servidor Apache

  1. Crea un directorio en /etc/apache2 para almacenar tu certificado autofirmado:

    sudo mkdir /etc/apache2/ssl
    sudo mv ca.cert /etc/apache2/ssl
    
  2. Edita los archivos de configuración del host virtual 000-default.conf ubicados en /etc/apache2/sites-available para proporcionar la ruta del archivo del certificado y asegurarte de que SSLEngine esté activado.

    A continuación, se muestra una configuración de muestra que escucha en el puerto 443:

      <VirtualHost *:443>
            ServerAdmin webmaster@localhost
            DocumentRoot /var/www/html
            ErrorLog ${APACHE_LOG_DIR}/error.log
            CustomLog ${APACHE_LOG_DIR}/access.log combined
            SSLEngine on
            SSLCertificateFile /etc/apache2/ssl/ca.cert
            SSLCertificateKeyFile "PKCS_KEY_TYPE=KEY_IDENTIFIER"
      </VirtualHost>
    
  3. Asegúrate de que Apache exporte las variables de entorno de forma correcta; para ello, agrégalas al archivo /etc/apache2/envvars con el editor de texto que prefieras. Es posible que necesites editar el archivo como raíz con sudo. Agrega las siguientes líneas al final del archivo:

    export PKCS11_MODULE_PATH="<var>PATH_TO_LIBKMSP11</var>"
    export KMS_PKCS11_CONFIG="<var>PATH_TO_PKCS11_CONFIG</var>"
    export GRPC_ENABLE_FORK_SUPPORT=1
    

    Reemplaza lo siguiente:

    • PATH_TO_LIBKMSP11: Es la ruta de acceso a libkmsp11.so.
    • PATH_TO_PKCS11_CONFIG: Es la ruta de acceso a pkcs11-config.yaml.

    Se necesita GRPC_ENABLE_FORK_SUPPORT para que gRPC incluya compatibilidad con la bifurcación y ejecute de forma correcta la biblioteca PKCS #11 de Cloud KMS como parte del servidor Apache.

    Si deseas autenticarte con una clave de cuenta de servicio, también debes exportar un valor para la variable de entorno GOOGLE_APPLICATION_CREDENTIALS.

Ejecuta el servidor

Habilita el módulo SSL de Apache, habilita la configuración de host virtual y agrega una página web de prueba en la carpeta DocumentRoot:

sudo a2enmod ssl
sudo a2ensite 000-default.conf
echo '<!doctype html><html><body><h1>Hello World!</h1></body></html>' | \
  sudo tee /var/www/html/index.html

Reinicia tu servidor Apache y prueba con curl que la configuración funcione como se espera. La marca --insecure es necesaria para ignorar las verificaciones de certificados autofirmados.

sudo systemctl restart apache2
curl -v --insecure https://127.0.0.1

Si encuentras algún error, el registro de errores de Apache es un buen punto de partida para ver qué salió mal. Los problemas de autenticación son una fuente común de errores. Si ves errores de PERMISSION_DENIED, asegúrate de que tu cuenta esté completamente autenticada y de que el archivo de credenciales tenga los permisos correctos. Para asegurarte de que tienes la autenticación completa, ejecuta el siguiente comando:

gcloud auth application-default login

Para confirmar que la autenticación se realizó correctamente, el resultado debe incluir la línea Credentials saved to file: [/path/to/credentials.json].