Use a Cloud HSM key to serve Apache traffic

This guide provides instructions for setting up an Apache server to use a Cloud HSM key for TLS signing on Debian 11 (Bullseye). You might need to modify these commands to work with your OS or Linux distribution.

You can find a Terraform-based blueprint version of this tutorial in the kms-solutions GitHub repository .

Before you begin

As a prerequisite, complete the configuration documented in OpenSSL Setup .

Once OpenSSL setup is complete, ensure that a recent version of Apache is installed:

 sudo apt-get update
sudo apt-get install apache2 

Configuration

Create a Cloud KMS-hosted signing key

Create a Cloud KMS EC-P256-SHA256 signing key in your Google Cloud project, in the key ring that you previously configured for 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" 

Create a self-signed certificate with OpenSSL

Generate a self-signed certificate with the Cloud KMS-hosted signing key. You can use OpenSSL to use a PKCS #11 URI instead of a file path and identify the key by its label. In the Cloud KMS PKCS #11 library, the key label is the CryptoKey name.

 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 
 

Replace the following:

  • CERTIFICATE_NAME : a name for the certificate.
  • DIGEST_FLAG : the digest algorithm used by the asymmetric signing key. Use -sha256 , -sha384 , or -sha512 depending on the key.
  • PKCS_KEY_TYPE : the type of identifier used to identify the key. To use the latest key version, use pkcs11:object with the key's name. To use a specific key version, use pkcs11:id with the full resource ID of the key version.
  • KEY_IDENTIFIER : an identifier for the key. If you're using pkcs11:object , use the key's name—for example, KEY_NAME . If you're using pkcs11:id , use the full resource ID of the key or key version—for example, projects/ PROJECT_ID /locations/ LOCATION /keyRings/ KEY_RING /cryptoKeys/ KEY_NAME /cryptoKeyVersions/ KEY_VERSION .
  • PATH_TO_CERTIFICATE : the path where you want to save the certificate file.

If this command fails, PKCS11_MODULE_PATH might have been set incorrectly, or you might not have the right permissions to use the Cloud KMS signing key.

You should now have a certificate that looks like this:

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

Set up the Apache server

  1. Create a directory in /etc/apache2 to store your self-signed certificate in:

     sudo mkdir /etc/apache2/ssl
    sudo mv ca.cert /etc/apache2/ssl 
    
  2. Edit the 000-default.conf virtual host configuration files located in /etc/apache2/sites-available to provide the certificate file path and ensure that the SSLEngine is on.

    Here is a sample configuration listening on port 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. Ensure Apache exports the environment variables correctly by adding them to the /etc/apache2/envvars file using your text editor of choice. You might need to edit the file as root using sudo . Add the following lines to the end of the 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 
     
    

    Replace the following:

    • PATH_TO_LIBKMSP11 : the path to libkmsp11.so .
    • PATH_TO_PKCS11_CONFIG : the path to pkcs11-config.yaml .

    GRPC_ENABLE_FORK_SUPPORT is needed for gRPC to include fork support and correctly run the Cloud KMS PKCS #11 library as part of the Apache server.

    If you want to authenticate using a service account key, you must also export a value for the GOOGLE_APPLICATION_CREDENTIALS environment variable.

Run your server

Enable the Apache SSL module, enable the virtualhost configuration, and add a test web page in your DocumentRoot folder:

  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 
 

Restart your Apache server and test with curl that the configuration works as expected. The --insecure flag is needed to ignore self-signed certificate checks.

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

If you encounter any errors, the Apache error log is a good starting place to see what went wrong. Authentication issues are a common source of errors. If you see PERMISSION_DENIED errors, make sure that you are fully authenticated and that the credentials file has the right permissions. To make sure you are fully authenticated, run the following command:

 gcloud  
auth  
application-default  
login 

To confirm that authentication was successful, the output should include the line Credentials saved to file: [/path/to/credentials.json] .

Create a Mobile Website
View Site in Mobile | Classic
Share by: