AdGuard Home¶
Network-Wide DNS Protection
AdGuard Home is a network-wide software for blocking ads & tracking. It operates as a DNS server that re-routes tracking domains to a "black hole," thus preventing your devices from connecting to those servers. Unlike browser extensions, AdGuard Home protects all devices on your network without requiring individual configuration.
Why Choose AdGuard Home?¶
- Network-wide ad blocking - protect all devices at once
- Privacy-focused - no telemetry or cloud dependencies
- Encrypted DNS - DNS-over-HTTPS and DNS-over-TLS
- Lightweight - minimal resource usage with local caching
Install¶
Infrastructure as Code
This AdGuard Home instance is deployed using OpenTofu with custom Incus images. The infrastructure configuration manages container provisioning and persistent storage volumes.
Custom AdGuard Image
The AdGuard Incus image is built and maintained at forgejo.benoit.jp.net/Benoit/Laminar.
Infrastructure Configuration¶
The OpenTofu configuration provisions:
- Incus instance running custom AdGuard Home image with macvlan networking
- Two persistent storage volumes:
/opt/adguard/data- Query logs, statistics database, and filtered data/var/backups/adguard- Backup storage
Macvlan Networking
The AdGuard container uses a macvlan network interface instead of the default Incus bridge. This gives the container its own IP address directly on the LAN, which is essential for a DNS server that needs to be reachable by all devices on the network.
Configuration File Location
The AdGuard configuration file (AdGuardHome.yaml) is located at /opt/adguard/AdGuardHome.yaml (outside the persistent data volume) and must be backed up separately during upgrades.
resource "incus_storage_volume" "adguard_opt_adguard_data" {
name = "adguard_opt_adguard_data"
pool = incus_storage_pool.default.name
config = {
"initial.gid" = "1001"
"initial.uid" = "1001"
"initial.mode" = "700"
}
}
resource "incus_storage_volume" "adguard_var_backups_adguard" {
name = "adguard_var_backups_adguard"
pool = incus_storage_pool.default.name
}
resource "incus_instance" "adguard" {
name = "adguard"
image = "laminar.incus:adguard-0.107.71-1benoitjpnet"
device {
name = "opt_adguard_data"
type = "disk"
properties = {
path = "/opt/adguard/data"
source = incus_storage_volume.adguard_opt_adguard_data.name
pool = incus_storage_pool.default.name
}
}
device {
name = "var_backups_adguard"
type = "disk"
properties = {
path = "/var/backups/adguard"
source = incus_storage_volume.adguard_var_backups_adguard.name
pool = incus_storage_pool.default.name
}
}
device {
name = "eth0"
type = "nic"
properties = {
nictype = "macvlan"
parent = "enp1s0"
}
}
}
Deploy Infrastructure¶
Initial Configuration¶
After provisioning, access the AdGuard Home web interface to complete initial setup:
- Navigate to
http://<container-ip>:3000 - Set admin username and password
- Configure upstream DNS servers (recommended: 1.1.1.1, 8.8.8.8)
- Set DNS bind interface (default: all interfaces, port 53)
- Add blocklists (AdGuard provides default lists, or add custom ones)
Recommended Blocklists
Popular community-maintained blocklists to consider:
Upgrade¶
Incus Image Upgrade
When upgrading to a newer Incus image version, follow these steps to migrate your data.
Critical: Tailscale Global Nameserver Warning
If you are using AdGuard as a Tailscale global nameserver, you must disable it in the Tailscale admin console before upgrading. Updates redeploy the container from scratch, which will:
- Uninstall Tailscale from the container
- Cause DNS resolution to fail for all Tailscale clients
- The new container will receive a different Tailscale IP address
Backup current instance data before upgrading:
Backup AdGuard configuration
Remove old machine from Tailscale (if using Tailscale)
Before upgrading, remove the old AdGuard machine from the Tailscale Admin Console. You'll add the new container as a fresh machine after the upgrade.
Deploy to new Incus image and restore data:
Update OpenTofu configuration
Edit your OpenTofu configuration file to update the image version:
Restore AdGuard configuration
Re-install Tailscale (if needed)
Generate a new auth key from the Tailscale Admin Console.
Update Tailscale Configuration
- Add the new Tailscale IP as a nameserver in Tailscale admin console
- Re-enable the global nameserver with the new Tailscale IP (if previously enabled)
- Test DNS resolution from multiple clients
Verification Required
After restore, verify AdGuard is working properly:
- Check web interface accessibility at
http://<container-ip>:3000 - Verify DNS resolution:
nslookup google.com <adguard-ip> - Test ad blocking with known ad domains
- Confirm all custom settings are preserved
- Check that blocklists are updating
Upgrade Complete
Your AdGuard Home instance is now running on the new Incus image!
Tailscale Integration¶
Why Tailscale + AdGuard?
Perfect combination: Access your private DNS server from anywhere while maintaining security and performance. No need to expose AdGuard to the internet! Use AdGuard as your DNS server even when connected to untrusted networks.
Independent Tailscale Node
Tailscale is installed directly inside the AdGuard container, making it an independent Tailscale node with its own identity on the Tailnet. This is preferable to relying on the Incus host's Tailscale, as it gives AdGuard a stable, dedicated Tailscale IP that doesn't depend on the host's networking configuration.
Getting Authentication Keys
Generate auth keys in the Tailscale Admin Console:
- Reusable: For multiple deployments
- Ephemeral: For temporary testing
- Preauthorized: Skip manual approval
Configure DNS in Tailscale:
- Navigate to Tailscale DNS Settings
- Under Nameservers, add your AdGuard Tailscale IP
- Optionally enable as Global nameserver to override client DNS settings
- Test from a Tailscale-connected device
Security considerations:
- Use tagged devices in Tailscale for better access control
- Configure ACLs to restrict which devices can use AdGuard as DNS
- Enable MagicDNS in Tailscale for seamless name resolution
Troubleshooting¶
Common Issues & Solutions
DNS not resolving
Port 53 already in use
If systemd-resolved is using port 53:
sed -i 's/#DNSStubListener=yes/DNSStubListener=no/' /etc/systemd/resolved.conf
systemctl restart systemd-resolved
Tailscale connectivity issues
Ads not being blocked
- Verify device is using AdGuard as DNS server (check device network settings)
- Confirm blocklists are enabled and recently updated
- Clear device DNS cache
- Check if domain is in query log but not blocked
- Test with different browser/device to isolate issue
Legitimate sites being blocked
- Check query logs in web interface to identify blocked domain
- Add to allowlist:
- Or disable specific blocklist causing false positive
Blocklists not updating
Check for network connectivity issues or blocklist URL accessibility.
Slow DNS resolution
- Check upstream DNS servers are responding quickly
- Monitor system resources (CPU/RAM) - AdGuard should use minimal resources
- Reduce query log retention time in settings
- Consider using faster upstream DNS providers (Cloudflare 1.1.1.1, Google 8.8.8.8)
- Enable DNS caching in AdGuard settings
High memory usage
# Edit configuration file
nano /opt/adguard/AdGuardHome.yaml
# Set smaller values:
querylog:
size_memory: 500
interval: 24h
Web interface slow to load
- Clear query logs from settings
- Reduce statistics retention period
- Check system disk I/O performance
Production Ready
Your AdGuard Home setup is now optimized for production use with:
- Infrastructure as Code deployment with OpenTofu and Incus
- Comprehensive backup and restore procedures
- Tailscale integration for secure remote access
- Troubleshooting guides for common issues
Related Documentation:
- Infrastructure Overview - Complete self-hosting architecture
- Tailscale Setup Guide - VPN configuration details
- AdGuard Home GitHub - Official repository