5$/month Self Hosted VPN with WireGuard
Tags: vpn, privacy
Published: 2021-04-01 11:07:34

---
title: "5$/month Self Hosted VPN with WireGuard"
tags:
  - vpn
  - privacy
cover_image: https://images.unsplash.com/photo-1549927455-67cc16cc490c?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&auto=format&fit=crop&w=600&q=80
published: true
canonical_url: https://cri.dev/posts/2021-02-01-5-dollar-easy-self-hosted-vpn-setup/
---

**Originally posted on [cri.dev](https://cri.dev/posts/2021-02-01-5-dollar-easy-self-hosted-vpn-setup/)**

This will take you less than 5 minutes to get a private VPN on your own Ubuntu server.

---

What you need to get started:

- a VPS (Ubuntu 20.04 LTS preferrably)
- docker and docker-compose installed

## Setting up docker-compose

On the VPS, I suggest to do the following:

Create a folder `wireguard/config` in your $HOME:

```
mkdir -p wireguard/config
```

Inside the `wireguard` folder (next to the `config` folder), create the docker-compose file:

```
vim docker-compose.yml
```

With the following contents:

```
version: "2.1"
services:
  wireguard:
    image: linuxserver/wireguard
    container_name: wireguard
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Rome
      - SERVERURL=YOUR_IP_OR_DNS_NAME_OF_YOUR_SERVER #optional
      - SERVERPORT=51820
      - PEERS=5
    volumes:
      - /home/YOUR_USERNAME/wireguard/config:/config
      - /lib/modules:/lib/modules
    ports:
      - 51820:51820/udp
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
    restart: always
```

Simply change the `SERVERURL` variable, or delete that line if you want to use the server IP.

Additionally, change the location of your wireguard config path in the `volumes` section. (use `pwd` to get the current path you are in).

**For more info and environment variables, check out the official [linuxserver/wireguard doc](https://hub.docker.com/r/linuxserver/wireguard).**

I've used `restart: always` so that WireGuard comes up after a system restart.

Changed `PEERS` to 5, so that I have 5 configurations available for my devices. 

## Launching the container

Start the container in the background with

```
docker-compose up -d
```

This will create the needed configurations in the `wireguard/config` folder.

The structure of your `wireguard` folder looks something like this

```
.
├── config
│   ├── coredns
│   │   └── Corefile
│   ├── peer1
│   │   ├── peer1.conf
│   │   ├── peer1.png
│   │   ├── privatekey-peer1
│   │   └── publickey-peer1
.............................
│   ├── server
│   │   ├── privatekey-server
│   │   └── publickey-server
│   ├── templates
│   │   ├── peer.conf
│   │   └── server.conf
│   └── wg0.conf
└── docker-compose.yml
```

## Firewall configuration

If you're using `ufw`, simply enable the port `51820` so that you can connect to your server from outside:

```
ufw enable 51820
ufw reload
```

If you run `sudo ufw status` you should see:

```
Status: active

To                         Action      From
--                         ------      ----
....................................................
51820                      ALLOW       Anywhere
51820 (v6)                 ALLOW       Anywhere (v6)
```

## Connecting devices

Now you can `cat` or `scp` the configurations individually to your devices.

The configurations are located in the `config/peerX` folder, where `X` represents the peer number.

E.g. I could `cat/scp` the configuration in `wireguard/config/peer1/peer1.conf` and put it in `/etc/wireguard/wg0.conf` on my host machine.

View the configuration for peer 1 on your server with

```
cat /home/YOUR_USERNAME/wireguard/config/peer1/peer1.conf
```

and place it in `/etc/wireguard/wg0.conf` on your host machine.

If you want to use `scp`, you could run the following on your local machine:

```
scp USER@SERVER:/home/YOUR_USERNAME/wireguard/config/peer1/peer1.conf /etc/wireguard/wg0.conf
```

To connect to your newly created WireGuard VPN from one of your devices, you'll need to install `wireguard-tools`.

E.g. `apt install wireguard-tools` , `pacman -S wireguad-tools` based on your distro

[Here you can find a more detailed explanation](https://www.wireguard.com/install/)

Now you can simply run **`wg-quick up wg0`** and you're connected to your VPN.

Test it out by running `curl ipinfo.io` and inspect the output.

## Connecting mobile device with QR code

On your mobile device, install the WireGuard client.

Then add a new WireGuard tunnel by creating a new configuration scanning a QR code.

On your VPS run the following to output a QR code on the terminal that you can scan on your mobile device:

```
docker exec -it wireguard app/show-peer 1
```

## Inspecting connections

If you want to understand who is connected and which profiles are in use, simply run the following on your VPS:

```
docker exec -it wireguard wg
```

This will give you more information about your connections with the following output:

```
interface: wg0
  public key: (redacted)
  private key: (hidden)
  listening port: 51820

peer: (redacted)
  endpoint: (redacted):51820
  allowed ips: (redacted)/32
  latest handshake: 27 seconds ago
  transfer: 5.04 MiB received, 172.64 MiB sent

...

peer: (redacted)
  allowed ips: (redacted)/32
```

## Conclusion

This was most definitely the easiest way I found to connect computers and mobile devices to your own WireGuard VPN.

Let me know if you had troubles setting it up yourself!


**Originally posted on [cri.dev](https://cri.dev/posts/2021-02-01-5-dollar-easy-self-hosted-vpn-setup/)**