--- title: "Set up a site-to-site VPN to Google Cloud" description: "Connect your E2E VPC to a Google Cloud VPC over a site-to-site IPsec VPN through an E2E Firewall, with optional access from GKE Pods." content_type: "how-to" product: "firewall" platform: "MyAccount" url: "/myaccount/firewall/how-to/set-up-a-site-to-site-vpn-to-google-cloud/" topic: ["network"] --- # Set up a site-to-site VPN to Google Cloud 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.](/images/myaccount/firewall/vpn-google-cloud-architecture.png) 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. ## Before you begin You need: - An E2E Firewall with the status **Running**, in your E2E VPC. See [Create a firewall](/myaccount/firewall/how-to/create-a-firewall/). Its public IP is one of your reserved IPs. For what a reserved IP costs, see [Reserved IP](/myaccount/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](/myaccount/vpc/). - A node in your E2E VPC to test with. See [Create a node](/myaccount/node/how-to/create-a-node/). - Access to the Google Cloud console, with permission to manage VPC networks, Compute Engine, and VPN. ## Example values The steps use these placeholders. Write down each value as you get it. | Placeholder | What goes there | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------ | | `` | The firewall's public IP, a reserved IP, such as `203.0.113.10`. It is under **Public IP** on **Manage Firewall**. | | `` | The firewall's address in your E2E VPC. It is under **Private IP** on **Manage Firewall**. | | `` | Your E2E VPC's address range, a `/23` range when E2E picked it. It is under **CIDR** on **Manage Virtual Private Cloud**. | | `` | The range you give the Google Cloud subnet, a private `/20` range. Choose one that shares no addresses with ``. | | `` | The static public IP you reserve in Google Cloud for the VPN gateway, such as `203.0.113.20`. | | `` | The pre-shared key for the tunnel. You set it in Google Cloud and enter the same key on the FortiGate. | | `` | The Google Cloud test VM's internal IP. | | `` | The E2E test node's private IP. It is on the node's details in MyAccount. | | `` | The E2E node's network interface in the VPC, such as `ens9`. | | `` | Your GKE cluster's Pod range, only for the optional GKE section. | ## Set up Google Cloud Do these steps in the [Google Cloud console](https://console.cloud.google.com). 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. ### Create a VPC network 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** ``. 5. Click **Create**. The subnet details page shows when the network is ready. ### Create a test VM in Google Cloud 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 ()`. 5. Click **Create**. The VM reaches **Running** in one to two minutes. 6. Note its **Internal IP**, your ``. ### Reserve a static public 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 ``, and the VPN gateway uses it. ### Create the Classic VPN gateway and tunnel 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**: `` - **IKE version**: **IKEv2** - **IKE pre-shared key**: enter a strong key, or click **Generate**. Write it down as your ``. 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**: `` - **Local subnetworks**: `e2e-gcp` - **Local IP ranges**: `` 8. Click **Create**. Google Cloud creates the VPN gateway and the tunnel. Before you move on, write down ``, ``, and ``. ### Check the VPN route 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 `` 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 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 | `` | | 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. ## Set up the FortiGate ### Sign in to the FortiGate 1. In a browser, go to `https://`. 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](/myaccount/firewall/how-to/sign-in-to-the-fortigate/). ### Move the FortiGate's screen to port 444 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://:444`. You can also make this change on the FortiGate's command line. See [Before you build an IPsec VPN on the same address](/myaccount/firewall/how-to/sign-in-to-the-fortigate/#before-you-build-an-ipsec-vpn-on-the-same-address). ### Create a custom IPsec tunnel 1. Go to **VPN** > **VPN Tunnels**. 2. Click **Create new**, and select **Custom IPsec tunnel**. ### Set the network and authentication settings In the **Network** section, enter: | Setting | Value | | ------------------- | ---------------------- | | Name | `e2e-gcp` | | Remote gateway | Static IP Address | | IP address | `` | | 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 | `` | | IKE version | Version 2 | ### Set Phase 1 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 | ### Set Phase 2 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 | `` | | Remote address | `` | 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. ### Add a static route to Google Cloud 1. Go to **Network** > **Static Routes**, and click **Create New**. 2. Set **Destination** to `` and **Interface** to the VPN tunnel `e2e-gcp`. 3. Click **OK**. This sends all traffic for Google Cloud into the tunnel. ### Create the firewall policies 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 | ## Check that the tunnel is up - 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 1. In MyAccount, open your node list and note the E2E node's **Private IP**, your ``. The Google Cloud test VM's internal IP is ``. 2. Sign in to the E2E node over SSH, and add a route to the Google Cloud subnet: ```bash sudo ip route add via dev ``` - `` is the Google Cloud subnet range. - `` is the FortiGate's private IP on the E2E side. - `` 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. ## Test the connection ### Ping in both directions From the E2E node, ping the Google Cloud VM: ```bash ping ``` From the Google Cloud VM, using the browser SSH in the Google Cloud console, ping the E2E node: ```bash ping ``` 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 1. On the E2E node, create an SSH key, and press Enter to accept the defaults: ```bash ssh-keygen -t ed25519 -C "e2e-gcp-vpn" ``` 2. Show the public key, and copy it: ```bash 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: ```bash ssh e2e-gcp-vpn@ ``` The sign-in succeeds over the tunnel. ## (Optional) Reach E2E from GKE Pods 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 ``, so add that range to the tunnel too. Without it, Pod traffic to E2E is dropped with no error. ### Find the GKE Pod range Run this, with your cluster's name in place of `cluster-1` and its location in place of `asia-south1`: ```bash gcloud container clusters describe cluster-1 \ --location asia-south1 \ --format="value(ipAllocationPolicy.clusterIpv4CidrBlock)" ``` The output is the cluster's Pod range, your ``. The later steps use it. ### 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 `` next to the existing subnet range. | | Before | After | | -------------- | -------------------- | ------------------------------------------ | | Remote network | `` | ``, unchanged | | Local networks | `` | `` and `` | 3. Click **Save**. ### Add a Phase 2 selector for the Pod range 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 | `` | | Remote Address | `` | | Encryption | AES256GCM | | PFS | Enable | | DH Group | 14 | | Auto-Negotiate | Enable | | Auto Key Keep Alive | Enable | 3. Click **OK**. ### Add a static route for the Pod range 1. Go to **Network** > **Static Routes**, and click **Create New**. 2. Set **Destination** to `` and **Interface** to the tunnel `e2e-gcp`. 3. Click **OK**. ### 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** ``. 3. Click **OK**. ### 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 Sign in to the E2E node over SSH, and add a route to the Pod range through the FortiGate's private IP: ```bash sudo ip route add via dev ``` - `` is the GKE Pod range. - `` is the FortiGate's private IP. - `` is the E2E node's private network interface, such as `ens9`. ### Test from a GKE Pod 1. Start a test Pod: ```bash kubectl run test --image=busybox:1.36 -it --rm -- sh ``` 2. From inside the Pod, ping a private IP in your E2E VPC: ```bash ping ``` 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](/myaccount/firewall/how-to/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](/myaccount/firewall/troubleshooting/firewall/#the-site-to-site-vpn-tunnel-does-not-come-up).