Este guia fornece instruções para configurar o NGINX de modo a usar uma chave do Cloud HSM para descarregar o TLS no Debian 11 (Bullseye). Pode ter de modificar estes comandos para funcionarem com o seu SO ou distribuição Linux.
Pode encontrar uma versão baseada no Terraform deste tutorial no repositório do GitHub kms-solutions.
Exemplos de utilização
A utilização de uma chave do HSM na nuvem com o NGINX para a transferência de TLS ajuda a satisfazer as seguintes necessidades de segurança empresarial:
- Quer que o seu servidor Web NGINX transfira as operações criptográficas TLS para o Cloud HSM.
- Não quer armazenar a chave privada do seu certificado no sistema de ficheiros local da instância do Compute Engine que está a alojar a sua aplicação Web.
- Tem de cumprir os requisitos regulamentares em que as aplicações viradas para o público precisam que os respetivos certificados sejam protegidos por um HSM com a certificação FIPS 140-2 Level 3.
- Quer usar o NGINX para criar um proxy inverso com terminação TLS para proteger a sua aplicação Web.
Antes de começar
Antes de continuar, conclua os passos em Usar uma chave de HSM na nuvem com o OpenSSL.
Quando a configuração do OpenSSL estiver concluída, certifique-se de que tem instalada uma versão recente do nginx
:
sudo apt-get update
sudo apt-get install libengine-pkcs11-openssl opensc nginx
Recomendações de configuração de segurança
Proteja a instância que aloja o NGINX com as seguintes recomendações:
Siga as instruções para criar e ativar contas de serviço para instâncias para alojar o NGINX.
- Atribua as seguintes funções:
roles/cloudkms.signerVerifier
roles/cloudkms.viewer
- Atribua as seguintes funções:
Configure as políticas da organização da seguinte forma para limitar os IPs externos e a criação de chaves de contas de serviço.
constraints/compute.vmExternalIpAccess
constraints/iam.disableServiceAccountKeyCreation
Crie uma sub-rede personalizada que permita o acesso privado à Google.
Configure regras de firewall.
- Crie regras de firewall do IAP apenas para SSH.
Crie uma VM do Linux e configure-a da seguinte forma:
- Selecione a conta de serviço correta que criou anteriormente.
- Selecione a estação que criou anteriormente.
- Adicione etiquetas adequadas para quaisquer regras de firewall.
- Certifique-se de que o campo "IP externo" da sub-rede está definido como
none
.
Conceda à sua identidade a função de utilizador do túnel protegido por IAP (
roles/iap.tunnelResourceAccessor
) na instância.- Saiba mais lendo o artigo Configuração da IAP para computação.
Crie e configure uma chave de assinatura alojada no Cloud KMS
As secções seguintes detalham os passos necessários para criar e configurar uma chave de assinatura alojada no Cloud KMS.
Crie uma chave de assinatura alojada no Cloud KMS
Crie uma EC-P256-SHA256
chave de assinatura do Cloud KMSGoogle Cloud no seu projeto, no conjunto de chaves que configurou anteriormente para o 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"
Faça SSH para a sua VM através do IAP
Faça SSH para a sua VM através do IAP com o seguinte comando:
gcloud compute ssh INSTANCE \
--zone ZONE --tunnel-through-iap
Se tiver um problema, confirme que usou a flag --tunnel-through-iap
.
Além disso, confirme que tem a função de utilizador do túnel protegido por IAP (roles/iap.tunnelResourceAccessor
) na instância para a identidade autenticada com a CLI gcloud.
Crie um certificado com o OpenSSL
Para um ambiente de produção, crie um pedido de assinatura de certificado (CSR). Saiba mais lendo o exemplo para gerar um CSR. Faculte o CSR à sua autoridade de certificação (AC) para que esta possa criar um certificado para si. Use o certificado fornecido pela sua CA nas secções subsequentes.
Para fins de exemplo, pode gerar um certificado autoassinado com a chave de assinatura alojada no Cloud KMS. Para tal, o OpenSSL permite-lhe usar URIs PKCS n.º 11 em vez de um caminho normal, identificando a chave pela respetiva etiqueta (para chaves do Cloud KMS, a etiqueta é o nome da 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
Substitua o seguinte:
CERTIFICATE_NAME
: um nome para o certificado.DIGEST_FLAG
: o algoritmo de resumo usado pela chave de assinatura assimétrica. Use-sha256
,-sha384
ou-sha512
, consoante a tecla.PKCS_KEY_TYPE
: o tipo de identificador usado para identificar a chave. Para usar a versão mais recente da chave, usepkcs11:object
com o nome da chave. Para usar uma versão específica da chave, usepkcs11:id
com o ID de recurso completo da versão da chave.KEY_IDENTIFIER
: um identificador da chave. Se estiver a usar opkcs11:object
, use o nome da chave, por exemplo,NGINX_KEY
. Se estiver a usarpkcs11:id
, use o ID do recurso completo da chave ou da versão da chave, por exemplo,projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING/cryptoKeys/NGINX_KEY/cryptoKeyVersions/KEY_VERSION
.CA_CERT
: o caminho onde quer guardar o ficheiro do certificado.
Se o comando falhar, o PKCS11_MODULE_PATH
pode ter sido definido incorretamente ou pode não ter as autorizações corretas para usar a chave de assinatura do Cloud KMS.
Agora, deve ter um certificado com o seguinte aspeto:
-----BEGIN CERTIFICATE-----
...
...
...
-----END CERTIFICATE-----
Instale o seu certificado para o NGINX
Execute os seguintes comandos para criar uma localização onde colocar o seu certificado público:
sudo mkdir /etc/ssl/nginx
sudo mv CA_CERT /etc/ssl/nginx
Configure o seu ambiente para usar a biblioteca PKCS #11
As secções seguintes detalham os passos necessários para preparar e testar o seu ambiente.
Prepare as configurações da biblioteca para o NGINX
Permita que o NGINX registe as operações do respetivo motor PKCS #11 com a biblioteca com o seguinte:
sudo mkdir /var/log/kmsp11
sudo chown www-data /var/log/kmsp11
Crie um ficheiro de configuração da biblioteca vazio com as autorizações adequadas para o NGINX.
sudo touch /etc/nginx/pkcs11-config.yaml
sudo chmod 744 /etc/nginx/pkcs11-config.yaml
Edite o ficheiro de configuração vazio e adicione a configuração necessária, conforme mostrado no fragmento seguinte:
# cat /etc/nginx/pkcs11-config.yaml
---
tokens:
- key_ring: "projects/PROJECT_ID/locations/LOCATION/keyRings/KEY_RING"
log_directory: "/var/log/kmsp11"
Teste a configuração do OpenSSL
Execute o seguinte comando:
openssl engine -tt -c -v pkcs11
Deverá ver uma saída semelhante à seguinte:
(pkcs11) pkcs11 engine
[RSA, rsaEncryption, id-ecPublicKey]
[ available ]
SO_PATH, MODULE_PATH, PIN, VERBOSE, QUIET, INIT_ARGS, FORCE_LOGIN
Configure o NGINX para usar o Cloud HSM
Permita a transferência de TLS editando alguns ficheiros NGINX. Primeiro, edite o ficheiro /etc/nginx/nginx.conf
em dois locais para adicionar algumas diretivas de configuração do NGINX para usar o PKCS #11.
Após o bloco event
e antes do bloco http
, adicione as seguintes diretivas:
ssl_engine pkcs11;
env KMS_PKCS11_CONFIG=/etc/nginx/pkcs11-config.yaml;
No mesmo ficheiro /etc/nginx/nginx.conf
, configure as diretivas SSL para usar o seu certificado e a respetiva chave privada no Cloud HSM. No bloco http
, adicione os seguintes 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.
O ficheiro /etc/nginx/nginx.conf
deve ter o seguinte aspeto:
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;
#...
#...
}
Configure o NGINX para ouvir o tráfego TLS
Edite o ficheiro /etc/nginx/sites-enabled/default
para ouvir o tráfego TLS.
Descomente a configuração SSL no bloco server
.
A alteração resultante deve ser semelhante ao seguinte exemplo:
server {
listen 80 default_server;
listen [::]:80 default_server;
# SSL configuration
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
# ...
# ...
}
Forneça variáveis de ambiente ao serviço NGINX
Execute o seguinte comando:
sudo systemctl edit nginx.service
No editor resultante, adicione as seguintes linhas e substitua LIBPATH
pelo valor da localização onde instalou 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"
Depois de configurar estes valores, tem de executar o seguinte comando para os disponibilizar:
sudo systemctl daemon-reload
Reinicie o NGINX com a transferência de TLS
Execute o seguinte comando para que o NGINX seja reiniciado e use a configuração atualizada:
sudo systemctl start nginx
Teste se o NGINX usa a transferência de TLS para o Cloud HSM
Use o openssl s_client
para testar a ligação ao seu servidor NGINX executando o seguinte comando:
openssl s_client -connect localhost:443
O cliente deve concluir o handshake SSL e pausar. O cliente está a aguardar a sua introdução, conforme mostrado abaixo:
# 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.
Os seus registos de auditoria devem agora mostrar operações na chave NGINX_KEY
.
Para ver os registos, navegue para Registos na nuvem na consola do Google Cloud.
No projeto que tem usado, adicione o seguinte filtro:
resource.type="cloudkms_cryptokeyversion"
Depois de executar a consulta, deve ver operações de chaves assimétricas na sua chave NGINX_KEY
.
Configurações opcionais
Pode ter de criar um balanceador de carga de rede de encaminhamento externo para expor o seu servidor NGINX com um IP externo.
Se precisar de usar o NGINX como um proxy inverso com equilíbrio de carga, considere atualizar o ficheiro de configuração do NGINX. Saiba mais sobre a configuração do NGINX como um proxy inverso lendo o artigo HA totalmente ativo para o NGINX Plus na Google Cloud Platform.
Passos seguintes
Configurou o servidor NGINX para usar a transferência de carga do TLS para o Cloud HSM.