One Click Wireguard Vpn on Google Cloud

Share on:

Our goal

We want a one click location to fire-up a VPN in the US to watch Netflix content not accessible in at your current location. Such solution could also be useful to watch some iplayer in the UK and probably some other thing

We will be using

  • Google cloud for hosting our VPS
  • Wireguard to connect to the vps
  • Home assistant (hosted on docker on raspbetty piOS) - for the one click component

We won't be using commercial VPN solution because where is the fun in that ?

Prerequisites

  • Home Assistant is up and running into a docker instance. This guide will help
  • You have created a google cloud account
  • You have installed google cloud command line utilities
  • You have installed wireguard on your raspberry pi but no need to configure it. We will use it to generate keys. This tutotial will help (all the way until the begining of section 1.3)

Configure google tools and create a project

Whilst logged in as the same user that is running homeassistant, run the following command and follow the instruction to initialize the gcloud tools.

1$ gcloud init

Generate Wireguard Keys

We will need two pairs of public/private keys for our VPN. One pair that will be on your device (I will use an iphone) and one pair that will be on your VPS

For the VPS

Run the following commands on your raspberry pi to generate a pair of keys. DO NOT REUSE THE KEY FROM THE CODE BELOW

1$ umask 0077
2$ wg genkey > serverprivate.key
3$ wg pubkey < serverprivate.key > serverpublic.key
4$ cat serverprivate.key 
5QCpUc3hMSLPtCMu4uLbIvSOBxR3GKDO+PKqu43f2gWM=
6$ cat serverpublic.key 
7xvULXWNUAKC4oJXhVfBPAureSCdLV7yBOIghC5cBGh0=

For your android / iPhone

Repeat the operation above to generate a second key pair. DO NOT REUSE THE KEY FROM THE CODE BELOW

1$ umask 0077
2$ wg genkey > iphoneprivate.key
3$ wg pubkey < iphoneprivate.key > iphonepublic.key
4$ cat iphoneprivate.key 
5qBsvi+rF4qCpB7Urge3SD9oQ07K0MOJCkpE+kvQzF1c=
6$ cat iphonepublic.key 
7xWei2SY4bHGowNLhyVdxTrZtBqiSQ7n0gy7WEwjG8BM=

Create a freedns dynamic domain name

Everytime you will fire up the VPS, Google is likely to allocate you a different IP address (unless you want to reserve an IP address and pay for it). To avoid having to refresh the VPN configuration everytime, we are going to register a dynamic domain name using the FreeDNS service. Everytime we start our VPS we will refresh the IP associated with the domain name

  1. Register an account if you don't have one already and login
  2. Click on the Dynamic DNS page [shortcut)[https://freedns.afraid.org/dynamic/]
  3. Add a new subdomain. I chose "vpndemo.chickenkiller.com".Don't bother about the IP for now. Fill the capcha and complete the registration
  4. Go back to the Dynamic DNS page [shortcut)[https://freedns.afraid.org/dynamic/]
  5. You domain name should be at the bottom and there should be something called Direct URL next to it. Copy that link. It should look like https://freedns.afraid.org/dynamic/update.php?VERYLONGSERIESOFLETTERSANDNUMBERS

Everytime you click that link or call it with wget, the associated with your domain name will be updated with the origin IP address

Generate a private IPV6

Go to this page and you will be granted with a generate private ipv6. To me it displayed:

1Combined/CID:	  fd16:d37a:a39c:6530::/64
2IPv6 addresses:	  fd16:d37a:a39c:6530:xxxx:xxxx:xxxx:xxxx

Fire-up a VM just to check everything is working

Let's start with spinning up a cmpute instace manually. gcloud should prompt you whether to enable the compute API and you should respond yes Once the instance is up we try to connect to it using the glcoud ssh function

NB: we will be using f1-micro instances which are powerful enough to run a VPN and also part of the free quota that google offers every month.

 1$ gcloud compute instances create wireguard-vps --zone=us-east1-b --machine-type=f1-micro --create-disk=image-project=ubuntu-os-cloud,image=ubuntu-2010-groovy-v20210315,size=10GB --network-interface=address="",network-tier=STANDARD
 2API [compute.googleapis.com] not enabled on project [1XXXX]. 
 3Would you like to enable and retry (this will take a few minutes)? 
 4(y/N)?  y
 5
 6Enabling service [compute.googleapis.com] on project [1XXXX]...
 7Operation "operations/acf.p2-1XXXX-4dc6f929-ceae-4fef-a826-b0019e8c634a" finished successfully.
 8Created [https://www.googleapis.com/compute/v1/projects/homeassistant-293616/zones/us-east1-b/instances/wireguard-vps].
 9NAME           ZONE        MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP     STATUS
10wireguard-vps  us-east1-b  f1-micro                   10.142.0.2   35.211.172.190  RUNNING
11
12$ gcloud compute ssh wireguard-vps
13[Follow the steps to create an ssh key]

Assuming all went well you can now terminate the instance

1$ gcloud compute instances delete wireguard-vps --zone=us-east1-b -q

Our compute instances won't be accessible on the internet unless we open a port in firewall. This is a command you have to run once only

1gcloud compute firewall-rules create wireguard --allow tcp:22,udp:51820,icmp
2Creating firewall...⠹Created [https://www.googleapis.com/compute/v1/projects/homeassistant-293616/global/firewalls/wireguard].                                                                                    
3Creating firewall...done.                                                                                                                                                                                         
4NAME       NETWORK  DIRECTION  PRIORITY  ALLOW           DENY  DISABLED
5wireguard  default  INGRESS    1000      tcp:22,udp:51820,icmp        False

Write the script to start and terminate your instances

First we will write the host script whhich we will call start_vpn.sh. This shell script will be uploaded and run on the instance

 1#!/bin/bash
 2
 3# No need for man pages on the instance and this will speed up deployment
 4sudo apt-get remove -y --purge man-db
 5
 6# install kernel headers 
 7apt update
 8apt install linux-headers-$(uname -r) wget --assume-yes
 9
10# update the free DN address
11wget https://freedns.afraid.org/dynamic/update.php?VERYLONGSERIESOFLETTERSANDNUMBERS
12
13# install wireguared.
14apt install wireguard --assume-yes
15
16WIREGUARD_KEY="QCpUc3hMSLPtCMu4uLbIvSOBxR3GKDO+PKqu43f2gWM="  # your server private key
17CLIENT_KEY="xWei2SY4bHGowNLhyVdxTrZtBqiSQ7n0gy7WEwjG8BM=" #your iphone public key
18
19# detect the name of the default network interface
20INTERFACE=`ip link | grep DEFAULT | grep -v LOOPBACK | awk 'BEGIN {FS=" "}{print $2}' | awk 'BEGIN {FS=":"}{print $1}'`
21
22umask 077
23echo $WIREGUARD_KEY >/etc/wireguard/privatekey
24wg pubkey < /etc/wireguard/privatekey > /etc/wireguard/publickey
25
26# Write the config file of the VPN to disk
27cat >/etc/wireguard/wg0.conf <<EOF
28[Interface]
29Address = 192.168.1.1/24,fd16:d37a:a39c:6530::1/128 # use your private IP ADDRESS here adding 1 in the end
30SaveConfig = false
31ListenPort = 51820
32PrivateKey = $WIREGUARD_KEY
33PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o $INTERFACE -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o $INTERFACE -j MASQUERADE
34PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o $INTERFACE -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o $INTERFACE -j MASQUERADE
35
36[Peer] #android
37PublicKey = $CLIENT_KEY
38AllowedIPs = 192.168.1.2/32,fd16:d37a:a39c:6530::2/128 # use your private IP ADDRESS here adding 2 in the end
39EOF
40
41# fire up the VPN
42wg-quick up wg0
43
44# ENABLE IPV4 outing
45sysctl -w net.ipv4.ip_forward=1

Then we will write the start_instance.sh script that will create the instance, upload the start_vpn.sh file to it and execute it

1#!/bin/bash
2
3echo "creating instance"
4gcloud compute instances create wireguard-vps --zone=us-east1-b --machine-type=f1-micro --create-disk=image-project=ubuntu-os-cloud,image=ubuntu-2010-groovy-v20210315,size=10GB --network-interface=address="",network-tier=STANDARD
5sleep 10 # wait for sshd to start 
6gcloud compute scp start_vpn.sh wireguard-vps:
7gcloud compute ssh wireguard-vps --command="sudo bash start_vpn.sh"

Then the delete_instance.sh

1#!/bin/bash
2
3gcloud compute instances delete wireguard-vps --zone=us-east1-b -q

NB: You can also terminate the instance from the google cloud console

Configure the VPN on your device

We are going to write the wireguard config script on the phone then upload it with a Qr code

 1[Interface]
 2PrivateKey = qBsvi+rF4qCpB7Urge3SD9oQ07K0MOJCkpE+kvQzF1c=  # iphone private key
 3Address = 192.168.1.2/32,fd16:d37a:a39c:6530::2/128 
 4DNS = 1.1.1.1, 1.0.0.1
 5
 6[Peer]
 7PublicKey = xvULXWNUAKC4oJXhVfBPAureSCdLV7yBOIghC5cBGh0= ## Server public key
 8AllowedIPs = 0.0.0.0/0, ::0/0
 9Endpoint = vpndemo.chickenkiller.com:51820
10

then install qrencode on your raspberry pi and generate a qrcode that you can scan on your iphone

1$ sudo apt install qrencode
2$ qrencode -t ansiutf8 < iphone.conf

Test

  1. Make sure your instance is running
  2. Fire up the VPN on your device
  3. Go to this website or search what is my IP in your search engine
    • I noticed that sometime I have to restart my browser to ensure it take into account the new VPN