[HowTo] PiHole + AlgoVPN (optionally using domain name for VPN)

I’ve been trying to make this work a lot of time, and know that I’ve achieved, I let you know how to do this.

AlgoVPN is a VPN solution to make your own VPN. It’s mainly oriented to deploy it to a cloud service, like DigitalOcean, but it also supports a local installation in Ubuntu 16/18. I think that it also works with debian, but haven’t tested yet. If someone tries it please comment about how it’s going.

In the PiHole documentation there’s a How-To having in the same machine PiHole and OpenVPN. It’s a so convenient solution, but I prefer Algo due to the paranoia about the OpenVPN security holes and the option of using it on Android, iOS, Linux and Windows natively, without any third party software in the client.

AlgoVPN has the option of installing an AdBlocking DNS automatically, but I don’t like it at all because you can’t manage it like PiHole.

This has been done in a Ubuntu Server 18.04.1 machine. Posibly it works along other debian based systems, but you’ll have to try in order to know.

The main problem was that after installing PiHole and AlgoVPN (order doesn’t matters, but in the final test AlgoVPN was installed first), PiHole only worked when using the VPN, but DNS queries were not attended from outside.

I found several work arounds involving dnsmasq, that were tedious and didn’t work, mainly because were concieved for OpenVPN. This solution has been made up with iptables. It took me a long time to figure it out because deleting all rules didn’t work. AlgoVPN always worked, however PiHole worked only after installing and before rebooting the machine. After rebooting, 4 rules dissapered form iptables, and adding them again solved the problem. Let’s start with the proccess:

Installing Algo

1.- Install dependencies

sudo apt-get update && sudo apt-get install \
    build-essential \
    libssl-dev \
    libffi-dev \
    python-dev \
    python-pip \
    python-setuptools \
    python-virtualenv -y
sudo apt-get install software-properties-common && sudo apt-add-repository ppa:ansible/ansible
sudo apt-get update && sudo apt-get install ansible python-pip build-essential python-dev
pip install virtualenv
pip install --upgrade pip
git clone https://github.com/trailofbits/algo

2.- Modify Algo files

2A.- Configure users and local DNSs

Modify the file “/algo/config.cfg”

At the top, change the users Dan and Jack to whatever you want, and add more if you need.

In line 48, change dns_encryption to false

In line 54, change dns_servers 1.1.1.1 to 127.0.0.1 and remove the second entry if you want to use PiHole when connected to VPN. Change IPv6 servers just if your machine supports it.

2B.- Using a domain instead a fixed IP (Optional)

Algo only officially supports using a fixed IP, but modifying this, you can use a domain name without problem.

In file “/algo/roles/vpn/defaults/main.yml” modify the line

subjectAltName_IP: "IP:{{ IP_subject_alt_name }}

to

subjectAltName_IP: "DNS:{{ IP_subject_alt_name }}

Personally I recommed duckdns.org, free and so convenient

3.- Execute Algo Installer

cd algo
python -m virtualenv env && source env/bin/activate && python -m pip install -U pip && python -m pip install -r requirements.txt
./algo

If you’re installing Algo to a local machine like me, select option 7, press enter in the following 2 options, write nothing.

Now write your domain name/fixed IP. The following options are in your hands, select what you need and/or want.

Wait AlgoVPN to finish installation, and copy the final message that is like this

        "\"#----------------------------------------------------------------------#\"",
        "\"#                          Congratulations!                            #\"",
        "\"#                     Your Algo server is running.                     #\"",
        "\"#    Config files and certificates are in the ./configs/ directory.    #\"",
        "\"#              Go to https://whoer.net/ after connecting               #\"",
        "\"#        and ensure that all your traffic passes through the VPN.      #\"",
        "\"#                    Local DNS resolver 172.16.0.1                     #\"",
        "\"#                The p12 and SSH keys password is XXXXXXXX             #\"",
        "\"#----------------------------------------------------------------------#\"",

You’ll need the p12 password in order to configure your clients.

Installing PiHole

Execute the following command. It’s the easy but a bit risky way (because an unlikely man in the middle attack)

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

The PiHole installer is so intuitive. You just have to be sure that when selecting the PiHole interface for listening, you choose wlan0/eth0 and not wg0.

Reboot your machine

Fixing the mess

Now, AlgoVPN works perfectly, and PiHole only when you’re using it connected to the VPN. To make it usable from outside, just introduce the following commands.

sudo iptables -A INPUT -p tcp --dport domain -j ACCEPT
sudo iptables -A INPUT -p udp --dport domain -j ACCEPT
sudo iptables -A INPUT -p tcp --dport http -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 4711:4720 -j ACCEPT
sudo dpkg-reconfigure iptables-persistent

The End

Just hoping this helps people save the time I have spent trying to figure out this solution.

Credits for @notDavid and @hduarte github users that helped me here to be able to use a domain name instead a fixed IP.

Thanks to PiHole for having such an awesome DNS solver that is versatile, configurable and easily usable.

Also thanks to AlgoVPN for providing this very well documented VPN solution.

Finally, sorry for my English, I’ve been a while without writing anything longer than 3 lines

First of all, excellent write up. I’ve been running a similar setup with OpenVPN, but this looks much more robust. I am having an issue with the algo install using the pihole for DNS though. Do you mind outlining the address you used for pihole on the eth0 interface? I’m setting this up on a VPS, so maybe that’s where I’m running into issues. Thanks

Interesting setup, it’s the same as mine. It’s really interesting to see, that people figured out the same. One thing differs in my setup. I setup stubby as local dns resolver to benefit from DNS over TLS. Maybe you want that as well.

Thank you so much! This really got me started with AlgoVpn.
I had been thinking of switching from OpenVpn but couldn’t find an alternative tutorial for others.

I wanted AlgoVpn mainly because of IKEv2.

One thing that took me a few hours to figure out why the VPN won’t work initially, then realized I had to port forward 500 and 4500 according to the issue:

Great write up, thank you for this. Have you tried it with Wireguard? Is it working for you?

I didn’t know about Stubby. It looks interesting. DNS over TLS is for Clients to VPN, VPN to Cloudfare or both? Does it block ads?

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

It’s interesting to be able to use PiHole from any other device which is not connected to the VPN

Yes, I think Algo only works with wireguard, and it’s working now

DNS over TLS is how the VPN will answer your queries. Algo points DNS to Pihole, Pihole points it to stubby, wich then sends it to, in my case, Cloudflare, using dns over tls.

Thank you for your feedback, I must be doing something wrong somewhere.

When I ssh into the server and ping a domain, it shows up in pi-hole’s logs, however the DNS requests done on my client (connected through wireguard) are not working at all, no DNS resolution.

Will go through the guide again, I must have missed something!

arent you exposing your public dns to public making this unsafe?

Mmm… what Linux distribution are you using? Sometimes the order to make it work is not the same, for example, in a raspberry pi with Ubuntu server 18.04 works the way here explained, but on a VPS with Ubuntu (16 and 18) works installing first pihole, algo and “fixing the mess”.
If I have time I will update the guide.

I think that the difference is due to the network manager, which was changed in Ubuntu 18 to netplan, but my VPS provider kept the old one in its image.

However, if you don’t want to start again the installation, I think that allowing all the traffic (with iptables) from the VPN subnet will do the trick.

Maybe. But I think a personal server won’t be a bad guys target.

It didn’t pick my OS, I let the script choose on DigitalOcean (so Ubuntu 18.04). I am trying again and will fiddle with iptables.

My clients use ipv6 I believe. So editing the file to have ::1 should be good, right? As I understand it’s the equivalent of 127.0.0.1

edit: hmmm any idea what would be the iptables rule for that?

I don’t understand you. If you’re running it in digitalocean just as a doplet, you couldn’t use pihole with it.

If you’re deploying it to Ubuntu, you should use in the script local installation, not digital ocean.

I’m so sorry but I have no idea about ipv6, never had to use it.

Look for the rules in google, you’ll find it quickly

Sorry if I wasn’t clear.

If I run it on a DO droplet, why can’t I install pi-hole on the same droplet? How would it be different from running on a pi?

I must be cursed. I tried that (setting droplet through algo, then installing pihole, then changing the DNS in wireguard) and sadly, it still doesn’t work for me :frowning: