This page provides instructions for creating a root certificate and
a signed intermediate certificate, and then uploading those certificates
to a Certificate Manager TrustConfig
resource. If you have existing
certificates to upload, skip the steps that create new certificates.
You also create the network security resources required for configuring mutual TLS (mTLS) for Application Load Balancers. The instructions use OpenSSL to create the root and intermediate certificates.
Before you begin
- Review the Mutual TLS overview.
- Review the Manage trust configs.
Install the Google Cloud CLI. For a complete overview of the tool, see the gcloud CLI overview. You can find commands related to load balancing in the API and gcloud CLI reference.
If you haven't run the gcloud CLI previously, first run the
gcloud init
command to authenticate.Enable APIs: Compute Engine API, Certificate Manager API, Network Security, and Network Services API.
Set your project.
gcloud
gcloud config set project PROJECT_ID
Permissions
To get the permissions that you need to complete this guide, ask your administrator to grant you the following IAM roles on the project:
-
To create load balancer resources such as
TargetHTTPSProxy
: Compute Load Balancer Admin (roles/compute.loadBalancerAdmin
) -
To use Certificate Manager resources:
Certificate Manager Owner (
roles/certificatemanager.owner
) -
To create security and networking components:
Compute Network Admin (
roles/compute.networkAdmin
) and Compute Security Admin (roles/compute.securityAdmin
) -
To create a project (optional):
Project Creator (
roles/resourcemanager.projectCreator
)
For more information about granting roles, see Manage access.
You might also be able to get the required permissions through custom roles or other predefined roles.
Generate a key and signed certificates
This section uses openssl
commands to create root and intermediate
certificates.
Use the following commands to generate a root certificate and a signed
intermediate certificate with valid keyUsage
and extendedKeyUsage
fields.
Create a sample
example.cnf
file with the minimum configuration required to create valid signing certificates. You can edit this file if you want to set any additional fields on these certificates.cat > example.cnf << EOF [req] distinguished_name = empty_distinguished_name [empty_distinguished_name] # Kept empty to allow setting via -subj command line arg. [ca_exts] basicConstraints=critical,CA:TRUE keyUsage=keyCertSign extendedKeyUsage=clientAuth EOF
Create the root certificate.
openssl req -x509 \ -new -sha256 -newkey rsa:2048 -nodes \ -days 3650 -subj '/CN=root' \ -config example.cnf \ -extensions ca_exts \ -keyout root.key -out root.cert
Create the signing request for the intermediate certificate.
openssl req \ -new -sha256 -newkey rsa:2048 -nodes \ -subj '/CN=int' \ -config example.cnf \ -extensions ca_exts \ -keyout int.key -out int.req
Create the intermediate certificate.
openssl x509 -req \ -CAkey root.key -CA root.cert \ -set_serial 1 \ -days 3650 \ -extfile example.cnf \ -extensions ca_exts \ -in int.req -out int.cert
Generate a certificate and add it to an allowlist
This section uses openssl
commands to create a sample certificate and add it
to an allowlist.
Use the following commands to generate a certificate and add it to an allowlist.
openssl req -x509 \
-new -sha256 -newkey rsa:2048 -nodes \
-days 3650 -subj '/CN=localhost' \
-keyout allowlisted.key -out allowlisted.cert
Format the certificates
To include new or existing certificates in a TrustStore
, format the
certificates into a single line
and store them in environment variables, so that they can be read into the YAML
file. Use the following commands to format the certificates and store them in
environment variables:
export ROOT_CERT=$(cat root.cert | sed 's/^[ ]*//g' | tr '\n' $ | sed 's/\$/\\n/g')
export INTERMEDIATE_CERT=$(cat int.cert | sed 's/^[ ]*//g' | tr '\n' $ | sed 's/\$/\\n/g')
To include new or existing certificates that are added to an allowlist in a
trust config, format the certificates into a single line
and store them in environment variables, so that they can be read into the YAML
file. For certificates that are on an allowlist, use the following command to
format the certificates into a single line and store them in the
ALLOWLISTED_CERT
environment variable.
export ALLOWLISTED_CERT=$(cat allowlisted.cert | sed 's/^[ ]*//g' | tr '\n' $ | sed 's/\$/\\n/g')
Create a TrustConfig resource
Create a Certificate Manager TrustConfig
resource
that represents your PKI. This example TrustConfig
resource contains a
trust store with two trust anchors and two intermediate CA certificates.
It reads the certificate content from
the environment variables created in the previous
Format the certificates step.
To create a trust store with additional trust anchors or intermediate CA
certificates, add pemCertificate
rows in the appropriate section. If you have
fewer trust anchors or intermediate CA certificates, remove the unneeded
lines.
This example TrustConfig
resource contains a certificate that is added to an
allowlist. You can specify multiple certificates in an allowlist by using
multiple instances of the pemCertificate
field.
In the following steps, replace TRUST_CONFIG_NAME
with the name of the TrustConfig
resource:
To create the
trust_config.yaml
file with a trust store, use the following command:cat << EOF > trust_config.yaml trustStores: - trustAnchors: - pemCertificate: "${ROOT_CERT?}" - pemCertificate: "${ROOT_CERT_2?}" intermediateCas: - pemCertificate: "${INTERMEDIATE_CERT?}" - pemCertificate: "${INTERMEDIATE_CERT_2?}" EOF
Optional: To create the
trust_config.yaml
file with a certificate that is added to an allowlist, use the following command:cat << EOF > trust_config.yaml allowlistedCertificates: - pemCertificate: "${ALLOWLISTED_CERT?}" EOF
To create the Certificate Manager
TrustConfig
resources, use thegcloud certificate-manager trust-configs import
command:global
For external Application Load Balancers and cross-region internal Application Load Balancers, use this command:
gcloud certificate-manager trust-configs import TRUST_CONFIG_NAME \ --source=trust_config.yaml
regional
For regional external Application Load Balancers and regional internal Application Load Balancers, use this command:
gcloud certificate-manager trust-configs import TRUST_CONFIG_NAME \ --source=trust_config.yaml \ --location=REGION
Create the network security resources
A server TLS policy (ServerTLSPolicy
network security resource) lets you
specify the server-side TLS mode and the TrustConfig
resource to use
when validating client certificates. When the client presents an invalid
certificate or no certificate to the load balancer, the
clientValidationMode
specifies how the client connection is handled.
- When the
clientValidationMode
is set toALLOW_INVALID_OR_MISSING_CLIENT_CERT
, all requests are passed to the backend even if the validation fails or the client certificate is missing. - When the
clientValidationMode
is set toREJECT_INVALID
, only requests that supply a client certificate that can be validated against aTrustConfig
resource are passed to the backend.
To create the ServerTLSPolicy
resource, complete the following steps:
Based on how you want to handle the connection, select one of the following options.
In the following steps, replace
SERVER_TLS_POLICY_NAME
with the name of the server TLS policy, and replacePROJECT_ID
with the ID of your Google Cloud project.Option 1:
clientValidationMode
is set toALLOW_INVALID_OR_MISSING_CLIENT_CERT
.To create the
server_tls_policy.yaml
file, use the following command:global
For external Application Load Balancers and cross-region internal Application Load Balancers, use the command:
cat << EOF > server_tls_policy.yaml name: SERVER_TLS_POLICY_NAME mtlsPolicy: clientValidationMode: ALLOW_INVALID_OR_MISSING_CLIENT_CERT clientValidationTrustConfig: projects/PROJECT_ID/locations/global/trustConfigs/TRUST_CONFIG_NAME EOF
regional
For regional external Application Load Balancers and regional internal Application Load Balancers, use the command:
cat << EOF > server_tls_policy.yaml name: SERVER_TLS_POLICY_NAME mtlsPolicy: clientValidationMode: ALLOW_INVALID_OR_MISSING_CLIENT_CERT clientValidationTrustConfig: projects/PROJECT_ID/locations/REGION/trustConfigs/TRUST_CONFIG_NAME EOF
Option 2:
clientValidationMode
is set toREJECT_INVALID
.To create the
server_tls_policy.yaml
file, use the following command:global
For external Application Load Balancers and cross-region internal Application Load Balancers, use the command:
cat << EOF > server_tls_policy.yaml name: SERVER_TLS_POLICY_NAME mtlsPolicy: clientValidationMode: REJECT_INVALID clientValidationTrustConfig: projects/PROJECT_ID/locations/global/trustConfigs/TRUST_CONFIG_NAME EOF
regional
For regional external Application Load Balancers and regional internal Application Load Balancers, use the command:
cat << EOF > server_tls_policy.yaml name: SERVER_TLS_POLICY_NAME mtlsPolicy: clientValidationMode: REJECT_INVALID clientValidationTrustConfig: projects/PROJECT_ID/locations/REGION/trustConfigs/TRUST_CONFIG_NAME EOF
To create the
ServerTlsPolicy
resource, use thegcloud network-security server-tls-policies import
command:global
For external Application Load Balancers and cross-region internal Application Load Balancers, use the command:
gcloud network-security server-tls-policies import SERVER_TLS_POLICY_NAME \ --source=server_tls_policy.yaml \ --location=global
regional
For regional external Application Load Balancers and regional internal Application Load Balancers, use the command:
gcloud network-security server-tls-policies import SERVER_TLS_POLICY_NAME \ --source=server_tls_policy.yaml \ --location=REGION
For more information, see MTLS client validation modes.
Sign a client key with the intermediate certificate
This section provides an additional configuration option to generate a leaf
certificate.
If you have already created a TrustConfig resource by using
intermediate certificates (int.cert
and int.key
), use the following
instructions:
Create a client key configuration file.
cat > client.config << EOF [req] default_bits = 2048 req_extensions = extension_requirements distinguished_name = dn_requirements prompt = no [extension_requirements] basicConstraints = critical, CA:FALSE keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage = clientAuth [dn_requirements] countryName = US stateOrProvinceName = California localityName = San Francisco 0.organizationName = example organizationalUnitName = test commonName = test.example.com emailAddress = test@example.com EOF
If you want to have a SPIFFE identity attached:
Add a
subjectAltName
to your[extension_requirements]
section as follows:subjectAltName = @sans_list
Add a new section at the bottom of the
client.config
file with the following:[sans_list] URI.1 = spiffe://example.com/test-identity
Sign the key.
openssl req -new -keyout client.key -out client.csr -config client.config openssl x509 -req -in client.csr -out client.cert -extfile client.config -extensions extension_requirements -days 365 -CA int.cert -CAkey int.key
To test send a
curl
request to the load balancer's IP address.curl -v -k --key client.key --cert client.cert https://IP_ADDRESS
Replace IP_ADDRESS with the load balancer's IP address.
What's next
- Set up mutual TLS for a global external Application Load Balancer
- Set up mutual TLS for a classic Application Load Balancer
- Set up mutual TLS for an internal Application Load Balancer
- Set up mutual TLS for a regional external Application Load Balancer
- Set up mutual TLS with a private CA