Set up protocol forwarding

This document contains instructions to configure protocol forwarding for both internal and external protocol forwarding. Before you configure protocol forwarding, read Protocol forwarding overview.

Set up external protocol forwarding

This section shows you how to set up external protocol forwarding by using a forwarding rule to forward TCP traffic to a single target instance. There are separate instructions for IPv4 and IPv6 traffic.

To set up external protocol forwarding, you create a target instance that contains a single VM instance. You then create an external regional forwarding rule that forwards traffic to the target instance.

IPv4

For simplicity, this example uses the default network and subnets.

  1. Create a firewall rule that allows external traffic to reach the target instance.

    gcloud compute firewall-rules create ALLOW_IPV4_FIREWALL_RULE_NAME \
     --target-tags=allow-ipv4-ext \
     --allow=tcp:80 \
     --source-ranges=0.0.0.0/0
    
  2. Create a VM. For this example, we're setting up an Apache server on the VM.

    gcloud compute instances create VM_INSTANCE_NAME \
     --zone=ZONE \
     --image-family=debian-10 \
     --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'
    
  3. 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 rule object because the forwarding rule must reference an existing target resource.

    gcloud compute target-instances create TARGET_INSTANCE_NAME \
       --instance=VM_INSTANCE_NAME \
       --zone=ZONE
    
  4. Reserve a static external IPv4 address.

    gcloud compute addresses create IPV4_ADDRESS \
      --region=REGION
    
  5. Create the forwarding rule that forwards TCP traffic to the target instance. The forwarding rule must be created in the same region in which the target instance was created.

    gcloud compute forwarding-rules create IPV4_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
    
  6. Test your setup.

    1. Get the IP address of your forwarding rule.

      gcloud compute forwarding-rules describe IPV4_FORWARDING_RULE_NAME \
        --region=REGION
      
    2. Make web requests to the load balancer by using curl to contact its IP address. Replace IP_ADDRESS with the IP address from the previous step.

      $ while true; do curl -m1 IP_ADDRESS; done
      

      The output is similar to the following, where the name of the backend VM generating the response is displayed.

      Page served from: VM_INSTANCE_NAME.
      

IPv6

Handling IPv6 traffic requires a dual-stack subnet with a dual-stack VM instance for the target instance backend.

  1. Create a custom mode VPC network.

    gcloud compute networks create VPC_NAME \
      --subnet-mode=custom
    
  2. Within the VPC network, create a dual-stack subnet.

    gcloud compute networks subnets create SUBNET_NAME \
      --network=VPC_NAME \
      --range=192.168.11.0/24 \
      --stack-type=IPV4_IPV6 \
      --ipv6-access-type=EXTERNAL \
      --region=REGION
    

    The range 192.168.11.0/24 is only an example IPv4 range. You can enter any primary IPv4 range for the new subnet, in CIDR notation. For more information, see IPv4 subnet ranges.

  3. Create a firewall rule that allows external traffic to reach the target instance.

    gcloud compute firewall-rules create ALLOW_IPV6_FIREWALL_RULE_NAME \
      --network=VPC_NAME \
      --target-tags=allow-ipv6-ext \
      --allow=tcp:80 \
      --source-ranges=::/0
    
  4. Create a dual-stack VM.

    gcloud compute instances create VM_INSTANCE_NAME \
      --subnet=SUBNET_NAME \
      --stack-type=IPV4_IPV6 \
      --zone=ZONE \
      --image-family=debian-10 \
      --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'
    
  5. Create a target instance that contains the VM created in the previous step.

    gcloud compute target-instances create TARGET_INSTANCE_NAME \
      --instance=VM_INSTANCE_NAME \
      --network=VPC_NAME \
      --zone=ZONE
    
  6. Reserve a static external IPv6 address range.

    gcloud compute addresses create IPV6_ADDRESS \
      --region=REGION \
      --subnet=SUBNET_NAME \
      --ip-version=IPV6 \
      --endpoint-type=NETLB
    
  7. Create an IPv6 forwarding rule that forwards TCP traffic to the target instance. The forwarding rule must be created in the same region in which the target instance was created.

    gcloud compute forwarding-rules create IPV6_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
    
  8. Test your setup.

    1. Get the IP address of the forwarding rule.

      gcloud compute forwarding-rules describe IPV6_FORWARDING_RULE_NAME \
       --region=REGION
      
    2. Make web requests to the load balancer by using curl to contact its IP address. Replace IPV6_ADDRESS with the IP address from the previous step.

      curl -6 'http://[IPV6_ADDRESS]:80'
      

      The output is similar to the following, where the name of the backend VM 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 a forwarding rule to forward TCP traffic to a single target instance. There are separate instructions for IPv4 and IPv6 traffic.

For this example, you create a target instance that contains a single VM instance with an Apache server installed on it. You then create an internal regional forwarding rule that forwards traffic to the target instance.

IPv4

For simplicity, this example uses the default network and subnets.

  1. Create a firewall rule that allows internal traffic to reach the target instance.

    gcloud compute firewall-rules create ALLOW_IPV4_FIREWALL_RULE_NAME \
      --target-tags=allow-ipv4-int \
      --allow=tcp \
      --source-ranges=0.0.0.0/0
    
  2. Create a firewall rule to allow SSH connectivity to VMs with the network tag allow-ssh. This is used to establish an SSH connection to the client VM.

    gcloud compute firewall-rules create ALLOW_SSH_FIREWALL_RULE_NAME \
      --target-tags=allow-ssh \
      --allow=tcp:22 \
      --source-ranges=0.0.0.0/0
    
  3. Create a VM.

    gcloud compute instances create VM_INSTANCE_NAME \
      --zone=ZONE \
      --image-family=debian-10 \
      --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'
    
  4. 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 rule object because the forwarding rule must reference an existing target resource.

    gcloud compute target-instances create TARGET_INSTANCE_NAME \
      --instance=VM_INSTANCE_NAME \
      --zone=ZONE
    
  5. Create the forwarding rule that forwards TCP traffic to the target instance. The forwarding rule must be created in the same region in which the target instance was created.

    gcloud compute forwarding-rules create IPV4_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
    
  6. Create a test client VM.

    gcloud compute instances create CLIENT_VM_NAME \
      --zone=ZONE \
      --image-family=debian-10 \
      --image-project=debian-cloud \
      --tags=allow-ssh
    

    You can now test your protocol forwarding configuration by sending traffic from this client VM to the forwarding rule IP address.

  7. Test your setup.

    1. Get the IP address of your forwarding rule.

      gcloud compute forwarding-rules describe IPV4_FORWARDING_RULE_NAME \
       --region=REGION
      
    2. Establish an SSH connection to the client VM.

      gcloud compute ssh CLIENT_VM_NAME \
      --zone=ZONE
      
    3. Make requests to the load balancer by using curl to contact its IP address.

      $ while true; do curl -m1 IP_ADDRESS; done
      

      The output is similar to the following, where the name of the backend VM generating the response is displayed.

      Page served from: VM_INSTANCE_NAME.
      

IPv6

Handling IPv6 traffic requires a dual-stack subnet with a dual-stack VM instance for the target instance backend.

  1. Create a custom mode VPC network with the --enable-ula-internal-ipv6 flag to configure internal IPv6 ranges on any subnets in this network.

    gcloud compute networks create VPC_NAME \
      --subnet-mode=custom \
      --enable-ula-internal-ipv6
    
  2. Within the VPC network, create a dual-stack subnet.

    gcloud compute networks subnets create SUBNET_NAME \
      --network=VPC_NAME \
      --range=192.168.11.0/24 \
      --region=REGION \
      --stack-type=IPV4_IPV6 \
      --ipv6-access-type=INTERNAL
    

    The range 192.168.11.0/24 is only an example IPv4 range. You can enter any primary IPv4 range for the new subnet, in CIDR notation. For more information, see IPv4 subnet ranges.

  3. Create a firewall rule that allows internal traffic to reach the target instance.

    gcloud compute firewall-rules create ALLOW_IPV6_FIREWALL_RULE_NAME \
      --network=VPC_NAME \
      --target-tags=allow-ipv6-int \
      --allow=tcp \
      --source-ranges=::/0
    
  4. Create a firewall rule to allow SSH connectivity to VMs by using the network tag allow-ssh.

    gcloud compute firewall-rules create ALLOW_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 the following steps) that you connect to by using SSH to send HTTP traffic to the IP address of the forwarding rule.

  5. Create a dual-stack VM.

    gcloud compute instances create VM_INSTANCE_NAME \
      --subnet=SUBNET_NAME \
      --stack-type=IPV4_IPV6 \
      --zone=ZONE \
      --image-family=debian-10 \
      --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'
    
  6. Create a target instance that contains the VM created in the previous step.

    gcloud compute target-instances create TARGET_INSTANCE_NAME \
      --instance=VM_INSTANCE_NAME \
      --network=VPC_NAME \
      --zone=ZONE
    
  7. Create an IPv6 forwarding rule that forwards TCP traffic to the target instance. The forwarding rule must be created in the same region in which the target instance was created.

    gcloud compute forwarding-rules create IPV6_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
    
  8. Create a client VM.

    gcloud compute instances create CLIENT_VM_NAME \
      --subnet=SUBNET_NAME \
      --stack-type=IPV4_IPV6 \
      --zone=ZONE \
      --image-family=debian-10 \
      --image-project=debian-cloud \
      --tags=allow-ssh
    
  9. Test your setup.

    1. Get the IP address of the forwarding rule.

      gcloud compute forwarding-rules describe IPV6_FORWARDING_RULE_NAME \
       --region=REGION
      
    2. Establish an SSH connection to the client VM.

      gcloud compute ssh CLIENT_VM_NAME \
       --zone=ZONE
      
    3. Make an HTTP request to the IP address of the forwarding rule by using curl.

      curl -6 'http://[FORWARDING_RULE_IP_ADDRESS]:80'
      

      The output is similar to the following, where the name of the backend VM generating the response is displayed in the text.

      Page served from: VM_INSTANCE_NAME.
      

What's next