Skip to content

Set up a site-to-site VPN to Google Cloud

View as Markdown

Connect your E2E VPC to a Google Cloud VPC with a site-to-site IPsec VPN. Private resources in your E2E VPC reach resources in your Google Cloud VPC directly. The traffic travels in an encrypted tunnel, so nobody on the internet can read it.

On the E2E side, the tunnel ends on an E2E Firewall, a FortiGate placed in your VPC. On the Google Cloud side, it ends on a Classic VPN gateway. A node in the E2E VPC sends traffic for Google Cloud to the firewall’s private IP, and the firewall sends it through the tunnel.

E2E Cloud on the left: an E2E VPC with virtual machines, databases, a Kubernetes cluster, and applications, behind a FortiGate Firewall. An encrypted IPsec VPN tunnel joins the FortiGate to a Google Cloud VPN Gateway on the right, in front of a Google Cloud VPC with Compute Engine, Cloud SQL, GKE, Cloud Storage, and other services.

The tunnel uses Google Cloud’s Classic VPN, where you enter each network’s address range by hand. Google Cloud’s HA VPN, which shares routes automatically with a routing protocol called BGP, is set up differently.

You need:

  • An E2E Firewall with the status Running, in your E2E VPC. See Create a firewall. Its public IP is one of your reserved IPs. For what a reserved IP costs, see Reserved IP.
  • The firewall’s public IP, under Public IP on Manage Firewall. In MyAccount, it is under Network > Firewall.
  • Your E2E VPC’s private address range. See VPC.
  • A node in your E2E VPC to test with. See Create a node.
  • Access to the Google Cloud console, with permission to manage VPC networks, Compute Engine, and VPN.

The steps use these placeholders. Write down each value as you get it.

Placeholder What goes there
<public-ip> The firewall’s public IP, a reserved IP, such as 203.0.113.10. It is under Public IP on Manage Firewall.
<firewall-private-ip> The firewall’s address in your E2E VPC. It is under Private IP on Manage Firewall.
<e2e-vpc-range> Your E2E VPC’s address range, a /23 range when E2E picked it. It is under CIDR on Manage Virtual Private Cloud.
<gcp-subnet-range> The range you give the Google Cloud subnet, a private /20 range. Choose one that shares no addresses with <e2e-vpc-range>.
<gcp-vpn-gateway-ip> The static public IP you reserve in Google Cloud for the VPN gateway, such as 203.0.113.20.
<pre-shared-key> The pre-shared key for the tunnel. You set it in Google Cloud and enter the same key on the FortiGate.
<gcp-vm-ip> The Google Cloud test VM’s internal IP.
<e2e-node-private-ip> The E2E test node’s private IP. It is on the node’s details in MyAccount.
<interface> The E2E node’s network interface in the VPC, such as ens9.
<gke-pod-range> Your GKE cluster’s Pod range, only for the optional GKE section.

Do these steps in the Google Cloud console. The names, such as e2e-gcp, are examples. Later steps use them, so if you pick your own, use your names throughout. The examples use the asia-south1 region, which is Google Cloud’s Mumbai region. Pick the Google Cloud region closest to your work, and use the same one in every step.

  1. In the left menu, go to VPC network > VPC networks.
  2. Click Create VPC network.
  3. Enter Name e2e-gcp, and set Subnet creation mode to Custom.
  4. Under New subnet, enter Name e2e-gcp, Region asia-south1, and IP range <gcp-subnet-range>.
  5. Click Create. The subnet details page shows when the network is ready.

You use this VM to check the tunnel once it is up.

  1. Go to Compute Engine > VM instances.
  2. Click Create instance.
  3. Enter Name e2e-gcp-test-vm, and choose Region asia-south1, the same region as the subnet.
  4. Under Networking, attach the instance to the new VPC: Network e2e-gcp and Subnetwork e2e-gcp IPv4 (<gcp-subnet-range>).
  5. Click Create. The VM reaches Running in one to two minutes.
  6. Note its Internal IP, your <gcp-vm-ip>.

The Classic VPN gateway needs a static external IP address.

  1. Go to VPC network > IP addresses.
  2. Click Reserve external.
  3. Enter Name vpn-gateway, set Type to Regional, and choose Region asia-south1.
  4. Click Reserve.

The new address appears in the list of IP addresses. Note it: it is your <gcp-vpn-gateway-ip>, and the VPN gateway uses it.

  1. In the search bar, search for VPN, and go to Network Connectivity > VPN.

  2. Click Create VPN connection.

  3. Select Classic VPN, and click Continue.

  4. Under VPN Gateway, enter Name e2e-gcp, Network e2e-gcp, Region asia-south1, and IP address vpn-gateway, the address you reserved.

  5. Under Tunnels, set:

    • Tunnel name: e2e-gcp-tunnel
    • Remote peer IP address: <public-ip>
    • IKE version: IKEv2
    • IKE pre-shared key: enter a strong key, or click Generate. Write it down as your <pre-shared-key>. You enter the same key on the FortiGate.
    • VPN cipher selection: Custom
  6. Set the ciphers:

    Phase Setting Value
    IKE Phase 1 Encryption AES-GCM-16-256
    IKE Phase 1 PRF PRF-HMAC-SHA2-256
    IKE Phase 1 Diffie-Hellman Group modp_2048 (Group 14)
    IKE Phase 2 Encryption AES-GCM-16-256
    IKE Phase 2 PFS modp_2048 (Group 14)

    The Phase 1 and Phase 2 ciphers in Google Cloud must match the FortiGate settings exactly. A cipher mismatch is the most common reason a tunnel fails.

  7. Set the routing:

    • Routing option: Policy-based
    • Remote network IP ranges: <e2e-vpc-range>
    • Local subnetworks: e2e-gcp
    • Local IP ranges: <gcp-subnet-range>
  8. Click Create. Google Cloud creates the VPN gateway and the tunnel.

Before you move on, write down <gcp-vpn-gateway-ip>, <pre-shared-key>, and <gcp-subnet-range>.

  1. Go to VPC network > Routes.
  2. Select the network e2e-gcp and the region asia-south1, and click View.
  3. Check that a static route for <e2e-vpc-range> is listed, with Next hop the VPN tunnel e2e-gcp-tunnel.

The route can show the warning Next hop VPN tunnel is not in the ESTABLISHED state. That is expected at this point. The warning goes away once the FortiGate side is set up and the tunnel connects.

Allow traffic from E2E in the Google Cloud firewall

Section titled “Allow traffic from E2E in the Google Cloud firewall”

This rule lets traffic from your E2E VPC into Google Cloud. Without it, the tunnel connects but Google Cloud drops that traffic, with no error.

  1. In the left menu, go to VPC network > Firewall.

  2. Click Create firewall rule.

  3. Enter these settings:

    Field Value
    Name e2e-vpc
    Network e2e-gcp
    Direction of traffic Ingress
    Action on match Allow
    Targets All instances in the network
    Source IPv4 ranges <e2e-vpc-range>
    Protocols and ports TCP: 22, 80, 443, and ICMP
  4. Click Create.

Port 22 is for the SSH test, and ports 80 and 443 are for web traffic. Add any other ports your application needs.

  1. In a browser, go to https://<public-ip>.
  2. Sign in with the username admin and the password from the launch email E2E sent when the firewall first ran.

The FortiGate’s screen opens. For more on the first sign-in, see Sign in to the FortiGate.

The FortiGate’s screen uses port 443, and the VPN tunnel uses it too. Move the screen to port 444 before you create the tunnel.

  1. Go to System > Settings.
  2. Under Administration Settings, change HTTPS port from 443 to 444.
  3. Click Apply.
  4. Sign in again at https://<public-ip>:444.

You can also make this change on the FortiGate’s command line. See Before you build an IPsec VPN on the same address.

  1. Go to VPN > VPN Tunnels.
  2. Click Create new, and select Custom IPsec tunnel.

Set the network and authentication settings

Section titled “Set the network and authentication settings”

In the Network section, enter:

Setting Value
Name e2e-gcp
Remote gateway Static IP Address
IP address <gcp-vpn-gateway-ip>
Interface port1
NAT traversal Enable
Keepalive frequency 10
Dead peer detection Enable
DPD retry count 3
DPD retry interval 20 seconds

port1 carries the firewall’s public IP, and port2 its VPC address.

With NAT traversal set to Enable, the FortiGate uses it only if a device between the two gateways translates addresses.

In the Authentication section, enter:

Setting Value
Method Pre-shared Key
Pre-shared key <pre-shared-key>
IKE version Version 2

In the Phase 1 proposal section, enter:

Setting Value
Encryption AES256GCM
PRF PRFSHA256
Diffie-Hellman group 14
Key lifetime 86400 seconds

Google Cloud and the FortiGate name the same settings differently:

Google Cloud FortiGate
AES-GCM-16-256 AES256GCM
PRF-HMAC-SHA2-256 PRFSHA256
modp_2048 Diffie-Hellman group 14
  1. In the Phase 2 selectors section, click Create new.

  2. Enter the selector:

    Setting Value
    Name e2e-gcp
    Encapsulation Tunnel Mode
    IP version IPv4
    Local address <e2e-vpc-range>
    Remote address <gcp-subnet-range>
  3. In the Advanced section, enter:

    Setting Value
    Encryption AES256GCM
    Replay detection Enable
    Perfect Forward Secrecy (PFS) Enable
    Diffie-Hellman group 14
  4. Enter the remaining Phase 2 settings:

    Setting Value
    Local port All
    Remote port All
    Protocol All
    Auto-negotiate Enable
    Autokey keep alive Enable
    Key lifetime 43200 seconds
  5. Click OK to save the Phase 2 selector, and then OK to save the tunnel.

  1. Go to Network > Static Routes, and click Create New.
  2. Set Destination to <gcp-subnet-range> and Interface to the VPN tunnel e2e-gcp.
  3. Click OK.

This sends all traffic for Google Cloud into the tunnel.

You need both policies for traffic to flow in both directions.

  1. Go to Policy & Objects > Firewall Policy, and click Create New.

  2. Enter Policy 1, E2E to Google Cloud, and click OK:

    Field Value
    Name E2E-to-GCP
    Incoming interface port2, the internal side
    Outgoing interface e2e-gcp, the VPN tunnel
    Source The address object for your E2E network
    Destination The address object for the Google Cloud subnet
    Service ALL
    Action ACCEPT
    NAT Disable
  3. Click Create New again, enter Policy 2, Google Cloud to E2E, and click OK:

    Field Value
    Name GCP-to-E2E
    Incoming interface e2e-gcp, the VPN tunnel
    Outgoing interface port2, the internal side
    Source The address object for the Google Cloud subnet
    Destination The address object for your E2E network
    Service ALL
    Action ACCEPT
    NAT Disable
  • In Google Cloud, go to Network Connectivity > VPN > Cloud VPN tunnels. The e2e-gcp-tunnel status is Established.
  • On the FortiGate, go to VPN > VPN Tunnels. The e2e-gcp tunnel status is Up.

Test connections once the tunnel shows Established in Google Cloud and Up on the FortiGate. If either side shows another status, check that the pre-shared key and the cipher settings match exactly on both sides.

Send the E2E node’s traffic through the firewall

Section titled “Send the E2E node’s traffic through the firewall”
  1. In MyAccount, open your node list and note the E2E node’s Private IP, your <e2e-node-private-ip>. The Google Cloud test VM’s internal IP is <gcp-vm-ip>.

  2. Sign in to the E2E node over SSH, and add a route to the Google Cloud subnet:

    sudo ip route add <gcp-subnet-range> via <firewall-private-ip> dev <interface>
    • <gcp-subnet-range> is the Google Cloud subnet range.
    • <firewall-private-ip> is the FortiGate’s private IP on the E2E side.
    • <interface> is the node’s network interface in the E2E VPC, such as ens9.

Traffic for Google Cloud now goes to the FortiGate, which sends it through the tunnel.

From the E2E node, ping the Google Cloud VM:

ping <gcp-vm-ip>

From the Google Cloud VM, using the browser SSH in the Google Cloud console, ping the E2E node:

ping <e2e-node-private-ip>

Replies in both directions show that the tunnel is up and the routes are right.

Sign in over SSH from the E2E node to the Google Cloud VM

Section titled “Sign in over SSH from the E2E node to the Google Cloud VM”
  1. On the E2E node, create an SSH key, and press Enter to accept the defaults:

    ssh-keygen -t ed25519 -C "e2e-gcp-vpn"
  2. Show the public key, and copy it:

    cat ~/.ssh/id_ed25519.pub
  3. In the Google Cloud console, go to Compute Engine > VM Instances. Select the test VM, and click Edit.

  4. Under SSH Keys, click Add Item, paste the public key, and click Save.

  5. From the E2E node, sign in to the Google Cloud VM:

    ssh e2e-gcp-vpn@<gcp-vm-ip>

The sign-in succeeds over the tunnel.

Follow these steps when Pods in a GKE cluster need to reach your E2E VPC through the same tunnel. Pods use their own range, separate from <gcp-subnet-range>, so add that range to the tunnel too. Without it, Pod traffic to E2E is dropped with no error.

Run this, with your cluster’s name in place of cluster-1 and its location in place of asia-south1:

gcloud container clusters describe cluster-1 \
--location asia-south1 \
--format="value(ipAllocationPolicy.clusterIpv4CidrBlock)"

The output is the cluster’s Pod range, your <gke-pod-range>. The later steps use it.

Add the Pod range to the Google Cloud tunnel

Section titled “Add the Pod range to the Google Cloud tunnel”
  1. Go to Network Connectivity > VPN, and open the tunnel e2e-gcp-tunnel.

  2. In Local IP ranges, add <gke-pod-range> next to the existing subnet range.

    Before After
    Remote network <e2e-vpc-range> <e2e-vpc-range>, unchanged
    Local networks <gcp-subnet-range> <gcp-subnet-range> and <gke-pod-range>
  3. Click Save.

  1. On the FortiGate, go to VPN > VPN Tunnels, and open e2e-gcp.

  2. Click Create New Phase 2, and enter:

    Setting Value
    Name e2e-gcp-gke-pod-cidr
    Local Address <e2e-vpc-range>
    Remote Address <gke-pod-range>
    Encryption AES256GCM
    PFS Enable
    DH Group 14
    Auto-Negotiate Enable
    Auto Key Keep Alive Enable
  3. Click OK.

  1. Go to Network > Static Routes, and click Create New.
  2. Set Destination to <gke-pod-range> and Interface to the tunnel e2e-gcp.
  3. Click OK.

Create an address object for the Pod range

Section titled “Create an address object for the Pod range”
  1. Go to Policy & Objects > Addresses, and click Create New.
  2. Enter Name gke-pod-cidr and Subnet <gke-pod-range>.
  3. Click OK.

Add the Pod range to the firewall policies

Section titled “Add the Pod range to the firewall policies”
  1. Go to Policy & Objects > Firewall Policy.
  2. Edit E2E-to-GCP, add gke-pod-cidr to Destination Address, and click OK.
  3. Edit GCP-to-E2E, add gke-pod-cidr to Source Address, and click OK.

Add a route to the Pod range on the E2E node

Section titled “Add a route to the Pod range on the E2E node”

Sign in to the E2E node over SSH, and add a route to the Pod range through the FortiGate’s private IP:

sudo ip route add <gke-pod-range> via <firewall-private-ip> dev <interface>
  • <gke-pod-range> is the GKE Pod range.
  • <firewall-private-ip> is the FortiGate’s private IP.
  • <interface> is the E2E node’s private network interface, such as ens9.
  1. Start a test Pod:

    kubectl run test --image=busybox:1.36 -it --rm -- sh
  2. From inside the Pod, ping a private IP in your E2E VPC:

    ping <e2e-node-private-ip>

Replies show that GKE Pods reach your E2E VPC through the same tunnel.

Your E2E VPC and your Google Cloud VPC are now joined by a site-to-site VPN. Each E2E node that needs Google Cloud gets the same route to the Google Cloud subnet. To put another of your E2E networks behind the tunnel, see Attach a VPC to a firewall. For help with a tunnel that is not Up, see The site-to-site VPN tunnel does not come up.