Questa guida fornisce istruzioni per configurare NGINX in modo che utilizzi una chiave Cloud HSM per l'offload TLS su Debian 11 (Bullseye). Potrebbe essere necessario modificare questi comandi per farli funzionare con il tuo sistema operativo o la tua distribuzione Linux.
Puoi trovare una versione di questo tutorial basata su Terraform nel repository GitHub kms-solutions.
Casi d'uso
L'utilizzo di una chiave Cloud HSM con NGINX per l'offload TLS consente di soddisfare le seguenti esigenze di sicurezza aziendale:
- Vuoi che il tuo server web NGINX esegua l'offload delle operazioni crittografiche TLS a Cloud HSM.
- Non vuoi archiviare la chiave privata del certificato nel file system locale dell'istanza Compute Engine che ospita la tua applicazione web.
- Devi soddisfare i requisiti normativi in base ai quali le applicazioni rivolte al pubblico devono proteggere i propri certificati con un HSM con certificazione FIPS 140-2 di livello 3.
- Vuoi utilizzare NGINX per creare un reverse proxy con terminazione TLS per proteggere la tua applicazione web.
Prima di iniziare
Prima di continuare, completa i passaggi descritti in Utilizzo di una chiave Cloud HSM con OpenSSL.
Una volta completata la configurazione di OpenSSL, assicurati che sia installata una versione recente di nginx:
sudo apt-get update
sudo apt-get install libengine-pkcs11-openssl opensc nginx
Consigli per la configurazione della sicurezza
Proteggi l'istanza che ospita NGINX con i seguenti consigli:
Segui le istruzioni per creare e attivare service account per le istanze per ospitare NGINX.
- Assegna i seguenti ruoli:
roles/cloudkms.signerVerifierroles/cloudkms.viewer
- Assegna i seguenti ruoli:
Configura le policy dell'organizzazione come segue per limitare gli IP esterni e la creazione di chiavi del account di servizio.
constraints/compute.vmExternalIpAccessconstraints/iam.disableServiceAccountKeyCreation
Crea una subnet personalizzata che consenta l'accesso privato Google.
Configura le regole firewall.
- Crea regole firewall IAP solo per SSH.
Crea una VM Linux e configurala nel seguente modo:
- Seleziona il account di servizio corretto che hai creato in precedenza.
- Seleziona la rete che hai creato in precedenza.
- Aggiungi le etichette appropriate per le regole firewall.
- Assicurati che il campo "IP esterno" della subnet sia impostato su
none.
Concedi alla tua identità il ruolo Utente del tunnel con protezione IAP (
roles/iap.tunnelResourceAccessor) sull'istanza.- Scopri di più leggendo Configurazione di IAP per Compute.
Crea e configura una chiave di firma Cloud HSM
Le sezioni successive descrivono in dettaglio i passaggi necessari per creare e configurare una chiave di firma Cloud HSM.
Crea una chiave di firma ospitata da Cloud HSM
Crea una chiave di firma Cloud HSM EC-P256-SHA256 nel tuo
progettoGoogle Cloud , nel keyring che hai configurato in precedenza
per 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"
Connettiti alla VM utilizzando SSH e IAP
Connettiti alla VM utilizzando SSH e IAP con il seguente comando:
gcloud compute ssh INSTANCE \
--zone ZONE --tunnel-through-iap
Se riscontri un problema, verifica di aver utilizzato il flag --tunnel-through-iap.
Inoltre, verifica di disporre del ruolo Utente del tunnel con protezione IAP
(roles/iap.tunnelResourceAccessor) sull'istanza per l'identità
autenticata con gcloud CLI.
Crea un certificato con OpenSSL
Per un ambiente di produzione, crea una richiesta di firma del certificato (CSR). Scopri di più leggendo l'esempio per generare una richiesta di firma del certificato (CSR). Fornisci la CSR alla tua autorità di certificazione (CA) in modo che possa creare un certificato per te. Utilizza il certificato fornito dalla tua CA nelle sezioni successive.
A scopo esemplificativo, puoi generare un certificato autofirmato con la chiave di firma Cloud HSM. A questo scopo, OpenSSL consente di utilizzare URI PKCS #11 anziché un percorso normale, identificando la chiave in base alla sua etichetta (per le chiavi Cloud KMS, l'etichetta è il nome 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
Sostituisci quanto segue:
CERTIFICATE_NAME: un nome per il certificato.DIGEST_FLAG: l'algoritmo di digest utilizzato dalla chiave di firma asimmetrica. Utilizza-sha256,-sha384o-sha512a seconda della chiave.PKCS_KEY_TYPE: il tipo di identificatore utilizzato per identificare la chiave. Per utilizzare l'ultima versione della chiave, utilizzapkcs11:objectcon il nome della chiave. Per utilizzare una versione specifica della chiave, utilizzapkcs11:idcon l'ID risorsa completo della versione della chiave.KEY_IDENTIFIER: un identificatore per la chiave. Se utilizzipkcs11:object, utilizza il nome della chiave, ad esempioNGINX_KEY. Se utilizzipkcs11:id, usa l'ID risorsa completo della chiave o della versione della chiave, ad esempioprojects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/NGINX_KEY/cryptoKeyVersions/KEY_VERSION.CA_CERT: il percorso in cui vuoi salvare il file del certificato.
Se il comando non va a buon fine, PKCS11_MODULE_PATH potrebbe essere stato impostato in modo errato
oppure potresti non disporre delle autorizzazioni corrette per utilizzare la chiave di firma Cloud KMS.
Ora dovresti avere un certificato simile a questo:
-----BEGIN CERTIFICATE-----
...
...
...
-----END CERTIFICATE-----
Installa il certificato per NGINX
Esegui questi comandi per creare una posizione in cui inserire il certificato pubblico:
sudo mkdir /etc/ssl/nginx
sudo mv CA_CERT /etc/ssl/nginx
Configurare l'ambiente per l'utilizzo della libreria PKCS #11
Le sezioni successive descrivono in dettaglio i passaggi necessari per preparare e testare l'ambiente.
Prepara le configurazioni della libreria per NGINX
Consenti a NGINX di registrare le operazioni del motore PKCS #11 con la libreria con quanto segue:
sudo mkdir /var/log/kmsp11
sudo chown www-data /var/log/kmsp11
Crea un file di configurazione della libreria vuoto con le autorizzazioni appropriate per NGINX.
sudo touch /etc/nginx/pkcs11-config.yaml
sudo chmod 744 /etc/nginx/pkcs11-config.yaml
Modifica il file di configurazione vuoto e aggiungi la configurazione necessaria come mostrato nel seguente snippet:
# cat /etc/nginx/pkcs11-config.yaml
---
tokens:
- key_ring: "projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING"
log_directory: "/var/log/kmsp11"
Testare la configurazione di OpenSSL
Esegui questo comando:
openssl engine -tt -c -v pkcs11
Dovresti vedere un output simile al seguente:
(pkcs11) pkcs11 engine
[RSA, rsaEncryption, id-ecPublicKey]
[ available ]
SO_PATH, MODULE_PATH, PIN, VERBOSE, QUIET, INIT_ARGS, FORCE_LOGIN
Configurare NGINX per l'utilizzo di Cloud HSM
Consenti l'offload TLS modificando alcuni file NGINX. Per prima cosa, modifica il file
/etc/nginx/nginx.conf in due punti per aggiungere alcune direttive per configurare
NGINX in modo che utilizzi PKCS #11.
Dopo il blocco event e prima del blocco http, aggiungi le seguenti
direttive:
ssl_engine pkcs11;
env KMS_PKCS11_CONFIG=/etc/nginx/pkcs11-config.yaml;
Nello stesso file /etc/nginx/nginx.conf, configura le direttive SSL per utilizzare il certificato e la relativa chiave privata in Cloud HSM. Nel blocco http aggiungi gli
attributi seguenti:
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.
Il file /etc/nginx/nginx.conf dovrebbe avere il seguente aspetto:
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;
#...
#...
}
Configurare NGINX per l'ascolto del traffico TLS
Modifica il file /etc/nginx/sites-enabled/default per rilevare il traffico TLS.
Rimuovi il commento dalla configurazione SSL nel blocco server.
La modifica risultante dovrebbe essere simile all'esempio seguente:
server {
listen 80 default_server;
listen [::]:80 default_server;
# SSL configuration
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
# ...
# ...
}
Fornisci le variabili di ambiente al servizio NGINX
Esegui questo comando:
sudo systemctl edit nginx.service
Nell'editor risultante, aggiungi le seguenti righe e sostituisci
LIBPATH con il valore della posizione in cui hai installato
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"
Dopo aver configurato questi valori, devi eseguire il seguente comando per renderli disponibili:
sudo systemctl daemon-reload
Riavvia NGINX con il trasferimento del carico TLS
Esegui il seguente comando in modo che NGINX venga riavviato e utilizzi la configurazione aggiornata:
sudo systemctl start nginx
Test NGINX utilizza l'offload TLS su Cloud HSM
Utilizza openssl s_client per testare la connessione al server NGINX eseguendo il seguente comando:
openssl s_client -connect localhost:443
Il client completa l'handshake SSL e attende il tuo input:
# 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.
I log di controllo ora dovrebbero mostrare le operazioni sulla tua chiave NGINX_KEY.
Per visualizzare i log, vai a Cloud Logging nella console Google Cloud .
Nel progetto che hai utilizzato, aggiungi il seguente filtro:
resource.type="cloudkms_cryptokeyversion"
Dopo aver eseguito la query, dovresti visualizzare le operazioni con chiavi asimmetriche per la chiave
NGINX_KEY.
Configurazioni facoltative
Potresti dover creare un bilanciatore del carico di rete passthrough esterno per esporre il server NGINX con un IP esterno.
Se devi utilizzare NGINX come proxy inverso con bilanciamento del carico, valuta la possibilità di aggiornare il file di configurazione NGINX. Scopri di più sulla configurazione di NGINX come proxy inverso leggendo All-Active HA for NGINX Plus on the Google Cloud Platform.
Passaggi successivi
Ora hai configurato il server NGINX per utilizzare l'offload TLS in Cloud HSM.