Adding PiHole DNS and PiVPN in AWS.

This guide assumes you have basic knowledge of Linux, the internet, and AWS.

NOTE: You will need it later. I am not worried about these passwords or IP being shown here. Once completed, this server will be terminated and the IP’s will return back to the AWS pool for the next customer.

Hello everyone, so a few people wanted a tutorial of how I have PiHole setup in AWS for ad-blocking when outside of my house. I created the guide and be nice it’s one of my first I have made. This setup costs an average of $3.50 a month plus taxes. You can also use the guide for PiHole and PiVPN on a Raspberry Pi or hardware on your home network. You will need a static IP and configure port forwarding in your router.

This setup can also give you access to the Pi-Hole using a OpenVPN client on your mobile phones and creating a profile.

Your welcome to comment at the bottom if there are mistakes or you have questions. I am not responsible for extra AWS charges or any other issues which may resolve. (Disclaimer)

Links your need for this project:
https://lightsail.aws.amazon.com

https://pi-hole.net/

https://pivpn.io/

Once your in AWS LightSail you create a new instance.

Select OS Only since we do not want to use pre-built WordPress or other distro’s. Then select Debian 10, I have used Ubuntu with this before, however, with the built-in DNS resolver. There are always performance and other issues.

Make sure of your SSH key, this key is required to access SSH outside of the AWS site, such as using Putty or other ssh applications.

I use the lowest tier plan, the first 30 days is normally free then $3.50 after.

I name my instances for what they are being used for since I already have a Pi-hole with VPN running. I will name this one vpn2.

As you see its pending, building and getting it ready can take between 5-10 minutes.

Once it shows up and running, we can now access it.

Clicking on the command button will open a new window in your browser for SSH.

The first thing we want to do with any new build is updates.

“sudo apt-get update” Updates the repositories

“sudo apt-get dist-upgrade -y” in addition to performing the function of upgrade,
also intelligently handles changing dependencies with new versions
of packages

“sudo apt-get full-upgrade -y”

More information about command lines and apt-get updating can be found here (link)

This may take some time to complete and recommended to reboot after its done.
“sudo reboot”

So, don’t panic when you see the “you have been disconnected” like with a VM, you have to wait a few minutes and then load back into it from the SSH button or reconnect.

Once we are back in the SSH shell, we can get the install link from https://pi-hole.net/

To keep things simple we will use the one-step automated install.

Install command: “curl -sSL https://install.pi-hole.net | bash”
Using your mouse and right-click you can copy & paste into the SSH then “enter”

sudo curl -sSL https://install.pi-hole.net | bash

Enter

Yes, we know and will set one in AWS later on.
Choose the upstream servers you want to use, you can always change them later on. I normally just select google since I will add some custom config on my personal systems.

Enter past the default blacklist, there’s tons of list you can find and add online. Just google them, I have over 1 million domains blocked on my systems. Default is only a few thousand.

Depending on how you configure you can enable PiHole for IPv4 and/or IPv6, I leave this and just continue.

Displaying your systems default IP, now just the same if this was inside your network at home. These are Private IP’s and cant be reached from the internet. I will show you how to set your public IP later and open the ports on the AWS firewall.

To keep things simple, from this point you can “enter” on every screen until it begins installing.

Once installed your get a info window,

Once complete you can minimize this window for now and return to the AWS LightSail main screen.

Once there click on your instance to load its settings.

Continue to the networking tab

Now “create static IP”

For easy management name your IP and click create, it will assign it to the VM automatically.


***ANY PUBLIC IP NOT ATTACHED TO AN INSTANCE WILL BE BILLED MONTHLY. THEY ARE FREE AS LONG AS THEY ARE ATTACHED TO A MACHINE OR SOME INSTANCE.***

Note your public IP and now click “home” at the top.
Click back to your VM and networking tab.

Normally I disable IPv6, its not necessary to work and the benefits from it are small.

On the IPv4 Firewall, we have open ports 22/ssh and 80/web. Depending on your setup and preference, you can close port 80 and manage PiHole only from SSH. For now, we leave it and we are going to add one, port 1194/UDP, this is OpenVPN, and will be using it to access it later on.

So click “add rule”

Continue with “custom” “UDP” “1194” and click create

So now if we open another browser window and http://yourpublicip/admin we should load the PiHoles management page.


I won’t get into how to manage the PiHole, there’s plenty of documentation here. (LINK)

Just remember login on the left and the password we got during the SSH setup.

Now connecting to the server and setup VPN.

Just the same as using PiHoles automated scripts for less complicated setup PiVpn has an automated script as well.

So let’s return to the LightSail Console and click on the SSH shell to load it.

We can visit https://pivpn.io/ for documentation and instructions. However, to save time below is the script your need to paste into the command line and run.

curl -L https://install.pivpn.io | bash

Designed to run on system with little power this is perfect for the small AWS PiHole instance we have.

Note: sometimes the setup will error out because of iptables-persistent. If this happens, run “sudo apt-get install iptables-persistent -y”. Then run the setup again.

You can “enter” through the next few screens until you get to this choice.

At this point we are choosing to use Wireguard VPN or OpenVPN. I personally like OpenVPN and if you followed the instructions above. We already opened the port on the firewall for it to work. So we will use “tab” to select “OpenVPN” and enter.

The next screen ask to verify defaults and we “yes” to continue.

Your leave it at UDP, then 1194 on the next screen.

The excellent thing about this script is it detects PiHole and configures to use it for DNS.

You can “enter” through the next few screens, however, pay attention. Some custom settings can be changed based on how you want it configured. For this project, we are defaulting ahead!

Once complete we will need to add the client’s profiles, this is the OpenVPN profile you configure on your laptop or cell phone to access the PiHoles DNS.

Go ahead and continue with rebooting the VM. Reconnect to it once complete, we are not done with the command line yet.

Each client is recommended to have its own profile, however, you can use the same for all. It’s not recommended, in my instance, I use a separate one for each. I was able to catch some spyware on my son’s phone, if there wasn’t a profile for each then I would have seen the DNS logs but not known which device it was coming from. Use your preference here.

From the command line “pivpn add” then follow the prompts.

After completion your see the config was created in /home/admin/ovpns

So “cd /home/admin/ovpns”

“Dir” will show the profiles, I have “client.ovpn”

Lets “cat client.ovpn”

You need to copy everything it just displayed and save it into a text document with a .ovpn extension not .txt.
My Example:

Client
dev tun
proto udp
remote 18.235.92.78 1194
resolv-retry infinite
nobindremote-cert-tls server
tls-version-min 1.2
verify-x509-name ip-172-26-4-22_c326a007-79ba-4d47-b78e-f127d7b7faa7 name
cipher AES-256-CBC
auth SHA256
auth-nocache
verb 3
<ca>
-----BEGIN CERTIFICATE-----MIIBtjCCAVygAwIBAgIUda5Fkk59yVPqu3Rz5ZdZAWO74BkwCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIQ2hhbmdlTWUwHhcNMjEwNDE2MTg0NjQyWhcNMzEwNDE0MTg0NjQyWjATMREwDwYDVQQDDAhDaGFuZ2VNZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABAy56Aswi+dj4ktjYLXKe3uc0YxDiAI2JZn3a/FZKVACWgPuHPo9bqODYa5m2fyiwPNCUdhzfNkdOwfBzk9Nh3SjgY0wgYowHQYDVR0OBBYEFBvTKqPNBWru9PvuhwUc2uPBTqTyME4GA1UdIwRHMEWAFBvTKqPNBWru9PvuhwUc2uPBTqTyoRekFTATMREwDwYDVQQDDAhDaGFuZ2VNZYIUda5Fkk59yVPqu3Rz5ZdZAWO74BkwDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwCgYIKoZIzj0EAwIDSAAwRQIhALBnw+r0ai94ueJ7ps1w1xC+XYDZbiQkWjvdqNpREP6sAiAaa4AUMLEPTwRIhoymMEzmPew7qCPSLmum0PQATuHw8Q==
-----END CERTIFICATE-----
</ca>
<cert>
-----BEGIN CERTIFICATE-----MIIBxDCCAWmgAwIBAgIRAJiyN4gnakw9HjNwoxCzRj8wCgYIKoZIzj0EAwIwEzERMA8GA1UEAwwIQ2hhbmdlTWUwHhcNMjEwNDE2MTg1MTQyWhcNMjQwMzMxMTg1MTQyWjARMQ8wDQYDVQQDDAZjbGllbnQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASFzFLBQkRQSYAyF1dd/lIENTIeN5xKqjjA0/y1/JCkt7g0Oi/vSagegujcWqG9fK8Nf8Py78VhFOnBtbAkM8zio4GfMIGcMAkGA1UdEwQCMAAwHQYDVR0OBBYEFBUjG0oS0EQrkWfovGZix/AFOGniME4GA1UdIwRHMEWAFBvTKqPNBWru9PvuhwUc2uPBTqTyoRekFTATMREwDwYDVQQDDAhDaGFuZ2VNZYIUda5Fkk59yVPqu3Rz5ZdZAWO74BkwEwYDVR0lBAwwCgYIKwYBBQUHAwIwCwYDVR0PBAQDAgeAMAoGCCqGSM49BAMCA0kAMEYCIQCpz8ZwEYsCv4VyLqKbwYz6l/WUSf08w8YO2+9BuGowZwIhAIWKkWb0rdpl2KvJRtG/V3PY+OJYiuAYJCGaJHvO/+99
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN ENCRYPTED PRIVATE KEY-----MIHjME4GCSqGSIb3DQEFDTBBMCkGCSqGSIb3DQEFDDAcBAiWtwdcRhPAgAICCAAwDAYIKoZIhvcNAgkFADAUBggqhkiG9w0DBwQIS68aC/tgnjUEgZBiHvdYiYGB2ePCu52DJVHzRULJKLuFUUbWMjwX7E8Xp7M3iaP3F4Ak65O8FRBz1UcWh9Fdzsb1pDZLyISPzjJukIJQUtNd2I6XJzqX+XP3pE5mlugNwTw3/r/vVJEpM7RL2xeTM4Up2WGhDDkMwKoDxaBGeUmrLwnFWT+pJt5afUVRAuOeDMbnUw+GMva9d1c=
-----END ENCRYPTED PRIVATE KEY-----
</key>
<tls-crypt>
## 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----7b9021f8a226b5e62d5857c9eb162547b5a33d63168e588eefb7c63c9cf2d5bdeee6b29f7e467d64730a6166fa16b572077f993cec6f318c4b22fb862ddde38fee528c568c853e4a32b64315573a7f5f49d543717b3103ca0a07f6b87982d89f89723369665582eb0b0f29f3a8789041a48911433d292a5e8ec59b159f5a78a6b15793a13b952a3ec487ead4bb6c9757e080a16de4c1ab99274e952181ee4740d71fcb6e062c04cc8c33472659ba33dbd5661b36065c6312f3db08aa9557d722443944806dc3b32e538b1fc13a55db8dcb95e7fde507d737d45964c20395ed0e208e038992cc25feabffa062b907ef1e2d9c222eb3e2900dd2e88c45c92d247b
-----END OpenVPN Static key V1-----
</tls-crypt>

Notes and Other things to know!

  1. Two things you want to make sure is not in here, is:
    push “redirect-gateway def1” -Change to “# push “redirect-gateway def1””
    1. NOTE:–we want to set this to ignore if so, add a # in front of it. This can show a different “def1” if so # any “push redirect-gateway”, leaving this will push all traffic outbound through AWS as well. Resulting in large bills, removing and adding the one below pushes only DNS through AWS to the pihole, all other traffic exits your network normally. DNS traffic typically consists of a few hundred megabytes per system per month.
  2. Now if it’s not there, we need to add: push “dhcp-option DNS 10.8.0.1”
    1. push “dhcp-option DNS 10.8.0.1” -We want to add this if missing, this sets your systems DNS to be the pihole. This gives all clients the DNS of the PiHole.
  3. Another is block-outside-dns
    1. “block-outside-dns” –Adding this to the script blocks the use of outside DNS other than the one provided above.

Once you have the script complete and saved as a .ovpn document. Download the OpenVPN application from here. (LINK). Once installed import your profile and enter the password you provided during the “pivpn add”.

Now that you have your first client up, you should see its activity in pihole web interface. You can test your DNS configuration here at https://www.dnsleaktest.com/.

There is a lot of other things you can add to this configuration like DNSSEC for encrypted DNS.

https://docs.pi-hole.net/guides/misc/tor/dnssec/

If you have two PiHole devices you can use Gravity Sync to keep their settings and block list synced. For example, I have a PiHole on my local home network and one in AWS for my cell phones and mobile devices. Using Gravity Sync, I can sync the settings between the two so when I block a domain on one its synced to the other.
https://github.com/vmstan/gravity-sync

Disclaimer: I am not resonsible for charges, damages or any other