Use uma chave do Cloud HSM para publicar tráfego do Apache

Este guia fornece instruções para configurar um servidor Apache para usar uma chave do Cloud HSM para assinatura 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.

Antes de começar

Como pré-requisito, conclua a configuração documentada no artigo Configuração do OpenSSL.

Assim que a configuração do OpenSSL estiver concluída, certifique-se de que tem uma versão recente do Apache instalada:

sudo apt-get update
sudo apt-get install apache2

Configuração

Crie uma chave de assinatura alojada no Cloud KMS

Crie uma EC-P256-SHA256chave de assinatura do Cloud KMSGoogle Cloud no seu projeto, no conjunto de chaves que configurou anteriormente para o 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"

Crie um certificado autoassinado com o OpenSSL

Gere um certificado autoassinado com a chave de assinatura alojada no Cloud KMS. Pode usar o OpenSSL para usar um URI PKCS #11 em vez de um caminho de ficheiro e identificar a chave pela respetiva etiqueta. Na biblioteca PKCS #11 do Cloud KMS, a etiqueta da chave é 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 > PATH_TO_CERTIFICATE

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, use pkcs11:object com o nome da chave. Para usar uma versão específica da chave, use pkcs11:id com o ID de recurso completo da versão da chave.
  • KEY_IDENTIFIER: um identificador da chave. Se estiver a usar o pkcs11:object, use o nome da chave, por exemplo, KEY_NAME. Se estiver a usar pkcs11: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/KEY_NAME/cryptoKeyVersions/KEY_VERSION.
  • PATH_TO_CERTIFICATE: o caminho onde quer guardar o ficheiro do certificado.

Se este comando falhar, 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-----

Configure o servidor Apache

  1. Crie um diretório em /etc/apache2 para armazenar o seu certificado autossinado:

    sudo mkdir /etc/apache2/ssl
    sudo mv ca.cert /etc/apache2/ssl
    
  2. Edite os ficheiros de configuração do anfitrião virtual 000-default.conf localizados em /etc/apache2/sites-available para fornecer o caminho do ficheiro de certificado e certifique-se de que o SSLEngine está ativado.

    Segue-se um exemplo de configuração de escuta na 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. Certifique-se de que o Apache exporta as variáveis de ambiente corretamente adicionando-as ao ficheiro /etc/apache2/envvars através do editor de texto que preferir. Pode ter de editar o ficheiro como administrador com o comando sudo. Adicione as seguintes linhas ao final do ficheiro:

    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
    

    Substitua o seguinte:

    • PATH_TO_LIBKMSP11: o caminho para libkmsp11.so.
    • PATH_TO_PKCS11_CONFIG: o caminho para pkcs11-config.yaml.

    GRPC_ENABLE_FORK_SUPPORT é necessário para que o gRPC inclua suporte para ramificações e execute corretamente a biblioteca PKCS #11 do Cloud KMS como parte do servidor Apache.

    Se quiser autenticar através de uma chave de conta de serviço, também tem de exportar um valor para a variável de ambiente GOOGLE_APPLICATION_CREDENTIALS.

Execute o servidor

Ative o módulo SSL do Apache, ative a configuração do anfitrião virtual e adicione uma página Web de teste na pasta 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

Reinicie o servidor Apache e teste com curl se a configuração funciona como esperado. A flag --insecure é necessária para ignorar as verificações de certificados autossinados.

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

Se encontrar erros, o registo de erros do Apache é um bom ponto de partida para ver o que correu mal. Os problemas de autenticação são uma origem comum de erros. Se vir erros PERMISSION_DENIED, certifique-se de que tem a autenticação completa e que o ficheiro de credenciais tem as autorizações corretas. Para garantir que tem a autenticação completa, execute o seguinte comando:

gcloud auth application-default login

Para confirmar que a autenticação foi bem-sucedida, o resultado deve incluir a linha Credentials saved to file: [/path/to/credentials.json].