Use a Cloud HSM key to serve Apache traffic Stay organized with collections Save and categorize content based on your preferences.
This guide provides instructions for setting up an Apache server to use aCloud HSM key for TLS signing on Debian 11 (Bullseye). You might need tomodify these commands to work with your OS or Linux distribution.
Note: TLS termination with Apache is only supported for Elliptic CurveDigital Signature Algorithm (ECDSA) keys.You can find a Terraform-based blueprint version of this tutorial in thekms-solutions GitHub repository.
Before you begin
As a prerequisite, complete the configuration documented inOpenSSL Setup.
Once OpenSSL setup is complete, ensure that a recent version of Apache isinstalled:
sudo apt-get updatesudo apt-get install apache2apache2-2.4.42 andlater. If you are using an earlier version, you must upgrade theapache2package with the command above, or install from non-stable sources.For Debian Buster:
sudo apt install -t buster-backports apache2Configuration
Create a Cloud KMS-hosted signing key
Create a Cloud KMSEC-P256-SHA256 signing key in yourGoogle Cloud project, in the key ring that you previously configuredfor 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-hostedsigning key. You can use OpenSSL to use a PKCS #11 URI instead of a file pathand identify the key by its label. In the Cloud KMS PKCS #11library, the key label is the CryptoKey name.
openssl req -new -x509 -days 3650 -subj '/CN=CERTIFICATE_NAME/' \DIGEST_FLAG -engine pkcs11 -keyform engine \ -keyPKCS_KEY_TYPE=KEY_IDENTIFIER >PATH_TO_CERTIFICATEReplace the following:
CERTIFICATE_NAME: a name for the certificate.DIGEST_FLAG: the digest algorithm used by the asymmetric signingkey. Use-sha256,-sha384, or-sha512depending on the key.PKCS_KEY_TYPE: the type of identifier used to identify the key.To use the latest key version, usepkcs11:objectwith the key's name. Touse a specific key version, usepkcs11:idwith the full resource ID of thekey version.KEY_IDENTIFIER: an identifier for the key. If you're usingpkcs11:object, use the key's name—for example,KEY_NAME.If you're usingpkcs11:id, use the full resource ID of the key or keyversion—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 certificatefile.
If this command fails,PKCS11_MODULE_PATH might have been set incorrectly, oryou might not have the right permissions to use the Cloud KMSsigning key.
You should now have a certificate that looks like this:
-----BEGIN CERTIFICATE-----.........-----END CERTIFICATE-----Set up the Apache server
Create a directory in
/etc/apache2to store your self-signedcertificate in:sudo mkdir /etc/apache2/sslsudo mv ca.cert /etc/apache2/sslEdit the
000-default.confvirtual host configuration files located in/etc/apache2/sites-availableto provide the certificate file path andensure that the SSLEngine is on.Here is a sample configuration listening on port 443:
<VirtualHost*:443>ServerAdminwebmaster@localhostDocumentRoot/var/www/htmlErrorLog${APACHE_LOG_DIR}/error.logCustomLog${APACHE_LOG_DIR}/access.logcombinedSSLEngineonSSLCertificateFile/etc/apache2/ssl/ca.certSSLCertificateKeyFile"PKCS_KEY_TYPE=KEY_IDENTIFIER"</VirtualHost>Ensure Apache exports the environment variables correctly by adding them tothe
/etc/apache2/envvarsfile using your text editor of choice. You mightneed to edit the file as root usingsudo. Add the following lines to theend of the file:exportPKCS11_MODULE_PATH="<var>PATH_TO_LIBKMSP11</var>"exportKMS_PKCS11_CONFIG="<var>PATH_TO_PKCS11_CONFIG</var>"exportGRPC_ENABLE_FORK_SUPPORT=1Replace the following:
PATH_TO_LIBKMSP11: the path tolibkmsp11.so.PATH_TO_PKCS11_CONFIG: the path topkcs11-config.yaml.
GRPC_ENABLE_FORK_SUPPORTis needed for gRPC to include fork support andcorrectly run the Cloud KMS PKCS #11 library as part of the Apacheserver.If you want to authenticate using a service account key, you must alsoexport a value for the
GOOGLE_APPLICATION_CREDENTIALSenvironmentvariable.
Run your server
Enable the Apache SSL module, enable the virtualhost configuration, and add atest web page in your DocumentRoot folder:
sudoa2enmodsslsudoa2ensite000-default.confecho'<!doctype html><html><body><h1>Hello World!</h1></body></html>'|\sudotee/var/www/html/index.htmlRestart your Apache server and test withcurl that the configuration works asexpected. The--insecure flag is needed to ignore self-signed certificatechecks.
sudo systemctl restart apache2curl -v --insecure https://127.0.0.1If you encounter any errors, the Apache error log is a good starting place tosee what went wrong. Authentication issues are a common source of errors. If youseePERMISSION_DENIED errors, make sure that you are fully authenticated andthat the credentials file has the right permissions. To make sure you are fullyauthenticated, run the following command:
gcloudauthapplication-defaultloginTo confirm that authentication was successful, the output should include thelineCredentials saved to file: [/path/to/credentials.json].
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2026-02-19 UTC.