Overview
AdGuard Home is a network-wide software for blocking ads and tracking. When integrated with WireGuard Easy, all DNS queries from VPN clients are automatically routed through AdGuard Home, providing:- Network-wide ad blocking
- Protection against tracking and phishing
- Customizable DNS filtering rules
- DNS query logging and statistics
- Parental control features
Prerequisites
Before you begin, ensure you have:- A working WireGuard Easy installation
- Docker and Docker Compose installed
- Basic understanding of Docker networking
- (Optional) A reverse proxy setup like Traefik or Caddy for web UI access
Architecture
In this setup:- WireGuard Easy and AdGuard Home run in separate Docker containers
- Both containers connect to a shared Docker network
- WireGuard clients are configured to use AdGuard Home as their DNS server
- iptables rules redirect all DNS traffic (port 53) to AdGuard Home
- AdGuard Home filters DNS queries and forwards clean requests upstream
Installation Steps
sudo mkdir -p /etc/docker/containers/adguard
sudo mkdir -p /etc/docker/volumes/adguard/adguard_work
sudo mkdir -p /etc/docker/volumes/adguard/adguard_conf
sudo chmod -R 700 /etc/docker/volumes/adguard
services:
adguard:
image: adguard/adguardhome:latest
container_name: adguard
restart: unless-stopped
volumes:
- /etc/docker/volumes/adguard/adguard_work:/opt/adguardhome/work
- /etc/docker/volumes/adguard/adguard_conf:/opt/adguardhome/conf
networks:
wg:
ipv4_address: 10.42.42.43
ipv6_address: fdcc:ad94:bacf:61a3::2b
networks:
wg:
external: true
The static IP addresses (10.42.42.43 for IPv4 and fdcc:ad94:bacf:61a3::2b for IPv6) are used by WireGuard clients for DNS resolution. These must match the network configuration in your WireGuard Easy setup.
Modify your existing WireGuard Easy Docker Compose file to connect to the shared network and configure DNS settings.
services:
wg-easy:
image: ghcr.io/wg-easy/wg-easy:latest
container_name: wg-easy
restart: unless-stopped
ports:
- "51820:51820/udp"
- "51821:51821/tcp"
cap_add:
- NET_ADMIN
- SYS_MODULE
sysctls:
- net.ipv4.ip_forward=1
- net.ipv4.conf.all.src_valid_mark=1
- net.ipv6.conf.all.forwarding=1
volumes:
- /etc/docker/volumes/wg-easy:/etc/wireguard
networks:
wg:
ipv4_address: 10.42.42.2
ipv6_address: fdcc:ad94:bacf:61a3::2
environment:
# Web UI Configuration
- WG_HOST=your-domain.com
- PASSWORD=your-secure-password
# DNS Configuration - Point to AdGuard Home
- WG_DEFAULT_DNS=10.42.42.43,fdcc:ad94:bacf:61a3::2b
# Network Configuration
- WG_ALLOWED_IPS=0.0.0.0/0,::/0
- WG_PORT=51820
networks:
wg:
external: true
ipam:
driver: default
config:
- subnet: 10.42.42.0/24
- subnet: fdcc:ad94:bacf:61a3::/64
Access the WireGuard Easy web interface and navigate to Admin → Hooks. Configure the following hooks to redirect all DNS traffic to AdGuard Home:
iptables -A INPUT -p udp -m udp --dport {{port}} -j ACCEPT; ip6tables -A INPUT -p udp -m udp --dport {{port}} -j ACCEPT; iptables -t nat -A PREROUTING -i wg0 -p udp --dport 53 -j DNAT --to-destination 10.42.42.43; iptables -t nat -A PREROUTING -i wg0 -p tcp --dport 53 -j DNAT --to-destination 10.42.42.43; ip6tables -t nat -A PREROUTING -i wg0 -p udp --dport 53 -j DNAT --to-destination fdcc:ad94:bacf:61a3::2b; ip6tables -t nat -A PREROUTING -i wg0 -p tcp --dport 53 -j DNAT --to-destination fdcc:ad94:bacf:61a3::2b; iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -s {{ipv4Cidr}} -o {{device}} -j MASQUERADE; ip6tables -t nat -A POSTROUTING -s {{ipv6Cidr}} -o {{device}} -j MASQUERADE;
iptables -D INPUT -p udp -m udp --dport {{port}} -j ACCEPT || true; ip6tables -D INPUT -p udp -m udp --dport {{port}} -j ACCEPT || true; iptables -t nat -D PREROUTING -i wg0 -p udp --dport 53 -j DNAT --to-destination 10.42.42.43 || true; iptables -t nat -D PREROUTING -i wg0 -p tcp --dport 53 -j DNAT --to-destination 10.42.42.43 || true; ip6tables -t nat -D PREROUTING -i wg0 -p udp --dport 53 -j DNAT --to-destination fdcc:ad94:bacf:61a3::2b || true; ip6tables -t nat -D PREROUTING -i wg0 -p tcp --dport 53 -j DNAT --to-destination fdcc:ad94:bacf:61a3::2b || true; iptables -D FORWARD -i wg0 -j ACCEPT || true; iptables -D FORWARD -o wg0 -j ACCEPT || true; ip6tables -D FORWARD -i wg0 -j ACCEPT || true; ip6tables -D FORWARD -o wg0 -j ACCEPT || true; iptables -t nat -D POSTROUTING -s {{ipv4Cidr}} -o {{device}} -j MASQUERADE || true; ip6tables -t nat -D POSTROUTING -s {{ipv6Cidr}} -o {{device}} -j MASQUERADE || true;
These hooks will redirect ALL DNS traffic from VPN clients to AdGuard Home, regardless of what DNS server they specify. This ensures consistent ad-blocking across all devices.
# Start AdGuard Home
cd /etc/docker/containers/adguard
sudo docker compose up -d
# Restart WireGuard Easy to apply changes
cd /etc/docker/containers/wg-easy
sudo docker compose down
sudo docker compose up -d
http://<your-server-ip>:3000 (or through your reverse proxy)Network Configuration Details
IP Addressing
The setup uses the following IP addressing scheme:| Service | IPv4 Address | IPv6 Address |
|---|---|---|
| WireGuard Easy | 10.42.42.2 | fdcc:ad94:bacf:61a3::2 |
| AdGuard Home | 10.42.42.43 | fdcc:ad94:bacf:61a3::2b |
| VPN Network | 10.42.42.0/24 | fdcc:ad94:bacf:61a3::/64 |
DNS Traffic Flow
- Client → WireGuard: VPN client makes DNS query
- WireGuard → iptables: Traffic enters wg0 interface, matches DNAT rule
- iptables → AdGuard: DNS traffic redirected to AdGuard Home (10.42.42.43)
- AdGuard → Upstream: AdGuard filters query and forwards to upstream DNS
- Response path: Reverse of above, with filtered content
Verification
Test DNS resolution
From a connected VPN client, test DNS resolution:Check AdGuard Home logs
In the AdGuard Home web interface:- Navigate to Query Log
- You should see DNS queries from your VPN clients
- Blocked queries will be marked with a red icon
Verify container connectivity
Optimization
Increase UDP buffer sizes
For better DNS performance under load, increase UDP buffer sizes: File:/etc/sysctl.d/99-adguard.conf
AdGuard Home settings
In the AdGuard Home interface, optimize these settings:-
Settings → DNS settings:
- Enable “Use DNSSEC”
- Enable “Parallel queries”
- Set “Rate limit” to appropriate value (e.g., 20)
-
Filters → DNS blocklists:
- Enable standard AdGuard DNS filter
- Add additional blocklists as needed
- Keep the lists updated automatically
Reverse Proxy Integration
With Traefik
Add these labels to your AdGuard Home service:With Caddy
Add to your Caddyfile:Troubleshooting
DNS queries not being blocked
Issue: Ads still appear despite AdGuard Home running. Solutions:-
Verify DNS traffic is reaching AdGuard Home:
-
Check iptables rules are applied:
-
Ensure VPN client is using correct DNS:
- Check WireGuard client configuration file
- DNS should be set to
10.42.42.43, fdcc:ad94:bacf:61a3::2b
-
Verify AdGuard Home filters are enabled:
- Open AdGuard Home UI
- Go to Filters → DNS blocklists
- Ensure filters are enabled and up to date
Cannot access AdGuard Home web interface
Issue: Cannot connect to AdGuard Home UI. Solutions:-
Check container is running:
-
Verify port binding:
-
Check container logs:
-
Test local connectivity:
DNS resolution extremely slow
Issue: DNS queries take several seconds to resolve. Solutions:-
Check AdGuard Home upstream DNS servers:
- Avoid using too many upstream servers
- Choose geographically close servers
- Consider using
1.1.1.1or8.8.8.8
-
Increase cache size in AdGuard Home:
- Go to Settings → DNS settings
- Increase “Cache size” (default is 4MB)
- Apply UDP buffer optimizations (see Optimization section)
-
Check for DNS loops:
VPN clients can’t reach internet
Issue: Connected to VPN but no internet access. Solutions:-
Verify IP forwarding is enabled:
-
Check MASQUERADE rules:
-
Verify WireGuard interface is up:
-
Test connectivity from within container:
AdGuard Home container keeps restarting
Issue: AdGuard Home container won’t stay running. Solutions:-
Check container logs:
-
Verify volume permissions:
-
Check for port conflicts:
-
Verify network configuration:
IPv6 not working
Issue: IPv4 works but IPv6 DNS queries fail. Solutions:-
Verify IPv6 is enabled on host:
-
Check IPv6 forwarding:
-
Verify ip6tables rules:
-
Test IPv6 connectivity:
Advanced Configuration
Custom DNS rewrites
You can configure custom DNS entries for local services:- In AdGuard Home, go to Filters → DNS rewrites
- Add custom entries, for example:
server.local→192.168.1.100*.homelab.local→192.168.1.50
Parental controls
Enable content filtering for specific clients:- Go to Settings → Parental control
- Enable parental control
- Configure blocked services and content categories
Per-client settings
Create different filtering rules for different VPN clients:- Go to Settings → Client settings
- Add client by IP address (from VPN subnet)
- Configure custom filtering rules, upstream DNS, or schedules
HTTPS/TLS for DNS
Configure DNS-over-HTTPS or DNS-over-TLS:- Go to Settings → Encryption settings
- Upload SSL certificates (or use Let’s Encrypt)
- Enable DNS-over-HTTPS and/or DNS-over-TLS
- Update VPN client configurations to use secure DNS
Complete Docker Compose Example
Here’s a complete example combining WireGuard Easy, AdGuard Home, and Traefik:Security Considerations
- Firewall rules: Only expose necessary ports (51820/udp for WireGuard)
- Strong passwords: Use strong, unique passwords for both services
- Regular updates: Keep both WireGuard Easy and AdGuard Home updated
- HTTPS access: Always use HTTPS for web interfaces (via reverse proxy)
- Rate limiting: Enable rate limiting in AdGuard Home to prevent DNS abuse
- Query logging: Be mindful of privacy - configure appropriate log retention