Set up protocol forwarding Stay organized with collections Save and categorize content based on your preferences.
This document contains instructions to configure protocol forwarding for bothinternal and external protocol forwarding. Before you configure protocolforwarding, readProtocol forwarding overview.
Note: You cannot create target instance resources using the Google Cloud console.You can only use theGoogle Cloud CLIorAPI commands.Set up external protocol forwarding
This section shows you how to set up external protocol forwarding by using aforwarding rule to forward TCP traffic to a single target instance. Thereare separate instructions for IPv4-only, dual-stack, and IPv6-only traffic.
To set up external protocol forwarding, you create a target instance thatcontains a single VM instance. You then create an external regional forwardingrule that forwards traffic to the target instance.
IPv4 only
For simplicity, this example uses the default network and subnets.
Create a firewall rule that allows external traffic to reach the targetinstance.
gcloud compute firewall-rules createALLOW_IPV4_FIREWALL_RULE_NAME \ --target-tags=allow-ipv4-ext \ --allow=tcp:80 \ --source-ranges=0.0.0.0/0
Create a VM. For this example, you set up an Apache server on the VM.
gcloud compute instances createVM_INSTANCE_NAME \ --zone=ZONE \ --image-family=debian-12 \ --image-project=debian-cloud \ --tags=allow-ipv4-ext \ --metadata=startup-script='#! /bin/bash sudo apt-get update sudo apt-get install apache2 -y sudo a2ensite default-ssl sudo a2enmod ssl vm_hostname="$(curl -H "Metadata-Flavor:Google" \ http://169.254.169.254/computeMetadata/v1/instance/name)" echo "Page served from: $vm_hostname" | \ tee /var/www/html/index.html sudo systemctl restart apache2'
Create a target instance that contains the VM created in the previous step.You must create a target instance before you can create a forwarding ruleobject because the forwarding rule must reference an existing targetresource.
gcloud compute target-instances createTARGET_INSTANCE_NAME \ --instance=VM_INSTANCE_NAME \ --zone=ZONE
Reserve astatic external IPv4address.
gcloud compute addresses createIPV4_ADDRESS \ --region=REGION
Create the forwarding rule that forwards TCP traffic to the targetinstance. The forwarding rule must be created in the same region in whichthe target instance was created.
gcloud compute forwarding-rules createIPV4_FORWARDING_RULE_NAME \ --load-balancing-scheme=EXTERNAL \ --region=REGION \ --ip-protocol=TCP \ --address=IPV4_ADDRESS \ --ports=80 \ --target-instance=TARGET_INSTANCE_NAME \ --target-instance-zone=ZONE
Test your setup.
Get the IP address of your forwarding rule.
gcloud compute forwarding-rules describeIPV4_FORWARDING_RULE_NAME \ --region=REGION
Make web requests to the load balancer by using curl to contact its IPaddress. Replace
IP_ADDRESSwith the IP addressfrom the previous step.while true; do curl -m1IP_ADDRESS; done
The output is similar to the following, where the name of the backendVM generating the response is displayed.
Page served from:VM_INSTANCE_NAME.
Dual-stack
Handling both IPv4 and IPv6 traffic requires a dual-stack subnet with adual-stack VM instance for the target instance backend.
Create a custom mode VPC network.
gcloud compute networks createVPC_NAME \ --subnet-mode=custom
Within the VPC network, create a dual-stack subnet.
gcloud compute networks subnets createSUBNET_NAME \ --network=VPC_NAME \ --range=IPV4_ADDRESS_RANGE \ --stack-type=IPV4_IPV6 \ --ipv6-access-type=EXTERNAL \ --region=REGION
ForIPV4_ADDRESS_RANGE, you can enter any primary IPv4 range forthe new subnet, in CIDR notation. For example,
192.168.11.0/24. For moreinformation, seeIPv4 subnetranges.Create a firewall rule that allows external traffic to reach the targetinstance.
gcloud compute firewall-rules createALLOW_IPV6_FIREWALL_RULE_NAME \ --network=VPC_NAME \ --target-tags=allow-ipv6-ext \ --allow=tcp:80 \ --source-ranges=::/0
Create a dual-stack VM.
gcloud compute instances createVM_INSTANCE_NAME \ --subnet=SUBNET_NAME \ --stack-type=IPV4_IPV6 \ --zone=ZONE \ --image-family=debian-12 \ --image-project=debian-cloud \ --tags=allow-ipv6-ext \ --metadata=startup-script='#! /bin/bash sudo apt-get update sudo apt-get install apache2 -y sudo a2ensite default-ssl sudo a2enmod ssl vm_hostname="$(curl -H "Metadata-Flavor:Google" \ http://metadata.google.internal/computeMetadata/v1/instance/name)" echo "Page served from: $vm_hostname" | \ tee /var/www/html/index.html sudo systemctl restart apache2'
Create a target instance that contains the VM created in the previous step.
gcloud compute target-instances createTARGET_INSTANCE_NAME \ --instance=VM_INSTANCE_NAME \ --network=VPC_NAME \ --zone=ZONE
Reserve astatic external IPv4address.
gcloud compute addresses createIPV4_ADDRESS \ --region=REGION
Create an IPv4 forwarding rule that forwards TCP traffic to the targetinstance. The forwarding rule must be created in the same region in whichthe target instance was created.
gcloud compute forwarding-rules createIPV4_FORWARDING_RULE_NAME \ --load-balancing-scheme=EXTERNAL \ --region=REGION \ --ip-protocol=TCP \ --address=IPV4_ADDRESS \ --ports=80 \ --target-instance=TARGET_INSTANCE_NAME \ --target-instance-zone=ZONE
Reserve astatic external IPv6 addressrange.
gcloud compute addresses createIPV6_ADDRESS \ --region=REGION \ --subnet=SUBNET_NAME \ --ip-version=IPV6 \ --endpoint-type=NETLB
Create an IPv6 forwarding rule that forwards TCP traffic to the targetinstance. The forwarding rule must be created in the same region in whichthe target instance was created.
gcloud compute forwarding-rules createIPV6_FORWARDING_RULE_NAME \ --load-balancing-scheme=EXTERNAL \ --subnet=SUBNET_NAME \ --ip-version=IPV6 \ --region=REGION \ --address=IPV6_ADDRESS \ --network-tier=PREMIUM \ --target-instance=TARGET_INSTANCE_NAME \ --target-instance-zone=ZONE \ --ip-protocol=TCP \ --ports=80
Test your setup.
Get the IP address of the forwarding rules.
gcloud compute forwarding-rules describeIPV4_FORWARDING_RULE_NAME \ --region=REGION
gcloud compute forwarding-rules describeIPV6_FORWARDING_RULE_NAME \ --region=REGION
Make web requests to the load balancer by using curl to contact its IPaddress. Replace
IP_ADDRESSwith the IPaddress from the previous step.For IPv4 traffic:
while true; do curl -m1IP_ADDRESS; done
For IPv6 traffic:
curl -6 'http://[IP_ADDRESS]:80'
The output is similar to the following, where the name of the backendVM generating the response is displayed.
Page served from:VM_INSTANCE_NAME.
IPv6 only
Handling only IPv6 traffic requires an IPv6-only subnet with an IPv6-only VMinstance for the target instance backend.
Create a custom mode VPC network.
gcloud beta compute networks createVPC_NAME \ --subnet-mode=custom
Within the VPC network, create an IPv6-only subnet.
gcloud beta compute networks subnets createSUBNET_NAME \ --network=VPC_NAME \ --stack-type=IPV6_ONLY \ --ipv6-access-type=EXTERNAL \ --region=REGION
Create a firewall rule that allows external traffic to reach the targetinstance.
gcloud beta compute firewall-rules createALLOW_IPV6_FIREWALL_RULE_NAME \ --network=VPC_NAME \ --target-tags=allow-ipv6-ext \ --allow=tcp:80 \ --source-ranges=::/0
Create an IPv6-only VM.
gcloud beta compute instances createVM_INSTANCE_NAME \ --subnet=SUBNET_NAME \ --stack-type=IPV6_ONLY \ --zone=ZONE \ --image-family=debian-12 \ --image-project=debian-cloud \ --tags=allow-ipv6-ext \ --metadata=startup-script='#! /bin/bash sudo apt-get update sudo apt-get install apache2 -y sudo a2ensite default-ssl sudo a2enmod ssl vm_hostname="$(curl -H "Metadata-Flavor:Google" \ http://metadata.google.internal/computeMetadata/v1/instance/name)" echo "Page served from: $vm_hostname" | \ tee /var/www/html/index.html sudo systemctl restart apache2'
Create a target instance that contains the VM created in the previous step.
gcloud beta compute target-instances createTARGET_INSTANCE_NAME \ --instance=VM_INSTANCE_NAME \ --network=VPC_NAME \ --zone=ZONE
Reserve astatic external IPv6 addressrange.
gcloud beta compute addresses createIPV6_ADDRESS \ --region=REGION \ --subnet=SUBNET_NAME \ --ip-version=IPV6 \ --endpoint-type=NETLB
Create an IPv6 forwarding rule that forwards TCP traffic to the targetinstance. The forwarding rule must be created in the same region in whichthe target instance was created.
gcloud beta compute forwarding-rules createIPV6_FORWARDING_RULE_NAME \ --load-balancing-scheme=EXTERNAL \ --subnet=SUBNET_NAME \ --ip-version=IPV6 \ --region=REGION \ --address=IPV6_ADDRESS \ --network-tier=PREMIUM \ --target-instance=TARGET_INSTANCE_NAME \ --target-instance-zone=ZONE \ --ip-protocol=TCP \ --ports=80
Test your setup.
Get the IP address of the forwarding rule.
gcloud beta compute forwarding-rules describeIPV6_FORWARDING_RULE_NAME \ --region=REGION
Make web requests to the load balancer by using curl to contact its IPaddress. Replace
IPV6_ADDRESSwith the IP address from theprevious step.curl -6 'http://[IPV6_ADDRESS]:80'
The output is similar to the following, where the name of the backendVM generating the response is displayed.
Page served from:VM_INSTANCE_NAME.
Set up internal protocol forwarding
This section shows you how to set up internal protocol forwarding by using aforwarding rule to forward TCP traffic to a single target instance. There areseparate instructions for IPv4-only, dual-stack, and IPv6-only traffic.
For this example, you create a target instance that contains a single VMinstance with an Apache server installed on it. You then create an internalregional forwarding rule that forwards traffic to the target instance.
IPv4 only
For simplicity, this example uses the default network and subnets to set upinternal protocol forwarding.
Create a firewall rule that allows internal traffic to reach the targetinstance.
gcloud compute firewall-rules createALLOW_IPV4_FIREWALL_RULE_NAME \ --target-tags=allow-ipv4-int \ --allow=tcp \ --source-ranges=0.0.0.0/0
Create a firewall rule to allow SSH connectivity to VMs with the networktag
allow-ssh. This is used to establish an SSH connection to the client VM.gcloud compute firewall-rules createALLOW_SSH_FIREWALL_RULE_NAME \ --target-tags=allow-ssh \ --allow=tcp:22 \ --source-ranges=0.0.0.0/0
Create a VM.
gcloud compute instances createVM_INSTANCE_NAME \ --zone=ZONE \ --image-family=debian-12 \ --image-project=debian-cloud \ --tags=allow-ipv4-int \ --metadata=startup-script='#! /bin/bash sudo apt-get update sudo apt-get install apache2 -y sudo a2ensite default-ssl sudo a2enmod ssl vm_hostname="$(curl -H "Metadata-Flavor:Google" \ http://169.254.169.254/computeMetadata/v1/instance/name)" echo "Page served from: $vm_hostname" | \ tee /var/www/html/index.html sudo systemctl restart apache2'
Create a target instance that contains the VM created in the previous step.You must create a target instance before you can create a forwarding ruleobject because the forwarding rule must reference an existing targetresource.
gcloud compute target-instances createTARGET_INSTANCE_NAME \ --instance=VM_INSTANCE_NAME \ --zone=ZONE
Create the forwarding rule that forwards TCP traffic to the targetinstance. The forwarding rule must be created in the same region in whichthe target instance was created.
gcloud compute forwarding-rules createIPV4_FORWARDING_RULE_NAME \ --load-balancing-scheme=INTERNAL \ --network-tier=PREMIUM \ --region=REGION \ --ip-protocol=TCP \ --ports=80 \ --target-instance=TARGET_INSTANCE_NAME \ --target-instance-zone=ZONE
Create a test client VM.
gcloud compute instances createCLIENT_VM_NAME \ --zone=ZONE \ --image-family=debian-12 \ --image-project=debian-cloud \ --tags=allow-ssh
You can now test your protocol forwarding configuration by sending trafficfrom this client VM to the forwarding rule IP address.
Test your setup.
Get the IP address of your forwarding rule.
gcloud compute forwarding-rules describeIPV4_FORWARDING_RULE_NAME \ --region=REGION
Establish an SSH connection to the client VM.
gcloud compute sshCLIENT_VM_NAME \ --zone=ZONE
Make requests to the load balancer by using curl to contact its IPaddress.
while true; do curl -m1IP_ADDRESS; done
The output is similar to the following, where the name of the backendVM generating the response is displayed.
Page served from:VM_INSTANCE_NAME.
Dual-stack
Handling both IPv4 and IPv6 traffic requires a dual-stack subnet with adual-stack VM instance for the target instance backend.
Create a custom mode VPC network with the
--enable-ula-internal-ipv6flag to configure internal IPv6 ranges on anysubnets in this network.gcloud compute networks createVPC_NAME \ --subnet-mode=custom \ --enable-ula-internal-ipv6
Within the VPC network, create a dual-stack subnet.
gcloud compute networks subnets createSUBNET_NAME \ --network=VPC_NAME \ --range=IPV4_ADDRESS_RANGE \ --region=REGION \ --stack-type=IPV4_IPV6 \ --ipv6-access-type=INTERNAL
ForIPV4_ADDRESS_RANGE, you can enter any primary IPv4 range forthe new subnet, in CIDR notation. For example,
192.168.11.0/24. For moreinformation, seeIPv4 subnetranges.Create a firewall rule that allows internal traffic to reach the targetinstance.
gcloud compute firewall-rules createALLOW_IPV6_FIREWALL_RULE_NAME \ --network=VPC_NAME \ --target-tags=allow-ipv6-int \ --allow=tcp \ --source-ranges=::/0
Create a firewall rule to allow SSH connectivity to VMs by using the networktag
allow-ssh.gcloud compute firewall-rules createALLOW_SSH_FIREWALL_RULE_NAME \ --network=VPC_NAME \ --target-tags=allow-ssh \ --allow=tcp:22 \ --source-ranges=0.0.0.0/0
This firewall rule is applied to a client VM (created in one of thefollowing steps) that you connect to by using SSH to send HTTP traffic tothe IP address of the forwarding rule.
Create a dual-stack VM.
gcloud compute instances createVM_INSTANCE_NAME \ --subnet=SUBNET_NAME \ --stack-type=IPV4_IPV6 \ --zone=ZONE \ --image-family=debian-12 \ --image-project=debian-cloud \ --tags=allow-ipv6-int \ --metadata=startup-script='#! /bin/bash sudo apt-get update sudo apt-get install apache2 -y sudo a2ensite default-ssl sudo a2enmod ssl vm_hostname="$(curl -H "Metadata-Flavor:Google" \ http://metadata.google.internal/computeMetadata/v1/instance/name)" echo "Page served from: $vm_hostname" | \ tee /var/www/html/index.html sudo systemctl restart apache2'
Create a target instance that contains the VM created in the previous step.
gcloud compute target-instances createTARGET_INSTANCE_NAME \ --instance=VM_INSTANCE_NAME \ --network=VPC_NAME \ --zone=ZONE
Create an IPv4 forwarding rule that forwards TCP traffic to the targetinstance. The forwarding rule must be created in the same region in whichthe target instance was created.
gcloud compute forwarding-rules createIPV4_FORWARDING_RULE_NAME \ --load-balancing-scheme=INTERNAL \ --network-tier=PREMIUM \ --region=REGION \ --ip-protocol=TCP \ --ports=80 \ --target-instance=TARGET_INSTANCE_NAME \ --target-instance-zone=ZONE
Create an IPv6 forwarding rule that forwards TCP traffic to the targetinstance. The forwarding rule must be created in the same region in whichthe target instance was created.
gcloud compute forwarding-rules createIPV6_FORWARDING_RULE_NAME \ --load-balancing-scheme=INTERNAL \ --network-tier=PREMIUM \ --network=VPC_NAME \ --subnet=SUBNET_NAME \ --region=REGION \ --ip-protocol=TCP \ --ports=80 \ --target-instance=TARGET_INSTANCE_NAME \ --target-instance-zone=ZONE \ --ip-version=IPV6
Create a client VM.
gcloud compute instances createCLIENT_VM_NAME \ --subnet=SUBNET_NAME \ --stack-type=IPV4_IPV6 \ --zone=ZONE \ --image-family=debian-12 \ --image-project=debian-cloud \ --tags=allow-ssh
Test your setup.
Get the IP address of the forwarding rule.
gcloud compute forwarding-rules describeIPV4_FORWARDING_RULE_NAME \ --region=REGION
gcloud compute forwarding-rules describeIPV6_FORWARDING_RULE_NAME \ --region=REGION
Establish an SSH connection to the client VM.
gcloud compute sshCLIENT_VM_NAME \ --zone=ZONE
Make an HTTP request to the IP address of the forwarding rule by usingcurl.
For IPv4 traffic:
while true; do curl -m1IP_ADDRESS; done
For IPv6 traffic:
curl -6 'http://[FORWARDING_RULE_IP_ADDRESS]:80'
The output is similar to the following, where the name of the backendVM generating the response is displayed in the text.
Page served from:VM_INSTANCE_NAME.
IPv6 only
Handling only IPv6 traffic requires an IPv6-only subnet with anIPv6-only VM instance for the target instance backend.
Create a custom mode VPC network with the
--enable-ula-internal-ipv6flag to configure internal IPv6 ranges on anysubnets in this network.gcloud beta compute networks createVPC_NAME \ --subnet-mode=custom \ --enable-ula-internal-ipv6
Within the VPC network, create an IPv6-only subnet.
gcloud beta compute networks subnets createSUBNET_NAME \ --network=VPC_NAME \ --region=REGION \ --stack-type=IPV6_ONLY \ --ipv6-access-type=INTERNAL
Create a firewall rule that allows internal traffic to reach the targetinstance.
gcloud beta compute firewall-rules createALLOW_IPV6_FIREWALL_RULE_NAME \ --network=VPC_NAME \ --target-tags=allow-ipv6-int \ --allow=tcp \ --source-ranges=::/0
Create a firewall rule to allow SSH connectivity to VMs by using the networktag
allow-ssh.gcloud beta compute firewall-rules createALLOW_SSH_FIREWALL_RULE_NAME \ --network=VPC_NAME \ --target-tags=allow-ssh \ --allow=tcp:22 \ --source-ranges=0.0.0.0/0
This firewall rule is applied to a client VM (created in one of thefollowing steps) that you connect to by using SSH to send HTTP traffic tothe IP address of the forwarding rule.
Create an IPv6-only VM.
gcloud beta compute instances createVM_INSTANCE_NAME \ --subnet=SUBNET_NAME \ --stack-type=IPV6_ONLY \ --zone=ZONE \ --image-family=debian-12 \ --image-project=debian-cloud \ --tags=allow-ipv6-int \ --metadata=startup-script='#! /bin/bash sudo apt-get update sudo apt-get install apache2 -y sudo a2ensite default-ssl sudo a2enmod ssl vm_hostname="$(curl -H "Metadata-Flavor:Google" \ http://metadata.google.internal/computeMetadata/v1/instance/name)" echo "Page served from: $vm_hostname" | \ tee /var/www/html/index.html sudo systemctl restart apache2'
Create a target instance that contains the VM created in the previous step.
gcloud beta compute target-instances createTARGET_INSTANCE_NAME \ --instance=VM_INSTANCE_NAME \ --network=VPC_NAME \ --zone=ZONE
Create an IPv6 forwarding rule that forwards TCP traffic to the targetinstance. The forwarding rule must be created in the same region in whichthe target instance was created.
gcloud beta compute forwarding-rules createIPV6_FORWARDING_RULE_NAME \ --load-balancing-scheme=INTERNAL \ --network-tier=PREMIUM \ --network=VPC_NAME \ --subnet=SUBNET_NAME \ --region=REGION \ --ip-protocol=TCP \ --ports=80 \ --target-instance=TARGET_INSTANCE_NAME \ --target-instance-zone=ZONE \ --ip-version=IPV6
Create a client VM.
gcloud beta compute instances createCLIENT_VM_NAME \ --subnet=SUBNET_NAME \ --stack-type=IPV6_ONLY \ --zone=ZONE \ --image-family=debian-12 \ --image-project=debian-cloud \ --tags=allow-ssh
Test your setup.
Get the IP address of the forwarding rule.
gcloud beta compute forwarding-rules describeIPV6_FORWARDING_RULE_NAME \ --region=REGION
Establish an SSH connection to the client VM.
gcloud beta compute sshCLIENT_VM_NAME \ --zone=ZONE
Make an HTTP request to the IP address of the forwarding rule by usingcurl.
curl -6 'http://[FORWARDING_RULE_IP_ADDRESS]:80'
The output is similar to the following, where the name of the backendVM generating the response is displayed in the text.
Page served from:VM_INSTANCE_NAME.
What's next
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 2025-12-15 UTC.