1.9.1 Classic VPN - grzzboot/pingpong-service GitHub Wiki

Classic VPN - static routing

This part shows how to set up the simpler, but less production attractive solution, Classic VPN. It's obviously less attractive since it is non-high availability and also in this showcase we'll use static routing. It is possible to use dynamic routing even with Classic VPN, which somewhat increases its attractiveness, but still the non-HA factor is a significant limitation for production systems.

Get connected

This article assumes that you've performed the steps in the parent article.

To be able to connect the two different projects and networks we first need to create a Classic VPN gateway on each site. Once we have that we can create tunnels on either side with matching config and they should auto-connect to each other.

Let's start by setting up the pingpong-site1-gcp-demo-VPN. First we must create a static public IP that the VPN Gateway there can use:

gcloud compute addresses create pingpong-site1-vpn-gateway-ip --region=europe-west3

Use the list command to obtain the IP that was allocated, you'll need it in the scripts below.

> gcloud compute addresses list


NAME                               ADDRESS/RANGE  TYPE      PURPOSE       NETWORK  REGION        SUBNET                 STATUS
pingpong-site1-vpn-gateway-ip      <GATEWAY_IP>   EXTERNAL                         europe-west3                         ...

Then create the gateway, and the basic forwarding rules that ties the gateway to the allocated IP, using the following commands and replacing GATEWAY_IP with the allocted IP:

gcloud compute target-vpn-gateways create "pingpong-site1-vpn-gateway" \
  --region "europe-west3" \
  --network "pingpong-site1-net"
gcloud compute forwarding-rules create "pingpong-site1-vpn-gateway-rule-esp" \
  --region "europe-west3" \
  --address "<GATEWAY_IP>" \
  --ip-protocol "ESP" \
  --target-vpn-gateway "pingpong-site1-vpn-gateway"
gcloud compute forwarding-rules create "pingpong-site1-vpn-gateway-rule-udp500" \
  --region "europe-west3" \
  --address "<GATEWAY_IP>" \
  --ip-protocol "UDP" \
  --ports "500" \
  --target-vpn-gateway "pingpong-site1-vpn-gateway"
gcloud compute forwarding-rules create "pingpong-site1-vpn-gateway-rule-udp4500" \
  --region "europe-west3" \
  --address "<GATEWAY_IP>" \
  --ip-protocol "UDP" \
  --ports "4500" \
  --target-vpn-gateway "pingpong-site1-vpn-gateway"

After having done this we can go to the pingpong-site2-gcp-demo-project and do basically the same stuff there. Don't forget to replace GATEWAY_IP with what gets allocated in this project:

gcloud compute addresses create pingpong-site2-vpn-gateway-ip --region=europe-west3
gcloud compute target-vpn-gateways create "pingpong-site2-vpn-gateway" \
  --region "europe-west3" \
  --network "pingpong-site2-net"
gcloud compute forwarding-rules create "pingpong-site2-vpn-gateway-rule-esp" \
  --region "europe-west3" \
  --address "<GATEWAY_IP>" \
  --ip-protocol "ESP" \
  --target-vpn-gateway "pingpong-site2-vpn-gateway"
gcloud compute forwarding-rules create "pingpong-site2-vpn-gateway-rule-udp500" \
  --region "europe-west3" \
  --address "<GATEWAY_IP>" \
  --ip-protocol "UDP" \
  --ports "500" \
  --target-vpn-gateway "pingpong-site2-vpn-gateway"
gcloud compute forwarding-rules create "pingpong-site2-vpn-gateway-rule-udp4500" \
  --region "europe-west3" \
  --address "<GATEWAY_IP>" \
  --ip-protocol "UDP" \
  --ports "4500" \
  --target-vpn-gateway "pingpong-site2-vpn-gateway"

Ok, great! Now we have two gateways available. Let's create a tunnel on either side to hook up the networks to each other.

Remember that VPN:s are a two side story. It's going to be red and failing until both sides are ready and have agreed, so you'll need to configure both projects before you can tell if you got it right or not!

Switch back to pingpong-site1-gcp-demo-project and run the following to create a tunnel, remember to replace the <SITE-2-GATEWAY_IP> with the IP of the gateway in pingpong-site2-gcp-demo-project:

 gcloud compute vpn-tunnels create pingpong-site1-vpn-gateway-tunnel-1 \
  --peer-address <SITE-2-GATEWAY_IP> \
  --ike-version 2 \
  --shared-secret verysecret1 \
  --local-traffic-selector=0.0.0.0/0 \
  --remote-traffic-selector=0.0.0.0/0 \
  --target-vpn-gateway pingpong-site1-vpn-gateway\
  --region europe-west3

After having created the tunnel, let's create a static route and a firewall rule as well. The route is the rule that will send traffic from the network of site-1 through the tunnel and into the network of site-2. The firewall rule will allow traffic from site-2 to enter the network of site-1.

The network route:

gcloud compute routes create pingpong-site1-vpn-gateway-tunnel-1-route-pingpong \
  --destination-range 172.22.0.0/15 \
  --next-hop-vpn-tunnel pingpong-site1-vpn-gateway-tunnel-1 \
  --network pingpong-site1-net \
  --next-hop-vpn-tunnel-region europe-west3

The firewall rule:

gcloud compute firewall-rules create pingpong-site2-allow-all \
  --direction=INGRESS \
  --priority=1000 \
  --network=pingpong-site1-net \
  --action=ALLOW \
  --rules=all \
  --source-ranges=172.23.128.0/17

Note: --rules=all might not be a great choice for production! Consider specifying protocols and ports specifically.

Ok, now switch to the pingpong-site2-gcp-demo-project and run the following to do the same there, remember to replace the <SITE-1-GATEWAY_IP> with the IP of the gateway in pingpong-site1-gcp-demo-project:

gcloud compute vpn-tunnels create pingpong-site2-vpn-gateway-tunnel-1 \
  --peer-address <SITE-1-GATEWAY_IP> \
  --ike-version 2 \
  --shared-secret verysecret1 \
  --local-traffic-selector=0.0.0.0/0 \
  --remote-traffic-selector=0.0.0.0/0 \
  --target-vpn-gateway pingpong-site2-vpn-gateway\
  --region europe-west3
gcloud compute routes create pingpong-site2-vpn-gateway-tunnel-1-route-pingpong \
  --destination-range 172.20.0.0/15 \
  --next-hop-vpn-tunnel pingpong-site2-vpn-gateway-tunnel-1 \
  --network pingpong-site2-net \
  --next-hop-vpn-tunnel-region europe-west3
gcloud compute firewall-rules create pingpong-site1-allow-all \
  --direction=INGRESS \
  --priority=1000 \
  --network=pingpong-site2-net \
  --action=ALLOW \
  --rules=all \
  --source-ranges=172.21.128.0/17

That should be all!

Note, it may take up to a few minutes for tunnel, routes and rules to get setup, so don't panic if you don't see the services recovering immediately.

If you check your logs of both services you should see something similar to:

2020-09-19 16:51:57.490 DEBUG 1 --- [nio-8080-exec-1] c.g.s.p.resource.PingResourceController  : Ping complete: PingResource(message=Pong Site2), duration: 0 ms.
2020-09-19 16:51:58.879 DEBUG 1 --- [   scheduling-1] c.g.s.p.r.s.PingPongScheduledService     : Successfully Pinged service: Pong Site1
2020-09-19 16:52:02.490 DEBUG 1 --- [nio-8080-exec-7] c.g.s.p.resource.PingResourceController  : Ping complete: PingResource(message=Pong Site2), duration: 0 ms.
2020-09-19 16:52:03.879 DEBUG 1 --- [   scheduling-1] c.g.s.p.r.s.PingPongScheduledService     : Successfully Pinged service: Pong Site1
2020-09-19 16:52:07.492 DEBUG 1 --- [nio-8080-exec-4] c.g.s.p.resource.PingResourceController  : Ping complete: PingResource(message=Pong Site2), duration: 0 ms.

In the logs there are indications both of messages coming in from the other site and messages being sent to the other site.

Clean up!

Remember to clean up your resources and DON'T forget to release VPN Gateway IP-addresses no longer in use or you'll be charged significantly.

High availability setup

To try out a more production quality setup refer to the High-Availability VPN article.

⚠️ **GitHub.com Fallback** ⚠️