WireGuard VPN + PiHole Setup
07/08/2024
Introduction
Unlike the other separate guides for PiHole and WireGuard, in this guide we will see how to set up a VPN server with advertisement blocking capabilities using Wireguard and PiHole, essentially merging both and making them work together for a more seamless process.
Why combine WireGuard and PiHole?
Combining WireGuard with Pi-Hole offers a powerful duo for enhancing both privacy and network security. WireGuard provides a secure, encrypted VPN tunnel that protects your data and masks your online activities from external threats. Meanwhile, Pi-Hole blocks unwanted ads, trackers, and malicious domains at the network level, improving browsing speed and protecting your privacy. Together, they create a robust setup where your online traffic is both encrypted and free from intrusive ads, ensuring a safer and more enjoyable internet experience.
Installation
If you already have either PiHole or WireGuard setup separately - make sure to remove them altogether, so that we can add both at once and put them in the same subnet and assign static IPs for them.
Before proceeding, make sure to hash your desired password by running the below command:
docker run -it ghcr.io/wg-easy/wg-easy wgpw YOUR_PASSWORD
The output will be a bcrypt hash like: "$2y$10$hBCoykrB95WSzuV4fafBzOHWKu9sbyVa34GJr8VV5R/pIelfEMYyG"
Since we will be using docker-compose, anywhere you have the "$" symbol, make sure to add an extra one, so "$$" and copy the hash.
Now, we can proceed with the rest:
-
Create and open the directory
mkdir wireguard && cd wireguard -
Create a docker file
nano docker-compose.yml -
Paste the below and replace "your_hash" with the hash you've made in the previous steps:
version: "3" volumes: etc_wireguard: services: wg-easy: environment: # Change Language: # (Supports: en, ua, ru, tr, no, pl, fr, de, ca, es, ko, vi, nl, is, pt, chs, cht, it, th, hi) - LANG=en # Required: - WG_HOST=172.20.1.3 # Optional: - PASSWORD_HASH=your_hash # - WG_PORT=51820 # - WG_DEFAULT_ADDRESS=10.8.0.0 # - WG_DEFAULT_ADDRESS_RANGE=24 # - WG_DEFAULT_DNS=1.1.1.1 # - WG_MTU=1420 - WG_ALLOWED_IPS=0.0.0.0/0, ::/0 # - WG_PERSISTENT_KEEPALIVE=25 # - WG_PRE_UP=echo "Pre Up" > /etc/wireguard/pre-up.txt # - WG_POST_UP=echo "Post Up" > /etc/wireguard/post-up.txt # - WG_PRE_DOWN=echo "Pre Down" > /etc/wireguard/pre-down.txt # - WG_POST_DOWN=echo "Post Down" > /etc/wireguard/post-down.txt # - UI_TRAFFIC_STATS=true # - UI_CHART_TYPE=0 (0 # Charts disabled, 1 # Line chart, 2 # Area chart, 3 # Bar chart) image: ghcr.io/wg-easy/wg-easy container_name: wg-easy volumes: - etc_wireguard:/etc/wireguard ports: - "51820:51820/udp" - "51821:51821/tcp" restart: unless-stopped cap_add: - NET_ADMIN - SYS_MODULE sysctls: - net.ipv4.ip_forward=1 - net.ipv4.conf.all.src_valid_mark=1 networks: wg-easy: ipv4_address: 172.20.1.2 pihole: container_name: pihole image: pihole/pihole:latest # For DHCP it is recommended to remove these ports and instead add: network_mode: "host" labels: - "com.centurylinklabs.watchtower.enable=false" ports: - "53:53/tcp" # Host Port:Container Port - "53:53/udp" # - "67:67/udp" # Only required if you are using Pi-hole as your DHCP server - "80:80/tcp" environment: TZ: 'England/London' WEBPASSWORD: 'your_password' # Volumes store your data between container upgrades volumes: - './etc-pihole:/etc/pihole' - './etc-dnsmasq.d:/etc/dnsmasq.d' # https://github.com/pi-hole/docker-pi-hole#note-on-capabilities cap_add: - NET_ADMIN # Required if you are using Pi-hole as your DHCP server, else not needed networks: wg-easy: ipv4_address: 172.20.1.3 restart: unless-stopped networks: wg-easy: ipam: config: - subnet: 172.20.1.0/24 -
Save with
CTRL+X,Y,Enter -
Deploy the container
docker-compose up -d -
Confirm that it deployed successfully
docker ps -
Port Forward port 51820 (UDP) to the host's local IP from the router settings
-
Open the PiHole WebUI at localhost/admin (e.g., 192.168.100.186/admin)
-
Navigate to "Settings -> DNS" and change the DNS provider to Cloudflare and ensure that the Interface Setting is set to "Respond only on interface eth0"
Installation (Client)
- Download the WireGuard from AppStore/GooglePlay
- Navigate to localhost:51821, add user, and generate QR code
- Scan the QR code with the client device
- Ensure the Endpoint is set to PublicIP:51820 and DNS is set to 172.20.1.3, which should be your PiHole's container local IP
Firewall Port Configuration
If you do have a firewall in place, make sure that you've properly allowed the requried ports in the firewall. In case you need assistance with this - check my guide for UFW here.