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 o descarregamento do 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 Nível 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.
Assim que 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 sua instância que está a alojar 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.signerVerifierroles/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.vmExternalIpAccessconstraints/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 do Cloud HSM
As secções seguintes detalham os passos necessários para criar e configurar uma chave de assinatura do Cloud HSM.
Crie uma chave de assinatura alojada no Cloud HSM
Crie uma chave de assinatura do Cloud HSM no seu projeto, no conjunto de chaves que configurou anteriormente para o OpenSSL:EC-P256-SHA256Google Cloud
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"
Estabeleça ligação à sua VM através do SSH e do IAP
Estabeleça ligação à sua VM através do SSH e 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. Forneça 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 do Cloud HSM. 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,-sha384ou-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:objectcom o nome da chave. Para usar uma versão específica da chave, usepkcs11:idcom 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 usar opkcs11: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, é possível que PKCS11_MODULE_PATH tenha sido definido incorretamente ou que não tenha 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 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 seguinte fragmento:
# 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 para configurar o 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 conclui o handshake SSL e aguarda a sua entrada:
# 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 registos de auditoria devem agora mostrar operações na sua chave NGINX_KEY.
Para ver os registos, navegue para o Cloud Logging na sua Google Cloud consola.
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 como configurar o NGINX como um proxy inverso lendo o artigo HA totalmente ativo para o NGINX Plus na Google Cloud plataforma.
Passos seguintes
Configurou o servidor NGINX para usar a transferência de carga do TLS para o Cloud HSM.