Skip to content

Instantly share code, notes, and snippets.

@samuelba
Last active January 8, 2022 15:31
Show Gist options
  • Save samuelba/45d65a4972ee0de7712f4b4388d6c114 to your computer and use it in GitHub Desktop.
Save samuelba/45d65a4972ee0de7712f4b4388d6c114 to your computer and use it in GitHub Desktop.
Pi-Hole and AdGuard Home DNS Servers with Wireguard VPN

Ad Blocking DNS Servers with Wireguard VPN

Sources

DHCP Server

Configure only one DHCP server, either AdGuard or Pi-Hole.

Accessible from Host

# Host macvlan bridge recreate.
# See "ip addr" interface name "eth0".
ip link add macvlan-br0 link enp0s25 type macvlan mode bridge
# IP of server (docker host).
ip addr add 192.168.0.5/32 dev macvlan-br0
ip link set macvlan-br0 up
# IP of adguardhome docker container inside MACVLAN.
ip route add 192.168.0.6/32 dev macvlan-br0
# IP of pihole docker container inside MACVLAN.
ip route add 192.168.0.7/32 dev macvlan-br0

Wireguard

Server

Install Wireguard

sudo apt install wireguard

Enable IP forwarding, uncomment net.ipv4.ip_forward = 1 and net.ipv6.conf.all.forwarding = 1 in /etc/sysctl.conf and reload config sudo sysctl --system.

Create public and private keys

mkdir -p wireguard/keys
cd wireguard/keys
umask 077
wg genkey | tee privatekey | wg pubkey > publickey

Create /etc/wireguard/wg0.conf, use the interface name (here br-2c754ed5073d) of the dns_server_bridge Docker bridge network. This is required to access the DNS servers from Wireguard.

[Interface]
Address = 10.4.0.1/24
SaveConfig = true
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o dns_bridge -d 192.168.100.1/28 -j MASQUERADE; iptables -t nat -A POSTROUTING -o enp0s25 ! -d 192.168.100.1/28 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o dns_bridge -d 192.168.100.1/28 -j MASQUERADE; iptables -t nat -D POSTROUTING -o enp0s25 ! -d 192.168.100.1/28 -j MASQUERADE
ListenPort = 51820
PrivateKey = <server-private-key>

Maybe update the firewall rule

sudo ufw allow 51820/udp
sudo ufw enable

Start the Wireguard server

sudo wg-quick up wg0

Start the system service to auto-start the server at bootup

sudo systemctl enable wg-quick@wg0.service

Client

Install Wireguard

sudo apt install wireguard

Create public and private keys

mkdir -p wireguard/keys
cd wireguard/keys
umask 077
wg genkey | tee privatekey | wg pubkey > publickey

Create /etc/wireguard/wg0.conf

[Interface]
PrivateKey = <client-private-key>
Address = 10.4.0.2/32 # use different IP for each client
DNS = <dns-server-comma-separated>

[Peer]
PublicKey = <server-public-key>
Endpoint = <public-server-ip/domain>:51820
AllowedIPs = 10.4.0.0/24 # or just 0.0.0.0/0 to run everything over the server
PersistentKeepalive = 25

Register Client

On the server execute

sudo wg set wg0 peer <client-public-key> persistent-keepalive 25 allowed-ips <client-ip-address>/32
sudo systemctl restart wg-quick@wg0.service
version: "3"
services:
adguardhome:
container_name: adguardhome
image: adguard/adguardhome:latest
hostname: adguardhome
mac_address: 02:aa:bb:cc:dd:ee
cap_add:
- NET_ADMIN
networks:
dns_server_network:
ipv4_address: 192.168.0.6
dns_server_bridge:
ipv4_address: 192.168.100.6
dns:
- 127.0.0.1
- 1.1.1.1
- 8.8.8.8
ports:
- 53/tcp
- 53/udp
# Use either the AdGuard Home as DHCP server or Pi-Hole.
- 67/udp
- 68/udp
- 80/tcp
- 443/tcp
- 443/udp
- 3000/tcp
- 853/tcp
- 853/udp
- 784/udp
- 8853/udp
- 5443/tcp
- 5443/udp
volumes:
- ./adguardhome/work:/opt/adguardhome/work
- ./adguardhome/conf:/opt/adguardhome/conf
restart: unless-stopped
pihole:
container_name: pihole
image: pihole/pihole:latest
hostname: pihole
mac_address: 06:aa:bb:cc:dd:ee
cap_add:
- NET_ADMIN
networks:
dns_server_network:
ipv4_address: 192.168.0.7
dns_server_bridge:
ipv4_address: 192.168.100.7
dns:
- 127.0.0.1
- 1.1.1.1
- 8.8.8.8
ports:
- 53/tcp
- 53/udp
# Use either the AdGuard Home as DHCP server or Pi-Hole.
#- 67/udp
#- 68/udp
- 80/tcp
environment:
TZ: Europe/Zurich
ServerIP: 192.168.0.7
VIRTUAL_HOST: pihole.example.com
WEBPASSWORD: "your-password"
DNSMASQ_LISTENING: local
WEB_PORT: 80
volumes:
- ./pihole/etc-dnsmasq.d:/etc/dnsmasq.d
- ./pihole/etc-pihole:/etc/pihole
restart: unless-stopped
networks:
dns_server_network:
driver: macvlan
driver_opts:
parent: enp0s25
ipam:
config:
- subnet: 192.168.0.0/24
gateway: 192.168.0.1
ip_range: 192.168.0.2/28
aux_addresses:
server: 192.168.0.5
workstation: 192.168.0.10
dns_server_bridge:
driver: bridge
ipam:
config:
- subnet: 192.168.100.0/24
gateway: 192.168.100.1
ip_range: 192.168.100.2/28
driver_opts:
com.docker.network.bridge.name: dns_bridge
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment