Utilizzare una chiave Cloud HSM per gestire il traffico Apache

Questa guida fornisce istruzioni per configurare un server Apache in modo che utilizzi una chiave Cloud HSM per la firma TLS su Debian 11 (Bullseye). Potresti dover modificare questi comandi in modo che funzionino con il tuo sistema operativo o la tua distribuzione Linux.

Puoi trovare una versione del progetto basata su Terraform di questo tutorial nel repository GitHub kms-solutions.

Prima di iniziare

Come prerequisito, completa la configurazione descritta in Configurazione di OpenSSL.

Al termine della configurazione di OpenSSL, assicurati che sia installata una versione recente di Apache:

sudo apt-get update
sudo apt-get install apache2

Configurazione

Crea una chiave di firma ospitata in Cloud KMS

Crea una chiave di firma EC-P256-SHA256 Cloud KMS nel tuo progettoGoogle Cloud , nel portachiavi configurato in precedenza per 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"

Creare un certificato autofirmato con OpenSSL

Genera un certificato autofirmato con la chiave di firma ospitata in Cloud KMS. Puoi utilizzare OpenSSL per utilizzare un URI PKCS #11 anziché un percorso file e identificare la chiave tramite l'etichetta. Nella libreria PKCS #11 di Cloud KMS, l'etichetta della chiave è il nome della chiave 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

Sostituisci quanto segue:

  • CERTIFICATE_NAME: un nome per il certificato.
  • DIGEST_FLAG: l'algoritmo di hashing utilizzato dalla chiave di firma asimmetrica. Utilizza -sha256, -sha384 o -sha512 a seconda della chiave.
  • PKCS_KEY_TYPE: il tipo di identificatore utilizzato per identificare la chiave. Per utilizzare la versione più recente della chiave, utilizza pkcs11:object con il nome della chiave. Per utilizzare una versione della chiave specifica, utilizza pkcs11:id con l'ID risorsa completo della versione della chiave.
  • KEY_IDENTIFIER: un identificatore per la chiave. Se utilizzi pkcs11:object, utilizza il nome della chiave, ad esempio KEY_NAME. Se utilizzi pkcs11:id, utilizza l'ID risorsa completo della chiave o della versione della chiave, ad esempio projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/KEY_NAME/cryptoKeyVersions/KEY_VERSION.
  • PATH_TO_CERTIFICATE: il percorso in cui vuoi salvare il file del certificato.

Se questo comando non va a buon fine, è possibile che PKCS11_MODULE_PATH sia stato impostato in modo errato o che tu non disponga delle autorizzazioni necessarie per utilizzare la chiave di firma Cloud KMS.

A questo punto dovresti avere un certificato simile al seguente:

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

Configurare il server Apache

  1. Crea una directory in /etc/apache2 per archiviare il tuo certificato autofirmato:

    sudo mkdir /etc/apache2/ssl
    sudo mv ca.cert /etc/apache2/ssl
    
  2. Modifica i file di configurazione dell'host virtuale 000-default.conf in /etc/apache2/sites-available per fornire il percorso del file del certificato e assicurarti che SSLEngine sia attivo.

    Ecco un esempio di configurazione in ascolto sulla porta 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. Assicurati che Apache esegua correttamente l'esportazione delle variabili di ambiente aggiungendole al file /etc/apache2/envvars utilizzando l'editor di testo che preferisci. Potresti dover modificare il file come utente root utilizzando sudo. Aggiungi le seguenti righe alla fine del file:

    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
    

    Sostituisci quanto segue:

    • PATH_TO_LIBKMSP11: il percorso per libkmsp11.so.
    • PATH_TO_PKCS11_CONFIG: il percorso per pkcs11-config.yaml.

    GRPC_ENABLE_FORK_SUPPORT è necessario per consentire a gRPC di includere il supporto per i fork e di eseguire correttamente la libreria PKCS #11 di Cloud KMS all'interno del server Apache.

    Se vuoi eseguire l'autenticazione utilizzando una chiave dell'account di servizio, devi anche esportare un valore per la variabile di ambiente GOOGLE_APPLICATION_CREDENTIALS.

Esegui il server

Attiva il modulo SSL di Apache, attiva la configurazione del virtualhost e aggiungi una pagina web di test nella cartella 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

Riavvia il server Apache e verifica con curl che la configurazione funzioni come previsto. Il flag --insecure è necessario per ignorare i controlli dei certificati autofirmati.

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

Se riscontri errori, il log degli errori di Apache è un buon punto di partenza per capire cosa è andato storto. I problemi di autenticazione sono una fonte comune di errori. Se vedi errori PERMISSION_DENIED, assicurati di aver eseguito l'autenticazione completa e che il file delle credenziali abbia le autorizzazioni corrette. Per assicurarti di essere completamente autenticato, esegui il seguente comando:

gcloud auth application-default login

Per confermare che l'autenticazione sia andata a buon fine, l'output deve includere la riga Credentials saved to file: [/path/to/credentials.json].