VPN, secure and ads-free! WireGuard+PiHole


In this tutorial, we are going to install and configure WireGuard+Pi-hole with Docker to make our personal VPN, which it’s going to be secure and ads-free.

WireGuard is an extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography. It aims to be faster, simpler, leaner, and more useful than IPsec, while avoiding the massive headache. It intends to be considerably more performant than OpenVPN. WireGuard is designed as a general purpose VPN for running on embedded interfaces and super computers alike, fit for many circumstances.

Pi-hole is a Linux network-level advertisement and Internet tracker blocking application which acts as a DNS sinkhole and optionally a DHCP server, intended for use on a private network.

We are going to start editing our docker-compose file:

$ nano docker-compose.yaml
version: '3.8'

services:  

  wireguard:
    image: linuxserver/wireguard
    container_name: wireguard
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
   environment:
      - PUID=1000
      - PGID=1000
      - TZ=America/Argentina/Mendoza
      - SERVERPORT=51820
      - PEERS=2 #this is how many client I want
    volumes:
      - /path/to/our/wireguard/config:/config
      - /path/to/our/wireguard/lib/modules:/lib/modules
      - /usr/src:/usr/src
    ports:
      - 51820:51820/udp
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
    dns:
      - 172.0.0.10 #this is the internal docker ip of pihole
    restart: unless-stopped
    networks:
      lan:
        ipv4_address: 172.0.0.5

  pihole:
    container_name: pihole
    image: pihole/pihole
    expose:
      - "53"
      - "67"
      - "80"
      - "443"
    environment:
      TZ: 'America/Argentina/Mendoza'
      WEBPASSWORD: '12345678' #we can access pihole web with this pass
    volumes:
      - /path/to/pihole/etc-pihole/:/etc/pihole/
      - /path/to/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/
    cap_add:
      - NET_ADMIN
    restart: unless-stopped
    networks:
      lan:
        ipv4_address: 172.0.0.10

networks:
  lan: #name of the network subnet
    ipam:
      config:
        - subnet: 172.0.0.0/24

Now we can start our new containers with:

$ docker-compose up -d

We can check the status of the containers, not only with command “$ docker ps”, we can also use docker-compose (I prefer this command because it’s more readable):

$ docker-compose ps

Firewall

We need to open the firewall for 51820, depending on what OS are you using we are going to use a different command. In this case, I’m using Ubuntu 20.04 LTS and Ubuntu use UFW as firewall:

$ sudo ufw allow 51820

We can check this new rule with:

$ sudo ufw status

We also are going to need to open our edge router/home router. This also depend on what router do you use. I’m using a Mikrotik, so we need to go to IP>Firewall>Add New, and set up the Chain as “forward”, Protocol “TCP”, Destination Port 51820 and the Action “accept”. We also need to open 51820 on UDP, so go to IP>Firewall>Add New, and set up the Chain as “forward”, Protocol “UDP”, Destination Port 51820 and the Action “accept”.

Open 51820 port on Mikrotik using Winbox

Connecting clients (peers)

Now we need to connect our clients to the WireGuard server. The first step for this is installing WireGuard client. After the installation, we are going to need a peer.conf file or the QR code (for smartphones). We can find the peer.conf file on:

/path/to/our/wireguard/config/peer1/peer1.conf

Because we detail the numbers of peers in the docker-compose file, now we have the same amount of peers folders. We can upload this config file using transfer.sh following this tutorial.

If we want to connect our smartphone via QR code, we are going to check WireGuard logs typing:

$ docker logs wireguard
QR peer code on WireGuard log

Looking in the WireGuard’s logs file, we are going to see every QR peers code. In the android app, we are going to select “Add Tunnel” and the “Scanning QR code”. We can also download the peer.conf file and installed, but I think it’s faster with the QR.

WireGuard app on Android

Testing

We can quickly check if everything it’s okay doing a dig test connected to the VPN:

$ dig google.com
$ dig ads.google.com

I add “@172.20.0.7” because in that scenario I’m not using pihole as my default DNS, so adding that I can force 172.20.0.7 (my pihole IP) as DNS server.

Now we can check in our browser if pihole it’s working fine:

WireGuard Off

WireGuard On

We can test pihole too:

Done! Personal VPN wherever we are, with secure and ads-free connection.


Update (14 July 2022) :

Adding IP/domain to pi-hole to remove YouTube Ads.

One user on Reddit discovered doing some tcpdumps that if you do a nslookup on one domain that YouTube use for their ads, you can block that IP and stop the ads on your videos.

$ nslookup manifest.googlevideo.com
Server:		127.0.0.53
Address:	127.0.0.53#53

Non-authoritative answer:
Name:	manifest.googlevideo.com
Address: 142.251.133.46
Name:	manifest.googlevideo.com
Address: 2800:3f0:4002:809::200e

If we now do a new nslookup on that IP:

$ nslookup 142.251.133.46
46.133.251.142.in-addr.arpa	name = eze10s02-in-f14.1e100.net.

Authoritative answers can be found from:

Now go to your pi-hole dashboard, login, Blacklist and add this domain and IP:

Now you don’t have any ads on YouTube, the only thing I still don’t figure out, it’s how to remove this:

I mean, I know that clicking the “x”, but I don’t want that this empty rectangle shows up.


Update (03 Sep 2022) :

If trying to run docker-compose an error of binding ports like this appears:

ERROR: for pihole  Cannot start service pihole: driver failed programming external connectivity on endpoint pihole (306d268570ea188d68cee54de648ef24fdo3294fee3b0a4851c493c2793): Error starting userland proxy: listen udp4 0.0.0.0:53: bind: address already in use

Use lsof to check the binding ports, in this case DNS port 53

$ sudo lsof -i :53
matiasm@home-server:~/docker$ sudo lsof -i :53
[sudo] password for matiasm:
COMMAND   PID            USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
systemd-r 786 systemd-resolve   13u  IPv4  22331      0t0  UDP 127.0.0.53:domain
systemd-r 786 systemd-resolve   14u  IPv4  22332      0t0  TCP 127.0.0.53:domain (LISTEN)

Unbind systemd-resolve from port 53:

$ sudo systemctl disable systemd-resolved.service
Removed /etc/systemd/system/multi-user.target.wants/systemd-resolved.service.
Removed /etc/systemd/system/dbus-org.freedesktop.resolve1.service.
$ sudo systemctl stop systemd-resolved

Now edit resolved.conf

$ sudo nano /etc/systemd/resolved.conf

DNS=127.0.0.1
DNSStubListener=no

2 thoughts on “VPN, secure and ads-free! WireGuard+PiHole”

  1. Pingback: Apps for Android that every SRE should try – the admin notes

  2. Pingback: Networking with Linux: commands, services and more – the admin notes

Leave a Comment

Your email address will not be published. Required fields are marked *