Reputation: 11
I have deployed a GCP load balancer, which proxies the requests to the backend GCP MIG vms(which they run docker container with nginx proxy, where it proxies the request to a java application). In the initial phase, tls was disabled. Although, now I want to go to production, i must enable mtls. While having tls, i have tested and it is working, but enforcing mTLS, it is not working and i am getting the 400 ERROR, as it seems that GCP load balancer doesn't know about client's root CA certificate. To mention here, i have created a ssl policy and attached it, and also i have uploaded the server's Certificate and private key on the target proxy. How can I make aware about the client's root CA?
curl -v --cert client_auth_webserver.crt --key client_auth_webserver.key https://test.mytest.com/v1/licenseInfo
* Trying 35.201.71.87:443...
* Connected to test.mytest.com (35.201.71.87) port 443 (#0)
* ALPN: offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
* CAfile: /etc/ssl/cert.pem
* CApath: none
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256
* ALPN: server accepted h2
* Server certificate:
* subject: CN=test.mytest.com
* start date: May 28 05:44:13 2024 GMT
* expire date: Aug 26 05:44:12 2024 GMT
* subjectAltName: host "test.mytest.com" matched cert's "test.mytest.com"
* issuer: C=US; O=Let's Encrypt; CN=R3
* SSL certificate verify ok.
* using HTTP/2
* h2 [:method: GET]
* h2 [:scheme: https]
* h2 [:authority: test.myest.com]
* h2 [:path: /v1/licenseInfo]
* h2 [user-agent: curl/8.1.2]
* h2 [accept: */*]
* Using Stream ID: 1 (easy handle 0x15380a800)
> GET /v1/licenseInfo HTTP/2
> Host: us-deployment-test.cloudshsm.com
> User-Agent: curl/8.1.2
> Accept: */*
>
< HTTP/2 400
< server: nginx/1.25.5
< date: Wed, 29 May 2024 08:03:24 GMT
< content-type: text/html
< content-length: 237
< strict-transport-security: max-age=31536000; includeSubDomains
< via: 1.1 google
< alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
<
<html>
<head><title>400 No required SSL certificate was sent</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>No required SSL certificate was sent</center>
<hr><center>nginx/1.25.5</center>
</body>
</html>
* Connection #0 to host test.mytest.com left intact
i have tried to add some headers, but no luck
Upvotes: 0
Views: 62
Reputation: 11
Whether someone chooses to use certificates managed by google, or self signed certificates(user-provided certificates), for mtls on gcp https load balancer the key points are the below:
tls termination on the level of the load balancer(that was one of the reasons that fixed my issue, although i had to change the backend architecture, as I had a nginx for the tls termination)
place your server's certificate and private key on the GCP Certificate Manager->CLASSIC CERTIFICATES(it should be used by your load balancer's target proxy)
Add your client's rootCA and intermediateCA on the GCP Certificate Manager->TRUST CONFIGS
a. format the client's certificates: 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')
b. create the trust_config.yaml: cat << EOF > trust_config.yaml trustStores: - trustAnchors: - pemCertificate: "${ROOT_CERT?}" intermediateCas: - pemCertificate: "${INTERMEDIATE_CERT?}" EOF
c. import the client's certificate into the trust_config, based on the file trust_config.yaml:
gcloud certificate-manager trust-configs import TRUST_CONFIG_NAME
--source=trust_config.yaml
prepare the Client Authentication policy for mtls, known as ServerTLSPolicy where you have 2 options available: a. clientValidationMode is set to ALLOW_INVALID_OR_MISSING_CLIENT_CERT: 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
b. clientValidationMode is set to REJECT_INVALID
create the ServerTLSPolicy:
gcloud network-security server-tls-policies import SERVER_TLS_POLICY_NAME --source=server_tls_policy.yaml
--location=global
list all the target HTTPS proxies in your project: gcloud compute target-https-proxies list
export a target HTTPS proxy's configuration to a file:
gcloud compute target-https-proxies export TARGET_HTTPS_PROXY_NAME
--destination=TARGET_PROXY_FILENAME
--region=REGION
attach the ServerTlsPolicy to the target-https-proxy, by appending the resource file TARGET_PROXY_FILENAME: echo "serverTlsPolicy: //networksecurity.googleapis.com/projects/PROJECT_ID/locations/REGION/serverTlsPolicies/SERVER_TLS_POLICY_NAME" >> TARGET_PROXY_FILENAME
import a target HTTPS proxy's configuration from a file:
gcloud compute target-https-proxies import TARGET_HTTPS_PROXY_NAME
--source=TARGET_PROXY_FILENAME
--region=REGION
Upvotes: 1