-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Setup mTLS and TLS with GCP Application Load Balancer (EXTERNAL_MANAG…
…ED) (#1444) * Setup mTLS and TLS with GCP application load balancer * Update README.md --------- Co-authored-by: Andrew Gold <41129777+agold-rh@users.noreply.github.com>
- Loading branch information
1 parent
c8635a5
commit 659e7fc
Showing
8 changed files
with
399 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
## Setup mTLS and TLS with GCP Application Load Balancer (EXTERNAL_MANAGED) | ||
|
||
### OVERVIEW: | ||
|
||
mTLS with GCP Application Load Balancer enhances security by requiring clients to authenticate themselves with certificates, in addition to the server authenticating itself to the client. This provides mutual authentication, ensuring that both parties are who they claim to be. | ||
|
||
To implement mTLS with GCP Application Load Balancer, you need to create a trust config resource that contains the root and intermediate certificates used to validate client certificates. You then create a client authentication resource that specifies the client validation mode and associates it with the trust config. Finally, you attach the client authentication resource to your load balancer's HTTPS frontend. | ||
|
||
mTLS with GCP Application Load Balancer supports various features, including custom mTLS headers that can be used to pass information about the mTLS connection to backend services. It also supports different client validation modes, allowing you to choose how to handle invalid or missing client certificates. | ||
|
||
### [Create a VPC native cluster:](https://cloud.google.com/kubernetes-engine/docs/how-to/standalone-neg#create-cluster) | ||
|
||
```bash | ||
gcloud container clusters create neg-demo-cluster \ | ||
--create-subnetwork="" \ | ||
--network=default \ | ||
--zone=us-central1-a | ||
``` | ||
### Connect to GKE cluster: | ||
```bash | ||
gcloud container clusters get-credentials neg-demo-cluster --zone us-central1-a --project <GCP_PROJECT_ID> | ||
``` | ||
### Deploy the Sample application deployment and service(along with [NEG](https://cloud.google.com/load-balancing/docs/negs/zonal-neg-concepts)): | ||
```bash | ||
kubectl apply -f manifests/deploy.yaml | ||
``` | ||
|
||
### Generate the self signed certificates | ||
|
||
A detailed steps to generate the self signed certificates are documented in the [Medium Article.](https://medium.com/google-cloud/tls-and-mtls-connection-with-gcp-application-load-balancer-6e2cd5189707) | ||
|
||
After executing the steps from the above article, you should have a root, 2 intermediate, server and client certificates generated. Copy all the generated certificates along with the following unencrypted server keys in the `terraform/certs` directory. | ||
|
||
Decrypt the server key file using the passphrase used in previous steps: | ||
```bash | ||
openssl rsa -in server.key -out un-server.key | ||
``` | ||
|
||
### Deploy the GCP Global application load balancer with both tls and mTLS configuration | ||
|
||
#### Update the following terraform local variables in `terraform/main.tf`: | ||
* project_id: GCP Project ID where the GCP load balancer will be deployed. | ||
* vpc_networks: List of VPC network where the load balancer backend exists. The additional firewall rules required by load balancer are added using this input variable. | ||
* vpc_projects: The GCP project ID where the VPC network exists. | ||
|
||
#### Initialize the terraform directory | ||
|
||
```bash | ||
terraform init | ||
``` | ||
|
||
#### Generate the terraform plan | ||
```bash | ||
terraform plan | ||
``` | ||
|
||
#### Apply the terraform plan to provision all GCP resources. | ||
|
||
```bash | ||
terraform apply | ||
``` | ||
|
||
After executing the terraform script, we should have the GCP application load balancer provisioned with 2 forwarding rules: | ||
* One forwarding rule is used to send the tls connection. | ||
 | ||
|
||
|
||
* Another forwarding rule is used to send the mtls connection to load balancer. | ||
 | ||
|
||
|
||
#### Test the tls connection to the GCP Load balancer by sending the following curl request | ||
|
||
```bash | ||
curl -v --cacert int2.cert --connect-to test-domain.com:443:34.149.90.136:443 https://test-domain.com | ||
``` | ||
<img width="1098" alt="Screenshot 2025-02-06 at 10 46 25 PM" src="https://github.com/user-attachments/assets/d392214c-da93-4198-be47-eb2e0ac3315f" /> | ||
The GCP application load balancer is also configured to send the custom headers of the mtls request back to the backend service which are seen in the curl request output of the mTLS connection, since the above request was tls connection, the custom headers are empty in the above tls connection response. | ||
|
||
|
||
#### Test the mTLS connection to the GCP application load balancer by sending the following request | ||
|
||
```bash | ||
curl -v --cacert int2.cert --key client.key --cert client.cert --connect-to test-domain.com:443:34.8.115.55:443 https://test-domain.com | ||
``` | ||
<img width="1204" alt="Screenshot 2025-02-06 at 10 49 07 PM" src="https://github.com/user-attachments/assets/24f69993-46a9-4329-bb8f-6609c7d2680f" /> | ||
We see the mTLS custom headers in above mtls connection response are populated automatically by load balancer frontend and sent back to the backend server after a successful mTLS connection is established. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# Copyright 2025 Google Inc. All Rights Reserved. | ||
|
||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
|
||
apiVersion: v1 | ||
kind: Namespace | ||
metadata: | ||
name: mtls-demo | ||
--- | ||
apiVersion: apps/v1 | ||
kind: Deployment | ||
metadata: | ||
name: echo | ||
namespace: mtls-demo | ||
spec: | ||
selector: | ||
matchLabels: | ||
app: echo | ||
template: | ||
metadata: | ||
labels: | ||
app: echo | ||
spec: | ||
containers: | ||
- name: echo | ||
image: gcr.io/istio-testing/app:latest | ||
args: | ||
- --tcp=7070 | ||
- --tcp=7071 | ||
- --port=8080 | ||
- --grpc=9090 | ||
- --server-first=7071 | ||
--- | ||
apiVersion: v1 | ||
kind: Service | ||
metadata: | ||
name: echo | ||
namespace: mtls-demo | ||
annotations: | ||
cloud.google.com/neg: '{"exposed_ports": {"8080":{"name": "mtls-demo-neg"}}}' | ||
spec: | ||
selector: | ||
app: echo | ||
ports: | ||
- name: http | ||
port: 8080 | ||
- name: tcp | ||
port: 7070 | ||
- name: tcp-sf | ||
port: 7071 | ||
- name: grpc | ||
port: 9090 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
[req] | ||
default_bits = 2048 | ||
req_extensions = extension_requirements | ||
distinguished_name = dn_requirements | ||
prompt = no | ||
|
||
[extension_requirements] | ||
basicConstraints = CA:FALSE | ||
keyUsage = nonRepudiation, digitalSignature, keyEncipherment | ||
extendedKeyUsage = serverAuth,clientAuth | ||
subjectAltName = DNS:test-client.com,DNS:www.test-client.com | ||
|
||
[dn_requirements] | ||
countryName = IN | ||
stateOrProvinceName = Telangana | ||
localityName = Hyderabad | ||
0.organizationName = Google | ||
organizationalUnitName = QA | ||
commonName = test-client |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
[req] | ||
default_bits = 2048 | ||
req_extensions = extension_requirements | ||
distinguished_name = dn_requirements | ||
prompt = no | ||
|
||
[extension_requirements] | ||
basicConstraints = critical,CA:TRUE | ||
keyUsage = keyCertSign | ||
|
||
[dn_requirements] | ||
countryName = IN | ||
stateOrProvinceName = Telangana | ||
localityName = Hyderabad | ||
0.organizationName = Google | ||
organizationalUnitName = IT | ||
commonName = int |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
[req] | ||
default_bits = 2048 | ||
req_extensions = extension_requirements | ||
distinguished_name = dn_requirements | ||
prompt = no | ||
|
||
[extension_requirements] | ||
basicConstraints = critical,CA:TRUE | ||
keyUsage = keyCertSign | ||
|
||
[dn_requirements] | ||
countryName = IN | ||
stateOrProvinceName = Telangana | ||
localityName = Hyderabad | ||
0.organizationName = Google | ||
organizationalUnitName = IT | ||
commonName = int2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
[req] | ||
default_bits = 2048 | ||
req_extensions = extension_requirements | ||
distinguished_name = dn_requirements | ||
prompt = no | ||
|
||
[extension_requirements] | ||
basicConstraints = critical,CA:TRUE | ||
keyUsage = keyCertSign | ||
|
||
[dn_requirements] | ||
countryName = IN | ||
stateOrProvinceName = Telangana | ||
localityName = Hyderabad | ||
0.organizationName = Google | ||
organizationalUnitName = IT | ||
commonName = root |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
[req] | ||
default_bits = 2048 | ||
req_extensions = extension_requirements | ||
distinguished_name = dn_requirements | ||
prompt = no | ||
|
||
[extension_requirements] | ||
basicConstraints = CA:FALSE | ||
keyUsage = nonRepudiation, digitalSignature, keyEncipherment | ||
extendedKeyUsage = serverAuth,clientAuth | ||
subjectAltName = DNS:test-domain.com,DNS:www.test-domain.com | ||
|
||
[dn_requirements] | ||
countryName = IN | ||
stateOrProvinceName = Telangana | ||
localityName = Hyderabad | ||
0.organizationName = Google | ||
organizationalUnitName = DEV | ||
commonName = test-domain.com |
Oops, something went wrong.