How to spin up your own VPN
Tags: privacy, surveillance, vpn
Published: 2021-10-08 03:47:56

## Introduction

There are a plenty of VPN providers out there. What's common between all of them? You can't trust them. They may have a no-log policy but as a company, there is always a tendency that they might share our browsing data to some third party. In this post you'll learn how you can spin up your own VPN with Amazon AWS. 

This post is not necessarily applicable to AWS, but any other IaaS. 

## Prerequisites

I am assuming that you are a **cloud practitioner** and you know your way around to **ssh** into your running **Linux instance**. 

Things you should know before starting. 

- Your EC2 instance is billed hourly.
- The data coming and going out of the instance is charged per GB basis.

`t2.micro` instance type is more than enough for this experiment.

Please check the pricing [here](https://aws.amazon.com/ec2/pricing/on-demand/#On-Demand_Pricing) and [here](https://aws.amazon.com/ec2/pricing/on-demand/#Data_Transfer) and proceed accordingly. It won't cost much if you are doing this for experimental purpose.

## Install OpenVPN Server

OpenVPN is a virtual private network (VPN) system that implements techniques to create secure point-to-point or site-to-site connections in routed or bridged configurations and remote access facilities. It implements both client and server applications.

What a typical VPN provider does is, when you are connected to the VPN provider, every request you make to internet, your source IP is seems to be coming from the VPN provider. The setup we are going to do will have show your EC2 instance's public IP. 

Note: While this post is for educational purpose, I would like to bring it up that you must comply with AWS T&C and your local law. 

### Installation Process

```
sudo -i
curl -O https://raw.githubusercontent.com/angristan/openvpn-install/master/openvpn-install.sh
```

`sudo -i` is to change the current user to root.

The `curl` command downloads the installation script which is the easiest way to install OpenVPN on my Linux servers today.

---

```
./openvpn-install.sh

```

At the given point, my typical installation looks like this:

```
Welcome to the OpenVPN installer!
The git repository is available at: https://github.com/angristan/openvpn-install

I need to ask you a few questions before starting the setup.
You can leave the default options and just press enter if you are ok with them.

I need to know the IPv4 address of the network interface you want OpenVPN listening to.
Unless your server is behind NAT, it should be your public IPv4 address.
IP address: 10.2.1.201
```

Don't creep out if you are doing this installation for the first time. The inputs are auto-filled which works for most users.

---

Next question we get is about the public IP address:

```
It seems this server is behind NAT. What is its public IPv4 address or hostname?
We need it for the clients to connect to the server.
Public IPv4 address or hostname: 13.233.130.22
```

This will also be auto-filled.

---

Next up, we are asked if we want to enable IPv6 connectivity. I am not opting to install IPv6 for this time. I will do some tutorial for that at later time. 

```
Checking for IPv6 connectivity...

Your host does not appear to have IPv6 connectivity.

Do you want to enable IPv6 support (NAT)? [y/n]: n
```

---

Choose a port where OpenVPN will run. I am opting the default port 1194. You may want to change it to something else.

```
What port do you want OpenVPN to listen to?
   1) Default: 1194
   2) Custom
   3) Random [49152-65535]
Port choice [1-3]: 1
```

Next up is the protocol. I prefer UDP as most VPN providers do that.

```
What protocol do you want OpenVPN to use?
UDP is faster. Unless it is not available, you shouldn't use TCP.
   1) UDP
   2) TCP
Protocol [1-2]: 1
```

---

I am going with the default DNS resolver which installer provides. But you are always welcome to change this at your will.

```
What DNS resolvers do you want to use with the VPN?
   1) Current system resolvers (from /etc/resolv.conf)
   2) Self-hosted DNS Resolver (Unbound)
   3) Cloudflare (Anycast: worldwide)
   4) Quad9 (Anycast: worldwide)
   5) Quad9 uncensored (Anycast: worldwide)
   6) FDN (France)
   7) DNS.WATCH (Germany)
   8) OpenDNS (Anycast: worldwide)
   9) Google (Anycast: worldwide)
   10) Yandex Basic (Russia)
   11) AdGuard DNS (Anycast: worldwide)
   12) NextDNS (Anycast: worldwide)
   13) Custom
DNS [1-12]: 11
```

---


```
Do you want to use compression? It is not recommended since the VORACLE attack make use of it.
Enable compression? [y/n]: n

Do you want to customize encryption settings?
Unless you know what you're doing, you should stick with the default parameters provided by the script.
Note that whatever you choose, all the choices presented in the script are safe. (Unlike OpenVPN's defaults)
See https://github.com/angristan/openvpn-install#security-and-encryption to learn more.

Customize encryption settings? [y/n]: n

Okay, that was all I needed. We are ready to setup your OpenVPN server now.
You will be able to generate a client at the end of the installation.
Press any key to continue...
```

I am not enabling any compression for this time. 
I am not customizing any encryption this time.
That's all we need to do to continue installation.

---

Depending on your distro type, the installer will use the package manager to download and install the package.


## Create a Client Config File

As we already discussed in the start of the post, we are doing a single server and single client setup. For each client, we need to create a client configuration.

This configuration is automatically created as part of the OpenVPN installer. Go ahead and give a name to the configuration file.

```
Tell me a name for the client.
The name must consist of alphanumeric character. It may also include an underscore or a dash.
Client name: first-client

Do you want to protect the configuration file with a password?
(e.g. encrypt the private key with a password)
   1) Add a passwordless client
   2) Use a password for the client
Select an option [1-2]: 1

Note: using Easy-RSA configuration from: /etc/openvpn/easy-rsa/vars
Using SSL: openssl OpenSSL 1.0.2k-fips  26 Jan 2017
Generating a 256 bit EC private key
writing new private key to '/etc/openvpn/easy-rsa/pki/easy-rsa-9322.WOFVgi/tmp.kkk8CD'
-----
Using configuration from /etc/openvpn/easy-rsa/pki/easy-rsa-9322.WOFVgi/tmp.CneLJl
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'first-client'
Certificate is to be certified until Jan  7 02:07:48 2024 GMT (825 days)

Write out database with 1 new entries
Data Base Updated

Client first-client added.

The configuration file has been written to /home/ec2-user/first-client.ovpn.
Download the .ovpn file and import it in your OpenVPN client.
```

As you can see, the key file has been written to disk at `/home/ec2-user/first-client.ovpn`.

### Download the key file to your own system

As you saw the last section, the config file is located at `/home/ec2-user`. 

The next task is to download this ovpn file to my local system. I like to use scp, a cousin of ssh to do this.

```
scp -i /path/to/key.pem ec2-user@xxx.xxx.xxx.xxx:/home/ec2-user/first-client.ovpn .
```

I get the `first-client.ovpn` on my local machine. With this key in your hand, you can use this to connect a vast kind of devices, including Windows, MacOS, Linux, Android and iOS.

## Install VPN client on local machine

There might be other implementation of VPN clients, but I use OpenVPN Connect on my machine. You can get it here: 

<img src="https://s3.ap-south-1.amazonaws.com/santoshk.dev-blog/2021/Screenshot+2021-10-04+083428.png" alt="https://openvpn.net/vpn-client/" />

<center><sup>https://openvpn.net/vpn-client/</sup></center>

I have OpenVPN Connect installed on my machine and ready to take in the `.ovpn` config file we downloaded from the remote instance.

<img src="https://s3.ap-south-1.amazonaws.com/santoshk.dev-blog/2021/Screenshot+2021-10-04+084836.png" alt="OpenVPN Connect on my local machine" position="center" />
<center><sup>OpenVPN Connect on my local machine</sup></center>

Before we go ahead and have a private connection between you and your instance. We need to allow connection from internet to this instance.

## Open port on the EC2 instance

At this point of time, if you are installing OpenVPN on the server, you might have connected via SSH. I assume your port 22 is open. 

Similarly, we need to create a new hole in our firewall to allow OpenVPN connections on the choice of port we chose while installing. The default port is **1194**.

Create a security group called `openvpn` and create an inbound rule with these settings:

<img src="https://s3.ap-south-1.amazonaws.com/santoshk.dev-blog/2021/Screenshot+2021-10-04+085348.png" alt="Allow incoming traffic from 1194" position="center" />
<center><sup>Allow incoming traffic from 1194</sup></center>

Go ahead and attach it to the running instance which is running the OpenVPN server.

You may as well wish to tighten the security here (by providing CIDR/IP ranges in Source field) so that not everyone on the internet is able to connect to us. On the other hand, if you wish to share this VPN with everyone and want to charge then leave it to 0.0.0.0/0.

## Connect your computer to the VPN server

You just need to click "Browse" in the panel shown below and browse to the `.ovpn` file.

<img src="https://s3.ap-south-1.amazonaws.com/santoshk.dev-blog/2021/Screenshot+2021-10-04+084836.png" alt="Browse the config file on local computer" position="center" />
<center><sup>Browse the config file on local computer</sup></center>

After a connection has been made, you should see something like this:

<img src="https://s3.ap-south-1.amazonaws.com/santoshk.dev-blog/2021/Screenshot+2021-10-04+092307.png"  alt="An active VPN connection" position="center" />
<center><sup>An active VPN connection</sup></center>

## Conclusion

You can go ahead and configure this connection at the router level (assuming you have router capable of that) so that all the clients inside the network can be benefited. 

In next post, I might come up with ways to block malware and tracker with our VPN connection.

If you are having trouble or have any suggestion, please leave a comment and we can discuss.