This document provides instructions for setting up a global external proxy Network Load Balancer with a target SSL proxy and VM instance group backends. Before you start, read External proxy Network Load Balancer overview for information about how these load balancers work.
Setup overview
This example demonstrates how to set up an external proxy Network Load Balancer for a service that exists in two regions: Region A and Region B. You will configure the following:
- Four instances spread across two regions
- Instance groups for holding the instances
- Backend components, which include the following:
- Health check - used to monitor instance health
- Backend service - monitors instance groups and prevents them from exceeding configured usage
- Backends - hold the instance groups
- Frontend components, which include the following:
- An SSL certificate resource. You can use either a self-managed certificate, where you supply your own SSL certificate, or a Google-managed certificate, where Google issues a certificate that is valid for all of your domains. For more information, see Types of SSL certificates.
- The SSL proxy itself with its SSL certificate
- An external static IPv4 address and a forwarding rule that sends user traffic to the proxy
- An external static IPv6 address and a forwarding rule that sends user traffic to the proxy
- A firewall rule that allows traffic from the load balancer and health checker to the instances.
- Optionally, an SSL policy to control the features of SSL that your SSL proxy load balancer negotiates with clients.
After that, you'll test your configuration.
Permissions
To follow this guide, you must be able to create instances and modify a network in a project. You must be either a project owner or editor, or you must have all of the following Compute Engine IAM roles:
Task | Required Role |
---|---|
Create networks, subnets, and load balancer components | Network Admin |
Add and remove firewall rules | Security Admin |
Create instances | Compute Instance Admin |
For more information, see the following guides:
Configure the network and subnets
To create the example network and subnet, follow these steps.
Console
To support both IPv4 and IPv6 traffic, use the following steps:
In the Google Cloud console, go to the VPC networks page.
Click Create VPC network.
Enter a Name for the network.
Optional: If you want to configure internal IPv6 address ranges on subnets in this network, complete these steps:
- For VPC network ULA internal IPv6 range, select Enabled.
For Allocate internal IPv6 range, select Automatically or Manually.
If you select Manually, enter a
/48
range from within thefd20::/20
range. If the range is in use, you are prompted to provide a different range.
For the Subnet creation mode, choose Custom.
In the New subnet section, configure the following fields:
- In the Name field, provide a name for the subnet.
- In the Region field, select a region.
- For IP stack type, select IPv4 and IPv6 (dual-stack).
In the IP address range field, enter an IP address range. This is the primary IPv4 range for the subnet.
Although you can configure an IPv4 range of addresses for the subnet, you cannot choose the range of the IPv6 addresses for the subnet. Google provides a fixed size (
/64
) IPv6 CIDR block.For IPv6 access type, select External.
Click Done.
To add a subnet in a different region, click Add subnet and repeat the previous steps.
Click Create.
To support IPv4 traffic only, use the following steps:
In the Google Cloud console, go to the VPC networks page.
Click Create VPC network.
In the Name field, enter a name for the network.
For the Subnet creation mode, choose Custom.
In the New subnet section, configure the following:
- In the Name field, provide a name for the subnet.
- In the Region field, select a region.
- For IP stack type, select IPv4 (single-stack).
- In the IP address range field, enter the primary IPv4 range for the subnet.
Click Done.
To add a subnet in a different region, click Add subnet and repeat the previous steps.
Click Create.
gcloud
Create the custom mode VPC network:
gcloud compute networks update NETWORK \ [ --enable-ula-internal-ipv6 [ --internal-ipv6-range=ULA_IPV6_RANGE ]] \ --switch-to-custom-subnet-mode
Within the network, create a subnet for backends.
For IPv4 and IPv6 traffic, use the following command to update a subnet:
gcloud compute networks subnets update SUBNET \ --stack-type=IPV4_IPv6 \ --ipv6-access-type=EXTERNAL \ --network=NETWORK \ --region=REGION_A
gcloud compute networks subnets update SUBNET_B \ --stack-type=IPV4_IPv6 \ --ipv6-access-type=EXTERNAL \ --network=NETWORK \ --region=REGION_B
For IPv4 traffic only, use the following command:
gcloud compute networks subnets update SUBNET \ --network=NETWORK \ --stack-type=IPV4_ONLY \ --range=10.1.2.0/24 \ --region=REGION_A
gcloud compute networks subnets update SUBNET_B \ --stack-type=IPV4_ONLY \ --ipv6-access-type=EXTERNAL \ --network=NETWORK \ --region=REGION_B
Replace the following:
NETWORK
: a name for the VPC networkULA_IPV6_RANGE
: a/48
prefix from within thefd20::/20
range used by Google for internal IPv6 subnet ranges. If you don't use the--internal-ipv6-range
flag, Google selects a/48
prefix for the networkSUBNET
: a name for the subnet
REGION_A
orREGION_B
: the name of the region
Configure instances and instance groups
This section shows how to create instances and instance groups, then add the instances to the instance groups. A production system would normally use managed instance groups based on instance templates, but this setup is quicker for initial testing.
Create instances
Create these instances with the tag ssl-lb
, which the firewall rule will use
later.
Console
Create instances
In the Google Cloud console, go to the VM instances page.
Click Create instance.
Set Name to
vm-a1
.Set the Zone to ZONE_A.
Click Advanced options.
Click Networking and configure the following field:
- In the Network tags field, enter
ssl-lb
andallow-health-check-ipv6
.
- In the Network tags field, enter
In the Network interfaces section, click Edit and make the following changes:
- Select the network.
Select a subnet.
In the IP stack type field, select IPv4 and IPv6 (dual-stack).
Click Done.
Click Management. Enter the following script into the Startup script field.
sudo apt-get update sudo apt-get install apache2 -y sudo a2ensite default-ssl sudo a2enmod ssl sudo service apache2 restart echo '<!doctype html><html><body><h1>vm-a1</h1></body></html>' | sudo tee /var/www/html/index.html
Leave the default values for rest of the fields.
Click Create.
Create
vm-a2
with the same settings, except with Startup script set to the following:sudo apt-get update sudo apt-get install apache2 -y sudo a2ensite default-ssl sudo a2enmod ssl sudo service apache2 restart echo '<!doctype html><html><body><h1>vm-a2</h1></body></html>' | sudo tee /var/www/html/index.html
Create
vm-b1
with the same settings, except with Zone set toZONE_B
and Startup script set to the following:sudo apt-get update sudo apt-get install apache2 -y sudo a2ensite default-ssl sudo a2enmod ssl sudo service apache2 restart echo '<!doctype html><html><body><h1>vm-b1</h1></body></html>' | sudo tee /var/www/html/index.html
Create
vm-b2
with the same settings, except with Zone set toZONE_B
and Startup script set to the following:sudo apt-get update sudo apt-get install apache2 -y sudo a2ensite default-ssl sudo a2enmod ssl sudo service apache2 restart echo '<!doctype html><html><body><h1>vm-b2</h1></body></html>' | sudo tee /var/www/html/index.html
gcloud
Create
vm-a1
in zoneZONE_A
.gcloud compute instances create vm-a1 \ --image-family debian-12 \ --image-project debian-cloud \ --tags ssl-lb \ --zone ZONE_A \ --metadata startup-script="#! /bin/bash sudo apt-get update sudo apt-get install apache2 -y sudo a2ensite default-ssl sudo a2enmod ssl sudo service apache2 restart echo '<!doctype html><html><body><h1>vm-a1</h1></body></html>' | sudo tee /var/www/html/index.html EOF"
Create
vm-a2
in zoneZONE_A
.gcloud compute instances create vm-a2 \ --image-family=debian-12 \ --image-project=debian-cloud \ --tags=ssl-lb \ --zone=ZONE_A \ --metadata=startup-script="#! /bin/bash sudo apt-get update sudo apt-get install apache2 -y sudo a2ensite default-ssl sudo a2enmod ssl sudo service apache2 restart echo '<!doctype html><html><body><h1>vm-a2</h1></body></html>' | sudo tee /var/www/html/index.html EOF"
Create
vm-b1
in zoneZONE_B
.gcloud compute instances create vm-b1 \ --image-family=debian-12 \ --image-project=debian-cloud \ --tags=ssl-lb \ --zone=ZONE_B \ --metadata=startup-script="#! /bin/bash sudo apt-get update sudo apt-get install apache2 -y sudo a2ensite default-ssl sudo a2enmod ssl sudo service apache2 restart echo '<!doctype html><html><body><h1>vm-b1</h1></body></html>' | sudo tee /var/www/html/index.html EOF"
Create
vm-b2
in zoneZONE_B
.gcloud compute instances create vm-b2 \ --image-family=debian-12 \ --image-project=debian-cloud \ --tags=ssl-lb \ --zone=ZONE_B \ --metadata=startup-script="#! /bin/bash sudo apt-get update sudo apt-get install apache2 -y sudo a2ensite default-ssl sudo a2enmod ssl sudo service apache2 restart echo '<!doctype html><html><body><h1>vm-b2</h1></body></html>' | sudo tee /var/www/html/index.html EOF"
Create an instance group for each zone and add instances
Console
In the Google Cloud console, go to the Instance groups page.
Click Create instance group.
Set the Name to
instance-group-a
.Set the Zone to
ZONE_A
.Under Port mapping, click Add port. A load balancer sends traffic to an instance group through a named port. Create a named port to map the incoming traffic to a specific port number.
- Enter a Port name of
ssl-lb
and Port numbers of443
.
- Enter a Port name of
Under Instance definition, click Select existing instances.
From VM instances select
vm-a1
andvm-a2
.Leave other settings as they are.
Click Create.
Repeat steps, but set the following:
- Name:
instance-group-b
- Zone:
ZONE_B
- Port name of
ssl-lb
and Port numbers of443
- Instances: vm-b1 and vm-b2.
- Name:
Confirm that you now have two instance groups, each with two instances.
gcloud
Create the instance-group-a instance group.
gcloud compute instance-groups unmanaged create instance-group-a --zone ZONE_A
Set a named port for the instance group.
gcloud compute instance-groups set-named-ports instance-group-a \ --named-ports=ssl-lb:443 \ --zone=ZONE_A
Add
vm-a1
andvm-a2
to instance-group-agcloud compute instance-groups unmanaged add-instances instance-group-a \ --instances=vm-a1,vm-a2 \ --zone=ZONE_A
Create the
instance-group-b
instance group.gcloud compute instance-groups unmanaged create instance-group-b --zone ZONE_B
Set a named port for the instance group.
gcloud compute instance-groups set-named-ports instance-group-b \ --named-ports=ssl-lb:443 \ --zone=ZONE_B
Add
vm-b1
andvm-b2
to instance-group-bgcloud compute instance-groups unmanaged add-instances instance-group-b \ --instances=vm-b1,vm-b2 \ --zone=ZONE_B
You now have an instance group in each of two regions, each with two instances.
Create a firewall rule for the SSL load balancer
Configure the firewall to allow traffic from the load balancer and health checker to the instances.
Console
In the Google Cloud console, go to the Firewall policies page.
Click Create firewall rule.
In the Name field, enter
allow-ssl-lb-and-health
.Select the network.
Under Targets, select Specified target tags.
Set Target tags to
ssl-lb
.Set Source filter to IPv4 ranges.
Set Source IPv4 ranges to
130.211.0.0/22
and35.191.0.0/16
.Under Protocols and ports, set Specified protocols and ports to
tcp:443
.Click Create.
gcloud
gcloud compute firewall-rules create allow-ssl-lb-and-health \ --source-ranges=130.211.0.0/22,35.191.0.0/16 \ --target-tags=ssl-lb \ --allow=tcp:443
If you are using a Google-managed certificate, confirm that your certificate resource's status is ACTIVE. For more information, see Google-managed SSL certificate resource status.
gcloud compute ssl-certificates list
Create an IPv6 health check firewall rule
Ensure that you have an ingress rule that is applicable to the instances
being load balanced and that allows traffic from the Google Cloud
health checking systems (2600:2d00:1:b029::/64
). This example uses the
target tag allow-health-check-ipv6
to identify the VM instances to which
it applies.
Without this firewall rule, the default deny ingress rule blocks incoming IPv6 traffic to the backend instances.
Console
In the Google Cloud console, go to the Firewall policies page.
To allow IPv6 subnet traffic, click Create firewall rule again and enter the following information:
- Name:
fw-allow-lb-access-ipv6
- Network:
NETWORK
- Priority:
1000
- Direction of traffic: ingress
- Targets: Specified target tags
- Target tags field, enter
allow-health-check-ipv6
- Source filter: IPv6 ranges
- Source IPv6 ranges:
2600:2d00:1:b029::/64
,2600:2d00:1:1::/64
- Protocols and ports: Allow all
- Name:
Click Create.
gcloud
Create the fw-allow-lb-access-ipv6
firewall rule to allow communication
with the subnet:
gcloud compute firewall-rules create fw-allow-lb-access-ipv6 \ --network=NETWORK \ --action=allow \ --direction=ingress \ --target-tags=allow-health-check-ipv6 \ --source-ranges=2600:2d00:1:b029::/64,2600:2d00:1:1::/64 \ --rules=all
Configure the load balancer
Console
Start your configuration
In the Google Cloud console, go to the Load balancing page.
- Click Create load balancer.
- For Type of load balancer, select Network Load Balancer (TCP/UDP/SSL) and click Next.
- For Proxy or passthrough, select Proxy load balancer and click Next.
- For Public facing or internal, select Public facing (external) and click Next.
- For Global or single region deployment, select Best for global workloads and click Next.
- For Load balancer generation, select Global external proxy Network Load Balancer and click Next.
- Click Configure.
Basic configuration
Set the Name to my-ssl-lb
.
Backend configuration
- Click Backend configuration.
- Under Backend type, select Instance groups.
- Set the Protocol to SSL.
- In the IP address selection policy list, select Prefer IPv6.
- For Named port, enter
ssl-lb
. - Accept the default value for the Timeout.
- Leave the Backend type set to Instance groups.
- Configure the first backend:
- Under New backend, select instance group
instance-group-a
. - Set Port numbers to
443
. - Retain the remaining default values.
- Under New backend, select instance group
- Configure the second backend:
- Click Add backend.
- Select instance group
instance-group-b
. - Set Port numbers to
443
. - Click Done.
- Configure the health check:
- Under Health check, select Create health check.
- Set the health check Name to
my-ssl-health-check
. - Under Protocol, select SSL.
- Retain the remaining default values.
- Click Save and continue.
- In the Google Cloud console, verify that there is a check mark next to Backend configuration. If not, double-check that you have completed all of the steps.
Frontend configuration
- Click Frontend configuration.
- Enter a Name of
my-ssl-lb-forwarding-rule
. - Under Protocol, select SSL.
- Under IP address, select Create IP address:
- Enter a Name of
ssl-lb-static-ipv4
. - Click Reserve.
- Enter a Name of
- Under Certificate, select Create a new certificate.
- Enter a Name of
my-ssl-cert
. - If you choose Upload my certificate, complete these steps:
- Paste in your certificate or click Upload to navigate to your certificate file.
- Paste in your private key or click Upload to navigate to your private key file.
- If you choose Create Google managed certificate, enter a
Domain.
- To enter additional domains, click Add Domain.
- Click Create.
- To add certificate resources in addition to the primary SSL certificate resource, click Additional certificates. Then either select another certificate from the Certificates menu or click Create a new certificate and follow the instructions above.
- (Optional) To create an SSL policy:
- Under SSL policy, select Create a policy.
- Enter a Name of
my-ssl-policy
. - For Minimum TLS Version, select TLS 1.0.
- For Profile, select Modern. The Enabled features and Disabled features are displayed.
- Click Save.
- Optional: Turn on Proxy protocol.
- Click Done.
- Verify that there is a green check mark next to Frontend configuration in the Google Cloud console. If not, double-check that you have completed all the previous steps.
- Click Done.
- Add the first forwarding rule:
Review and finalize
- Click Review and finalize.
- Review your load balancer configuration settings.
- Optional: Click Equivalent code to view the REST API request that will be used to create the load balancer.
- Click Create.
gcloud
- Create a health check.
gcloud compute health-checks create ssl my-ssl-health-check --port=443
- Create a backend service.
gcloud beta compute backend-services create my-ssl-lb \ --load-balancing-scheme EXTERNAL_MANAGED \ --global-health-checks \ --protocol=SSL \ --port-name=ssl-lb \ --ip-address-selection-policy=PREFER_IPV6 \ --health-checks=my-ssl-health-check \ --timeout=5m \ --global
Alternatively you can configure unencrypted communication from the load balancer to the instances by using
--protocol=TCP
. Add instance groups to your backend service.
gcloud compute backend-services add-backend my-ssl-lb \ --instance-group=instance-group-a \ --instance-group-zone=ZONE_A \ --balancing-mode=UTILIZATION \ --max-utilization=0.8 \ --global
gcloud compute backend-services add-backend my-ssl-lb \ --instance-group=instance-group-b \ --instance-group-zone=ZONE_B \ --balancing-mode=UTILIZATION \ --max-utilization=0.8 \ --global
- Configure your SSL certificate resource.
If you are using self-managed certificates, you must already have at least one SSL certificate to upload. If you don't, see SSL certificates overview. When you use multiple SSL certificates, you must create them one at a time.
If you are using self-managed SSL certificates and you don't have a private key and signed certificate, you can create and use a self-signed certificate for testing purposes.
To create a self-managed SSL certificate resource:
gcloud compute ssl-certificates create my-ssl-cert \ --certificate=CRT_FILE_PATH \ --private-key=KEY_FILE_PATH
To create a Google-managed SSL certificate resource:
gcloud compute ssl-certificates create www-ssl-cert \ --domains=DOMAIN_1,DOMAIN_2
- Configure a target SSL proxy.
External proxy Network Load Balancers support creating a target SSL proxy that has from one to fifteen SSL certificates. Before you run this command, you must create an SSL certificate resource for each certificate.
If you want to turn on the proxy header, set it to
PROXY_V1
instead ofnone
. You can optionally attach an SSL policy to the target proxy. First, create the policy.gcloud compute ssl-policies create my-ssl-policy \ --profile=MODERN \ --min-tls-version=1.0
Then attached the policy to the target proxy.
gcloud beta compute target-ssl-proxies create my-ssl-lb-target-proxy \ --backend-service=my-ssl-lb \ --ssl-certificates=[SSL_CERT_1][,[SSL_CERT_2],...] \ --ssl-policy=my-ssl-policy \ --proxy-header=NONE
- Reserve global static IP addresses.
Your customers use these IP addresses to access your load-balanced service.
gcloud compute addresses create ssl-lb-static-ipv4 \ --ip-version=IPV4 \ --global
gcloud compute addresses create ssl-lb-static-ipv6 \ --ip-version=IPV6 \ --global
- Configure global forwarding rules.
Create global forwarding rules associated with the target proxy. Replace LB_STATIC_IP and LB_STATIC_IPV6 with the IP addresses you generated in Reserve global static IP addresses.
gcloud beta compute forwarding-rules create my-ssl-lb-forwarding-rule \ --load-balancing-scheme EXTERNAL_MANAGED \ --global \ --target-ssl-proxy=my-ssl-lb-target-proxy \ --address=LB_STATIC_IP \ --ports=443
Connect your domain to your load balancer
After the load balancer is created, note the IP address that is associated with
the load balancer—for example, 30.90.80.100
. To point your domain to your
load balancer, create an A
record by using your domain registration service. If
you added multiple domains to your SSL certificate, you must add an A
record
for each one, all pointing to the load balancer's IP address. For example, to
create A
records for www.example.com
and example.com
, use the following:
NAME TYPE DATA www A 30.90.80.100 @ A 30.90.80.100
If you use Cloud DNS as your DNS provider, see Add, modify, and delete records.
Test the load balancer
In your web browser, connect to your static IP address using HTTPS. In this test setup, the instances are using self-signed certificates. Therefore, you will see a warning in your browser the first time you access a page. Click through the warning to see the actual page. Replace IP_ADDRESS with either the IPv4 or IPv6 address you created earlier.
https://IP_ADDRESS
You should see one of the hosts from the region closest to you. Reload the page until you see the other instance in that region. To see instances from the other region, stop the instances in the closest region.
Alternatively, you can use curl
from the your local machine's command line.
If you are using a self-signed certificate on the SSL proxy, you must also
specify -k
. The curl -k
option allows curl to work even if you have a
self-signed certificate or no certificate at all. If you have a normal
certificate, you can remove that parameter. You should only use the -k
parameter for testing your own site. Under normal circumstances, a valid
certificate is an important security measure and certificate warnings shouldn't
be ignored.
Replace IP_ADDRESS with either the IPv4 or IPv6 address you created earlier.
curl -k https://IP_ADDRESS
If you can't reach the load balancer, try the steps described under Troubleshooting your setup.
Additional configuration options
This section expands on the configuration example to provide alternative and additional configuration options. All of the tasks are optional. You can perform them in any order.
PROXY protocol for retaining client connection information
The proxy Network Load Balancer ends TCP connections from the client and creates new connections to the instances. By default, the original client IP and port information is not preserved.
To preserve and send the original connection information to your instances, enable PROXY protocol version 1. This protocol sends an additional header that contains the source IP address, destination IP address, and port numbers to the instance as a part of the request.
Make sure that the proxy Network Load Balancer's backend instances are running servers that support PROXY protocol headers. If the servers are not configured to support PROXY protocol headers, the backend instances return empty responses.
If you set the PROXY protocol for user traffic, you can also set it for your
health checks. If you are checking health and serving
content on the same port, set the health check's --proxy-header
to match your
load balancer setting.
The PROXY protocol header is typically a single line of user-readable text in the following format:
PROXY TCP4 <client IP> <load balancing IP> <source port> <dest port>\r\n
The following example shows a PROXY protocol:
PROXY TCP4 192.0.2.1 198.51.100.1 15221 110\r\n
In the preceding example, the client IP is 192.0.2.1
, the load balancing IP is
198.51.100.1
, the client port is 15221
, and the destination port is 110
.
When the client IP is not known, the load balancer generates a PROXY protocol header in the following format:
PROXY UNKNOWN\r\n
Update PROXY protocol header for target proxy
The example load balancer setup on this page shows you how to enable the PROXY protocol header while creating the proxy Network Load Balancer. Use these steps to change the PROXY protocol header for an existing target proxy.
Console
In the Google Cloud console, go to the Load balancing page.
- Click Edit for your load balancer.
- Click Frontend configuration.
- Change the value of the Proxy protocol field to On.
- Click Update to save your changes.
gcloud
In the following command, edit the --proxy-header
field and set it to
either NONE
or PROXY_V1
depending on your requirement.
gcloud compute target-ssl-proxies update TARGET_PROXY_NAME \ --proxy-header=[NONE | PROXY_V1]
Configure session affinity
These procedures show you how to update a backend service for the example SSL proxy load balancer so that the backend service uses client IP affinity.
When client IP affinity is enabled, the load balancer directs a particular client's requests to the same backend VM based on a hash created from the client's IP address and the load balancer's IP address (the external IP address of an external forwarding rule).
Console
To enable client IP session affinity:
In the Google Cloud console, go to the Load balancing page.
Click Backends.
Click my-ssl-lb (the name of the backend service you created for this example) and click Edit.
On the Backend service details page, click Advanced configuration.
Under Session affinity, select Client IP from the menu.
Click Update.
gcloud
Use the following command to update the my-ssl-lb
backend
service, specifying client IP session affinity:
gcloud compute backend-services update my-ssl-lb \ --global \ --session-affinity=CLIENT_IP
API
To set client IP session affinity, make a PATCH
request to the
backendServices/patch
method.
PATCH https://www.googleapis.com/compute/v1/projects/[PROJECT_ID]/global/us-west1/backendServices/my-ssl-lb
{
"sessionAffinity": "CLIENT_IP"
}
Enable connection draining
You can enable connection draining on backend services to ensure minimal interruption to your users when an instance that is serving traffic is terminated, removed manually, or removed by an autoscaler. To learn more about connection draining, see the Enabling Connection Draining documentation.
What's next
- Convert proxy Network Load Balancer to IPv6
- External proxy Network Load Balancer logging and monitoring
- SSL policies for SSL and TLS protocols
- Use SSL policies for SSL and TLS protocols
- Convert to dual-stack backends
- Clean up a load balancing setup