Creating your own VPN with PiHole & UnBound on AWS


In this blog post we will:

  • Create our own VPN on AWS
  • Add PiHole to iit
  • Use Unbound as our DNS resolver
  • Access the VPN using Wireguard
  • Not go bankrupt doing it!

Step 1

Create an AWS lightsail instance on Amazon.

We use Lightsail instead of EC2 because EC costs £0.12 / GB on outbound transfers. That means for 1 TB / month it’ll cost £120.

Lightsail costs £3.50 / month and comes with 1 TB outbound transfer already.

We are saving £116.50 by using Lightsail over EC2.

  1. Create a new Lightsail instance (Ubuntu)
  2. Manually configure, and click through each step until you get to Security groups, and add the following: Custom UDP, Port Range: 51820, Source:, and Description: Wireguard
  3. Download your new keypair and save it to .ssh
  4. Click Elastic IP to create an Elastic IP, then click actions and associate, and associate the Elastic IP to your new server

Step 2

Connect to your new instance.

ssh -i /Users/[your user]/.ssh/PiVPNHOLE.pem ubuntu@[your host]

Step 3

Install PiHole

curl -sSL | bash
  • Take note of your PiHole’s web interface IP and the password

Step 4

Install PiVPN. This will automatically make a Wireguard VPN for us.

curl -L | bash

Step 5

Creatr your user profiles.

pivpn add -n <config name>
  • where [config name] is a unique name for each of your devices (e.g., mphone, mlaptop). You can repeat this step for as many devices that you want to connect to your Pi-hole.

Step 6

Display the QR codes to connect our mobile devices.

pivpn -qr [config name, e.g., mphone]

Step 7

Download the configs for our desktops.

scp -i /Users/[Your Name]/.ssh/PiVPNHOLE.pem ubuntu@[your host]:~/configs/[config name, e.g., mlaptop] [destination on your computer, e.g., ~/Documents/wireguard]

An example is:

scp -i /Users/example/.ssh/PiVPNHOLE.pem /Users/example/wireguard

This will download all of your config files to a folder on your computer called wireguard

Step 8

Install Wireguard on your devices.

  • Scan your QR code for your mobile devices, and/or install the downloaded configs for your laptop/desktop/other devices, turn them on.
  • I set them to “on-demand” meaning it’ll always be on
  • Go check out your PiHole at the address you saved in Step 2!

Step 9

Install Unbound. Unbound is a recursive DNS resolver. At first, it’ll be slow as it caches our DNS but over time it’ll be faster. It’s also privacy friendly!

  • Follow this guide
  • One thing to note, when you get to Configure Unbound instruction, it’ll say /etc/unbound/unbound.conf.d/pi-hole.conf, you actually need to add sudo nano to the start of that code in your Terminal to be able to create and paste in the configuration (or else you’ll just get an error). Then just copy/paste in the text from the guide and hit save/exit. sudo nano /etc/unbound/unbound.conf.d/pi-hole.conf.

Split Tunnel VPN

This step is not needed.

sudo nano /etc/wireguard/configs/[config name].conf

Change AllowedIPs from “, ::0” to “[PiHole IP address]/32, [DNS IP]/32”. The [DNS IP] is listed in [interface] and by default Note spit-tunnelling only routes the DNS (i.e., PiHole ad-blocking) vs., all of your data through your VPN which will save bandwidth to keep you on the free tier. You’ll need to repeat this for each [config name] you created in step 5.


  • Before being able to remotely log in, I had to run the command chmod 600 /Users/[your name]/.ssh/PiVPNHOLE.pem
  • After clicking “generate keys” in PiVPN, you may get /tmp/setupVars.conf permission denied. I solved this by deleting that file.
  • You may need to run the piVpn script as sudo. Run with curl -L | sudo bash