VPNGeek
Purchase
Guides CLOUD

Google Cloud VPN: connect a VPC to a VPNGeek gateway

GCP HA/Classic VPNIKEv2BGP or static 22 min · Updated Jun 2026

Connect a Google Cloud VPC to a VPNGeek gateway over IKEv2 IPsec — HA VPN with Cloud Router and BGP, or Classic VPN with static routes, end to end.

This guide connects a Google Cloud VPC to a VPNGeek gateway over IKEv2 IPsec. Google offers two products: HA VPN, the current recommendation, which gives a 99.99% SLA using two tunnel interfaces and BGP via a Cloud Router; and Classic VPN, a single-tunnel gateway that supports static (policy-based or route-based) routing. This guide covers HA VPN as the primary path and notes the Classic alternative where it differs. When you finish, the VPC and the VPNGeek side reach each other over an encrypted link — with automatic failover on HA VPN.

Before you start

Collect the following before you touch either side. Getting the ASNs and interface addressing straight now avoids the most common BGP problems.

  • A VPNGeek plan that includes IPsec Gateways, with a static public IP on the gateway.
  • A GCP project with the Compute Engine API enabled and rights to create networking resources, plus the gcloud CLI or the console.
  • An existing VPC network and subnet — example VPC range 10.100.0.0/16 in region europe-west1.
  • Non-overlapping CIDRs — VPC 10.100.0.0/16 vs the VPNGeek side 10.20.0.0/16.
  • For HA VPN/BGP: a Cloud Router ASN (e.g. 65010) and a peer ASN for VPNGeek (e.g. 65020), plus link-local /30 addresses in 169.254.0.0/16 for the BGP session(s).

1. Create the HA VPN gateway and Cloud Router

The HA VPN gateway is a Google-managed resource with two interfaces, each getting its own public IP. The Cloud Router runs BGP and propagates learned routes into the VPC.

# HA VPN gateway (two interfaces, two Google public IPs)
gcloud compute vpn-gateways create vpngeek-havpn-gw \
--network=vpngeek-vpc \
--region=europe-west1

# Cloud Router for BGP
gcloud compute routers create vpngeek-router \
--network=vpngeek-vpc \
--region=europe-west1 \
--asn=65010

# Read back the two interface IPs — you peer with BOTH:
gcloud compute vpn-gateways describe vpngeek-havpn-gw \
--region=europe-west1 \
--format='value(vpnInterfaces[].ipAddress)'

2. Register the VPNGeek side as an external VPN gateway

Google needs a peer object describing your VPNGeek gateway. A single-IP VPNGeek gateway is a one-interface external gateway; HA VPN will still stand up two tunnels from its two interfaces to that single peer IP.

# Single-interface peer (VPNGeek has one public IP)
gcloud compute external-vpn-gateways create vpngeek-peer \
--interfaces 0=203.0.113.10
Note. For a full 99.99% SLA, both HA VPN interfaces must reach the peer. With a single-IP VPNGeek gateway you still get two tunnels to that IP, which protects against Google-side interface failure. Provision a second VPNGeek gateway IP and use a two-interface external gateway if you need redundancy on the VPNGeek side too.

3. Create the VPN tunnels

Create one tunnel from each HA VPN interface to the external gateway. IKEv2 is set explicitly, and each tunnel references its Cloud Router for BGP. Note the --interface (0 and 1) selects which HA VPN interface the tunnel uses.

gcloud compute vpn-tunnels create vpngeek-tunnel-0 \
--peer-external-gateway=vpngeek-peer \
--peer-external-gateway-interface=0 \
--region=europe-west1 \
--ike-version=2 \
--shared-secret='<tunnel-0-psk>' \
--router=vpngeek-router \
--vpn-gateway=vpngeek-havpn-gw \
--interface=0

gcloud compute vpn-tunnels create vpngeek-tunnel-1 \
--peer-external-gateway=vpngeek-peer \
--peer-external-gateway-interface=0 \
--region=europe-west1 \
--ike-version=2 \
--shared-secret='<tunnel-1-psk>' \
--router=vpngeek-router \
--vpn-gateway=vpngeek-havpn-gw \
--interface=1
Warning. Give each tunnel its own shared secret and record which is which. Reusing one PSK across both tunnels or swapping them leaves a tunnel stuck negotiating and defeats HA VPN failover.

4. Configure BGP on the Cloud Router

Add a router interface with a link-local /30 for each tunnel, then a BGP peer on each. VPNGeek advertises 10.20.0.0/16 and learns the VPC ranges dynamically — no static routes to maintain.

# Interface + BGP peer for tunnel 0
gcloud compute routers add-interface vpngeek-router \
--interface-name=if-tunnel-0 \
--vpn-tunnel=vpngeek-tunnel-0 \
--ip-address=169.254.21.1 --mask-length=30 \
--region=europe-west1
gcloud compute routers add-bgp-peer vpngeek-router \
--peer-name=peer-tunnel-0 \
--interface=if-tunnel-0 \
--peer-ip-address=169.254.21.2 \
--peer-asn=65020 \
--region=europe-west1

# Repeat for tunnel 1 with 169.254.22.1/30 and peer .22.2

5. Configure the VPNGeek side

In the dashboard open Gateways > Tunnels and add a tunnel to each HA VPN interface IP from step 1. Force IKE version 2, use the matching per-tunnel shared secret, and configure the BGP peering to mirror the Cloud Router.

# Tunnel to HA VPN interface 0
peer_address: 198.51.100.40 # HA VPN interface 0 IP
ike_version: 2
proposal: aes256-sha256 # phase 1 & 2
dh_group: 14
psk: <tunnel-0-psk>
# BGP peering (mirrors the Cloud Router):
inside_local: 169.254.21.2/30
inside_peer: 169.254.21.1
local_asn: 65020
peer_asn: 65010
advertise: 10.20.0.0/16

# Second tunnel → 198.51.100.41, 169.254.22.2/30, tunnel-1 psk

# CLASSIC VPN alternative (single tunnel, static routing) uses
# local_subnet 10.20.0.0/16 and remote_subnet 10.100.0.0/16
# instead of BGP.
Note. Classic VPN (gcloud compute target-vpn-gateways) supports static route-based or policy-based routing with a single tunnel, but it is being deprecated for many configurations and carries only a 99.9% SLA. Prefer HA VPN for new deployments; use Classic only when a single static tunnel is genuinely all you need.

6. Verify the connection

Both tunnels should report Established on GCP and ESTABLISHED in the VPNGeek dashboard, and the BGP sessions should come up. Check status, then send real traffic from a Compute Engine VM to a host on the VPNGeek side.

# Tunnel detail — look for "Established"
gcloud compute vpn-tunnels describe vpngeek-tunnel-0 \
--region=europe-west1 --format='value(status,detailedStatus)'

# BGP session state and learned routes
gcloud compute routers get-status vpngeek-router \
--region=europe-west1 \
--format='value(result.bgpPeerStatus[].status,result.bgpPeerStatus[].numLearnedRoutes)'

# From a Compute Engine VM in the VPC:
ping 10.20.0.1
# Confirm VPC firewall rules allow ingress from 10.20.0.0/16.

Troubleshooting

Tunnel stuck in First Handshake / negotiating

Usually a per-tunnel shared secret mismatch, or a phase 1/2 proposal mismatch. Confirm IKEv2, aes256-sha256, and DH group 14 on both sides, and that each VPNGeek tunnel uses the secret from its matching gcloud tunnel.

Tunnel established but no traffic

On HA VPN, a BGP session that is not up means no routes exchange. Check get-status shows the peer as established with a non-zero learned-route count, and that VPNGeek is advertising 10.20.0.0/16. Also verify VPC firewall rules permit the traffic.

BGP will not establish

The link-local /30 addresses must line up — Cloud Router uses .1, VPNGeek uses .2 on each /30 — and the ASNs must not be swapped (Cloud Router 65010, VPNGeek 65020). A wrong mask or reused /30 across tunnels is the usual culprit.

Classic VPN no traffic with static routes

Confirm you created a matching route in the VPC pointing 10.20.0.0/16 at the tunnel, and that the remote/local traffic selectors mirror exactly. Policy-based Classic VPN is intolerant of selector mismatches.

Did this guide get you connected?