Network Services beginner ⏱ 30 minutes

AdGuard Home: Modern DNS Filtering for Homelabs

Network-wide ad blocking with encrypted DNS support. DoH, DoT, and advanced filtering rules.

By homelabbing.io • 2025-12-16
#adguard#dns#ad-blocking#privacy#encrypted-dns

Introduction

AdGuard Home is a powerful network-wide ad blocker and DNS server that offers a modern alternative to Pi-hole. With built-in support for DNS-over-HTTPS (DoH), DNS-over-TLS (DoT), DNS-over-QUIC (DoQ), and an intuitive web interface, AdGuard Home provides comprehensive privacy protection with advanced features like per-client configuration, parental controls, and detailed analytics.

By the end of this guide, you’ll have a production-ready AdGuard Home installation that:

  • Blocks ads, trackers, and malicious domains network-wide
  • Provides encrypted DNS using DoH, DoT, or DoQ protocols
  • Offers per-client filtering and configuration
  • Includes comprehensive blocklist management
  • Features automated backup and monitoring
  • Supports mobile device configuration

Prerequisites

Before starting, ensure you have:

  • A Linux server (bare metal, VM, or Raspberry Pi) with at least 512MB RAM
  • Docker and Docker Compose installed
  • Static IP address configured for your server
  • Root or sudo access
  • Basic understanding of DNS and networking
  • At least 5GB free disk space

Why Choose AdGuard Home Over Pi-hole?

AdGuard Home Advantages

Modern Interface: Sleek, responsive web UI that works perfectly on mobile devices with real-time statistics and intuitive configuration.

Native Encryption: Built-in DNS-over-HTTPS, DNS-over-TLS, and DNS-over-QUIC support without requiring additional containers.

Per-Client Rules: Apply different filtering rules, upstream DNS servers, and schedules for individual clients or groups.

Advanced Filtering: Support for AdGuard syntax, hosts files, domain lists, and regular expressions with powerful customization.

Better Performance: Written in Go with efficient memory usage and faster query processing under 100MB of RAM.

Parental Controls: Built-in safe browsing, adult content blocking, and safe search enforcement.

When to Use Pi-hole Instead

  • You prefer dnsmasq’s extensive features
  • You need integration with specific third-party tools designed for Pi-hole
  • You want a larger community and more extensive documentation
  • You’re already familiar with Pi-hole’s ecosystem

Architecture Overview

Our setup consists of:

  1. AdGuard Home: Main DNS server and filtering engine
  2. Encrypted DNS: Built-in DoH/DoT support for upstream queries
  3. Web Interface: Modern dashboard on port 3000
  4. Optional DHCP: Integrated DHCP server for automatic client configuration

The request flow:

  • Clients query AdGuard Home on port 53
  • AdGuard Home checks filtering rules and blocklists
  • Blocked domains return 0.0.0.0 or REFUSED
  • Allowed domains are forwarded to upstream DNS (optionally via DoH/DoT)
  • Responses are cached and returned to clients

Directory Structure Setup

Create the necessary directory structure:

mkdir -p ~/adguard-home/{work,conf,scripts,backups}
cd ~/adguard-home

Docker Compose Configuration

Create a docker-compose.yml file:

version: '3.8'

services:
  adguardhome:
    container_name: adguardhome
    image: adguard/adguardhome:latest
    restart: unless-stopped
    hostname: adguardhome
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "67:67/udp"
      - "68:68/udp"
      - "80:80/tcp"
      - "443:443/tcp"
      - "443:443/udp"
      - "3000:3000/tcp"
      - "853:853/tcp"
      - "853:853/udp"
      - "784:784/udp"
      - "8853:8853/udp"
      - "5443:5443/tcp"
      - "5443:5443/udp"
    volumes:
      - './work:/opt/adguardhome/work'
      - './conf:/opt/adguardhome/conf'
    environment:
      - TZ=America/New_York
    cap_add:
      - NET_ADMIN
    dns:
      - 127.0.0.1
      - 1.1.1.1
    networks:
      - adguard_net

networks:
  adguard_net:
    driver: bridge

Port explanations:

  • 53: Standard DNS
  • 67/68: DHCP server (optional)
  • 80/443: Web interface and DoH
  • 853: DNS-over-TLS
  • 784: DNS-over-QUIC
  • 3000: Initial setup interface
  • 5443: DNSCrypt
  • 8853: DNS-over-QUIC (alternative)

Initial Setup

Start AdGuard Home:

docker-compose up -d

Access the setup wizard at http://YOUR-SERVER-IP:3000

Setup Wizard Steps

  1. Choose Interface and Port:

    • Admin Web Interface: All interfaces, port 80
    • DNS Server: All interfaces, port 53
    • Click “Next”
  2. Create Admin Account:

    • Username: admin (or your preferred username)
    • Password: Use a strong password (at least 12 characters)
    • Click “Next”
  3. Configure Devices:

    • Note the instructions for configuring your router or devices
    • Click “Next”
  4. Complete Setup:

    • Click “Open Dashboard”

The web interface will now be available at http://YOUR-SERVER-IP

Core Configuration

After initial setup, configure these essential settings via the web interface.

DNS Settings

Navigate to Settings DNS settings

Upstream DNS Servers:

Add these encrypted DNS providers (choose your preferred):

# Cloudflare DNS-over-HTTPS
https://dns.cloudflare.com/dns-query

# Cloudflare DNS-over-TLS
tls://1.1.1.1
tls://1.0.0.1

# Quad9 DNS-over-HTTPS (with malware blocking)
https://dns.quad9.net/dns-query

# Google DNS-over-HTTPS
https://dns.google/dns-query

# NextDNS (replace YOUR-CONFIG-ID)
https://dns.nextdns.io/YOUR-CONFIG-ID

Bootstrap DNS Servers (for resolving DoH/DoT hostnames):

1.1.1.1
8.8.8.8
9.9.9.9

DNS Server Configuration:

  • Enable “Enable DNSSEC”
  • Enable “Enable EDNS Client Subnet” (for better CDN performance)
  • Set “Rate limit” to 20 (queries per second per client)
  • Enable “Use DNSSEC”
  • Set “Blocking mode” to “REFUSED” or “NXDOMAIN”

DNS Cache Configuration:

  • Enable “Enable caching”
  • Set “Cache size” to 4 MB or higher
  • Set “Minimum TTL” to 300 seconds
  • Set “Maximum TTL” to 86400 seconds

Encryption Settings

Navigate to Settings Encryption settings

Enable DNS-over-HTTPS:

For a simple setup using the built-in certificate:

  • Enable “Enable DNS-over-HTTPS”
  • Server name: YOUR-SERVER-IP or adguard.yourdomain.com
  • Let AdGuard Home generate a self-signed certificate (or provide your own)

Enable DNS-over-TLS:

  • Enable “Enable DNS-over-TLS”
  • Use the same certificate as DoH

For production with Let’s Encrypt:

If you have a domain name, use Let’s Encrypt:

# Install certbot
sudo apt update
sudo apt install certbot

# Get certificate
sudo certbot certonly --standalone -d adguard.yourdomain.com

# Copy certificates to AdGuard directory
sudo cp /etc/letsencrypt/live/adguard.yourdomain.com/fullchain.pem ~/adguard-home/conf/
sudo cp /etc/letsencrypt/live/adguard.yourdomain.com/privkey.pem ~/adguard-home/conf/
sudo chown $USER:$USER ~/adguard-home/conf/*.pem

Then in AdGuard Home:

  • Set certificate path: /opt/adguardhome/conf/fullchain.pem
  • Set private key path: /opt/adguardhome/conf/privkey.pem

Advanced Blocklist Management

AdGuard Home’s filtering is its most powerful feature. Here’s how to configure it optimally.

Navigate to Filters DNS blocklists Add blocklist

General Ad Blocking:

  • AdGuard DNS filter: https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt
  • EasyList: https://easylist-downloads.adblockplus.org/easylist.txt
  • AdAway Default: https://adaway.org/hosts.txt
  • Steven Black Hosts: https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts

Privacy and Tracking:

  • EasyPrivacy: https://easylist.to/easylist/easyprivacy.txt
  • Peter Lowe’s List: https://pgl.yoyo.org/adservers/serverlist.php?hostformat=adblockplus&showintro=0
  • Fanboy’s Enhanced Tracking: https://secure.fanboy.co.nz/enhancedstats.txt

Malware and Security:

  • Malware Domain List: https://www.malwaredomainlist.com/hostslist/hosts.txt
  • URLHaus: https://urlhaus.abuse.ch/downloads/hostfile/
  • Phishing Army: https://phishing.army/download/phishing_army_blocklist.txt

Social Media Tracking:

  • Fanboy’s Social Blocking: https://easylist.to/easylist/fanboy-social.txt
  • Block Facebook: https://www.github.developerdan.com/hosts/lists/facebook-extended.txt

Regional Lists (add if applicable):

  • RU AdList: https://easylist-downloads.adblockplus.org/advblock.txt
  • CHN: Anti-AD: https://anti-ad.net/easylist.txt

Custom Filtering Rules

Navigate to Filters DNS blocklists Custom filtering rules

Block specific domains:

||ads.example.com^
||tracker.example.com^
||analytics.facebook.com^

Block entire TLDs or patterns:

||.ad^
||*.doubleclick.net^
||metric*^

Allow exceptions (whitelist):

@@||important-domain.com^
@@||subdomain.example.com^

Block using regex:

/^ad[sxv]?[0-9]*.*/
/tracker[0-9]+\..*

DNS Rewrites

Navigate to Filters DNS rewrites

Create custom DNS responses for local services:

Local service mappings:

homeassistant.local -> YOUR-SERVER-IP
plex.local -> 192.168.1.100
nas.local -> 192.168.1.50

Block with custom response:

ads.example.com -> 0.0.0.0

Per-Client Configuration

One of AdGuard Home’s most powerful features is per-client settings.

Client Identification

Navigate to Settings Clients

Add a client:

  1. Click “Add client”
  2. Name: “John’s iPhone”
  3. Identifiers: Add MAC address or IP (e.g., 192.168.1.101)
  4. Configure:
    • Use global settings (or override)
    • Use global upstream DNS servers (or specify different ones)
    • Filtering enabled (or disabled for this client)
    • SafeBrowsing enabled
    • Parental control enabled

Per-client upstream DNS:

Example for a client that needs to bypass filtering:

Client: Work Laptop
Upstream DNS: 8.8.8.8
Disable filtering: Yes

Schedule-based filtering:

Use custom blocking schedules via API or configuration file editing.

Client Groups

Create groups for easier management:

Kids Devices Group:

  • Enable parental controls
  • Enable safe search
  • Block adult content
  • Custom blocklist with gaming sites during homework hours

IoT Devices Group:

  • Disable most filtering
  • Only block malware/phishing
  • Use fast local DNS

Guest Network Group:

  • Basic ad blocking only
  • Separate upstream DNS
  • Limited logging

Parental Controls and Safe Browsing

Navigate to Settings General settings

Safe Browsing:

  • Enable “Use AdGuard browsing security web service”
  • Blocks malware, phishing, and fraudulent sites

Parental Control:

  • Enable “Use AdGuard parental control web service”
  • Blocks adult content sites

Safe Search:

  • Enable “Enforce safe search”
  • Forces safe search on Google, Bing, YouTube, Yandex, DuckDuckGo

Custom Parental Rules:

Add to Custom filtering rules:

# Block social media during school hours (requires external automation)
||facebook.com^
||instagram.com^
||tiktok.com^
||snapchat.com^

# Block gaming sites
||twitch.tv^
||gaming.youtube.com^

DNS-over-HTTPS Configuration for Clients

Configure various clients to use your AdGuard Home DoH server.

Desktop Browsers

Firefox:

  1. Settings Network Settings Settings
  2. Enable “Enable DNS over HTTPS”
  3. Use “Custom” provider
  4. Enter: https://YOUR-SERVER-IP/dns-query

Chrome/Brave:

  1. Settings Privacy and security Security
  2. Enable “Use secure DNS”
  3. Select “With Custom”
  4. Enter: https://YOUR-SERVER-IP/dns-query

Edge:

  1. Settings Privacy, search, and services Security
  2. Enable “Use secure DNS”
  3. Choose “Custom” and enter: https://YOUR-SERVER-IP/dns-query

Mobile Devices

iOS (iPhone/iPad):

Install a DoH/DoT profile or use apps:

  1. Using Encrypted DNS Profile:

    • Create a mobileconfig profile with your DoH URL
    • Install via Safari
  2. Using DNSCloak (App Store):

    • Install DNSCloak
    • Add custom DoH server: https://YOUR-SERVER-IP/dns-query
    • Enable the profile
  3. Using NextDNS App (configure with AdGuard Home):

    • Use DNS-over-TLS: YOUR-SERVER-IP
    • Port: 853

Android:

  1. Native Private DNS (Android 9+):

    • Settings Network & Internet Advanced Private DNS
    • Select “Private DNS provider hostname”
    • Enter: YOUR-HOSTNAME (requires valid TLS certificate)
  2. Using Intra (App Store):

    • Install Intra by Jigsaw
    • Configure custom DoH: https://YOUR-SERVER-IP/dns-query
  3. Using AdGuard App:

    • Install AdGuard from Play Store
    • Settings DNS filtering DNS server
    • Add custom server: https://YOUR-SERVER-IP/dns-query

Performance Optimization

Cache Configuration

Optimize caching for better performance:

Edit conf/AdGuardHome.yaml:

dns:
  cache_size: 8388608  # 8MB cache
  cache_ttl_min: 300    # 5 minutes minimum
  cache_ttl_max: 86400  # 24 hours maximum
  cache_optimistic: true

Query Logging

Balance between visibility and performance:

Navigate to Settings General settings

Query Log Configuration:

  • Set “Query log retention” to 7 days (or less for better performance)
  • Enable “Anonymize client IP” if you don’t need full IP logging
  • Consider disabling logs for high-traffic clients

Upstream DNS Optimization

Choose geographically close DNS servers:

Test DNS server speed:

# Install dnsperftest
git clone https://github.com/cleanbrowsing/dnsperftest.git
cd dnsperftest
./dnstest.sh

# Or use namebench
sudo apt install namebench
namebench

Add the fastest servers to your upstream DNS list.

Resource Limits

For systems with limited resources, edit docker-compose.yml:

    deploy:
      resources:
        limits:
          cpus: '0.50'
          memory: 256M
        reservations:
          cpus: '0.25'
          memory: 128M

Backup and Restore Procedures

Manual Backup via Web Interface

Navigate to Settings General settings

Scroll to “Configuration” section:

  • Click “Download configuration”
  • Save the AdGuardHome.yaml file

Automated Backup Script

Create a backup script at scripts/backup-adguard.sh:

#!/bin/bash

BACKUP_DIR="./backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_NAME="adguard_backup_$TIMESTAMP"

# Create backup directory
mkdir -p "$BACKUP_DIR"

echo "Starting AdGuard Home backup..."

# Stop container for consistent backup
docker-compose stop

# Backup configuration and data
echo "Backing up configuration and data..."
tar -czf "$BACKUP_DIR/$BACKUP_NAME.tar.gz" work/ conf/

# Start container
docker-compose start

# Keep only last 14 backups
echo "Cleaning old backups (keeping last 14)..."
cd "$BACKUP_DIR"
ls -t adguard_backup_*.tar.gz | tail -n +15 | xargs -r rm

echo "Backup completed: $BACKUP_DIR/$BACKUP_NAME.tar.gz"

Make it executable:

chmod +x scripts/backup-adguard.sh

Automated Backup with Cron

crontab -e

Add this line to run backup daily at 3 AM:

0 3 * * * cd /path/to/adguard-home && ./scripts/backup-adguard.sh >> ./backups/backup.log 2>&1

Restore Procedure

Create a restore script at scripts/restore-adguard.sh:

#!/bin/bash

if [ -z "$1" ]; then
    echo "Usage: $0 backup_file.tar.gz"
    exit 1
fi

BACKUP_FILE="$1"

echo "Restoring from $BACKUP_FILE..."

# Stop container
echo "Stopping AdGuard Home..."
docker-compose down

# Backup current state
echo "Backing up current state..."
mv work work.bak
mv conf conf.bak

# Extract backup
echo "Restoring backup..."
tar -xzf "$BACKUP_FILE"

# Start container
echo "Starting AdGuard Home..."
docker-compose up -d

echo "Restore completed successfully!"
echo "Previous state backed up to work.bak and conf.bak"

Make it executable:

chmod +x scripts/restore-adguard.sh

Monitoring and Analytics

Built-in Statistics

Navigate to Dashboard

View detailed metrics:

  • DNS queries (last 24 hours)
  • Blocked by filters
  • Top queried domains
  • Top blocked domains
  • Top clients
  • Query types distribution
  • Upstream servers response time

Query Log Analysis

Navigate to Query Log

Filter and analyze:

  • Filter by client
  • Filter by domain
  • Filter by status (blocked, allowed, etc.)
  • Filter by upstream
  • Export logs for external analysis

Performance Monitoring Script

Create a monitoring script at scripts/monitor-adguard.sh:

#!/bin/bash

echo "=== AdGuard Home Performance Monitor ==="
echo ""

echo "Container Stats:"
docker stats --no-stream adguardhome
echo ""

echo "Container Status:"
docker-compose ps
echo ""

echo "Disk Usage:"
du -sh work/ conf/
echo ""

echo "Recent Logs:"
docker-compose logs --tail=20 adguardhome
echo ""

echo "Memory Info:"
docker exec adguardhome cat /proc/meminfo | grep -E "MemTotal|MemFree|MemAvailable"

Make it executable:

chmod +x scripts/monitor-adguard.sh

Prometheus Integration

For advanced monitoring, AdGuard Home exposes Prometheus metrics.

Edit conf/AdGuardHome.yaml:

prometheus:
  enabled: true
  address: 0.0.0.0:9091

Add to docker-compose.yml:

    ports:
      - "9091:9091/tcp"

Access metrics at: http://YOUR-SERVER-IP:9091/metrics

Client Configuration

Router Configuration

Configure your router to use AdGuard Home:

  1. Access router admin interface
  2. Navigate to DHCP/DNS settings
  3. Set Primary DNS: YOUR-SERVER-IP
  4. Set Secondary DNS: 1.1.1.1 (fallback)
  5. Save and reboot router

Individual Device Configuration

Windows:

# Run as Administrator
netsh interface ipv4 set dns "Ethernet" static YOUR-SERVER-IP primary
netsh interface ipv4 add dns "Ethernet" 1.1.1.1 index=2

macOS:

networksetup -setdnsservers Wi-Fi YOUR-SERVER-IP 1.1.1.1

Linux:

Using systemd-resolved:

sudo nano /etc/systemd/resolved.conf

Add:

[Resolve]
DNS=YOUR-SERVER-IP
FallbackDNS=1.1.1.1

Restart:

sudo systemctl restart systemd-resolved

iOS:

  1. Settings Wi-Fi [Network Name]
  2. Configure DNS Manual
  3. Add Server: YOUR-SERVER-IP
  4. Save

Android:

  1. Settings Network & Internet Wi-Fi [Network Name]
  2. Advanced IP settings Static
  3. DNS 1: YOUR-SERVER-IP
  4. DNS 2: 1.1.1.1
  5. Save

DHCP Server Configuration

AdGuard Home can replace your router’s DHCP server for better integration.

Enable DHCP

Navigate to Settings DHCP settings

DHCP Server Configuration:

  1. Enable “Enable DHCP server”
  2. Interface: Select your network interface
  3. Gateway IP: Your router’s IP (e.g., 192.168.1.1)
  4. Subnet mask: 255.255.255.0
  5. DHCP IP range:
    • Start: 192.168.1.100
    • End: 192.168.1.200
  6. Lease duration: 86400 (24 hours)
  7. Save

Important: Disable DHCP on your router before enabling it in AdGuard Home to avoid conflicts.

Static Leases

Add static IP assignments:

  1. Click “Add static lease”
  2. MAC address: Device MAC address
  3. IP address: Desired static IP
  4. Hostname: Device name
  5. Save

This ensures devices always get the same IP and enables better client identification.

Advanced Features

DNS Rewrites for Local Services

Navigate to Filters DNS rewrites

Local service discovery:

*.home.lan -> YOUR-SERVER-IP
homeassistant.home.lan -> 192.168.1.100
plex.home.lan -> 192.168.1.101
nas.home.lan -> 192.168.1.102

Blocked Services

Navigate to Filters Blocked services

Enable one-click blocking for common services:

  • YouTube
  • Facebook
  • Instagram
  • TikTok
  • Twitch
  • Discord
  • Reddit

Useful for parental controls or productivity.

Custom DNS Records

Add custom A, AAAA, CNAME records via DNS rewrites:

Example local domain setup:

home.lab -> 192.168.1.1
*.home.lab -> 192.168.1.1
plex.home.lab -> 192.168.1.100

Troubleshooting

Common Issues

Issue: Web interface not accessible

# Check if container is running
docker-compose ps

# Check logs
docker-compose logs adguardhome

# Restart container
docker-compose restart

Issue: DNS queries not being blocked

  1. Verify filters are enabled: Settings DNS blocklists
  2. Check if domain is whitelisted: Filters DNS allowlists
  3. Review query log to see why domain was allowed
  4. Force filter update: Filters DNS blocklists Update

Issue: Slow DNS resolution

# Test DNS response time
dig @YOUR-SERVER-IP google.com

# Check upstream DNS performance
# Navigate to: Settings -> DNS settings -> Test upstreams

# Reduce logging: Settings -> General -> Query log retention

Issue: DoH/DoT not working

  1. Verify certificate is valid and properly configured
  2. Check that ports 443 and 853 are not blocked by firewall
  3. Test with curl:
# Test DoH
curl -H 'accept: application/dns-json' 'https://YOUR-SERVER-IP/dns-query?name=google.com'

# Test DoT
kdig -d @YOUR-SERVER-IP +tls google.com

Health Check Script

Create a health check script at scripts/healthcheck.sh:

#!/bin/bash

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

echo "=== AdGuard Home Health Check ==="
echo ""

# Check container
echo -n "Container status: "
if docker ps | grep -q adguardhome; then
    echo -e "${GREEN}Running${NC}"
else
    echo -e "${RED}Not running${NC}"
    exit 1
fi

# Test DNS resolution
echo -n "DNS resolution test: "
if dig @localhost google.com +short > /dev/null 2>&1; then
    echo -e "${GREEN}Passed${NC}"
else
    echo -e "${RED}Failed${NC}"
fi

# Test ad blocking
echo -n "Ad blocking test: "
RESULT=$(dig @localhost ads.google.com +short | head -1)
if [ -z "$RESULT" ] || [ "$RESULT" = "0.0.0.0" ]; then
    echo -e "${GREEN}Working${NC}"
else
    echo -e "${YELLOW}May not be blocking properly${NC}"
fi

# Check disk space
echo ""
echo "Disk usage:"
df -h | grep -E "Filesystem|/mnt|/$"

# Check memory usage
echo ""
echo "Memory usage:"
docker stats --no-stream adguardhome --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}"

echo ""
echo "Configuration directory size:"
du -sh work/ conf/

Make it executable:

chmod +x scripts/healthcheck.sh

Maintenance Tasks

Create a maintenance script at scripts/maintenance.sh:

#!/bin/bash

echo "=== AdGuard Home Maintenance ==="
echo ""

# Update Docker image
echo "Checking for updates..."
docker-compose pull

# Backup before update
echo "Creating backup..."
./scripts/backup-adguard.sh

# Update filters
echo "Updating DNS filters..."
# Note: Filters update automatically, but can be forced via API
curl -X POST http://localhost:80/control/filtering/refresh

# Restart with new image if updated
echo "Restarting AdGuard Home..."
docker-compose up -d

# Clean old logs (older than 30 days)
echo "Cleaning old query logs..."
find work/data/querylog.json* -mtime +30 -delete 2>/dev/null

echo ""
echo "Maintenance completed!"

Make it executable:

chmod +x scripts/maintenance.sh

Schedule monthly maintenance:

crontab -e

Add:

0 4 1 * * cd /path/to/adguard-home && ./scripts/maintenance.sh >> ./backups/maintenance.log 2>&1

API Access

AdGuard Home provides a comprehensive REST API for automation.

API Authentication

Get your credentials from conf/AdGuardHome.yaml:

users:
  - name: admin
    password: YOUR_BCRYPT_PASSWORD_HASH

Common API Examples

Get statistics:

curl -u admin:password http://YOUR-SERVER-IP/control/stats

Get filtering status:

curl -u admin:password http://YOUR-SERVER-IP/control/filtering/status

Block a domain:

curl -u admin:password -X POST http://YOUR-SERVER-IP/control/filtering/add_url   -H "Content-Type: application/json"   -d '{"name":"Custom Block", "url":"data:text/plain,||example.com^"}'

Query log:

curl -u admin:password http://YOUR-SERVER-IP/control/querylog

Force filters update:

curl -u admin:password -X POST http://YOUR-SERVER-IP/control/filtering/refresh

Security Hardening

Firewall Configuration

Restrict access to AdGuard Home:

# Allow DNS from local network only
sudo ufw allow from 192.168.1.0/24 to any port 53 proto udp
sudo ufw allow from 192.168.1.0/24 to any port 53 proto tcp

# Allow web interface from local network
sudo ufw allow from 192.168.1.0/24 to any port 80 proto tcp
sudo ufw allow from 192.168.1.0/24 to any port 443 proto tcp

# Allow DoT from local network
sudo ufw allow from 192.168.1.0/24 to any port 853 proto tcp

# Enable firewall
sudo ufw enable

Access Control

Edit conf/AdGuardHome.yaml to restrict admin interface:

bind_host: 192.168.1.0/24

Rate Limiting

Configure rate limiting to prevent DNS amplification attacks:

Navigate to Settings DNS settings

Set “Rate limit” to appropriate value (e.g., 20 queries/second per client)

Disable Query Logging for Privacy

If privacy is a concern:

Navigate to Settings General settings

  • Disable “Enable query log”
  • Or set retention to 1 hour minimum

Performance Benchmarks

Expected performance metrics:

  • Query response time: 5-20ms (cached), 50-150ms (uncached with DoH)
  • Memory usage: 50-150MB depending on cache size
  • CPU usage: Under 10% on modern hardware
  • Blocking rate: 10-25% depending on blocklists
  • Cache hit rate: 70-85% after warm-up
  • Supports 1000+ queries/second on modest hardware

Comparison: AdGuard Home vs Pi-hole

FeatureAdGuard HomePi-hole
Setup DifficultyEasierEasy
Web InterfaceModern, mobile-friendlyFunctional, dated
Native DoH/DoTYes, built-inRequires additional containers
Per-client SettingsYes, extensiveLimited
Parental ControlsBuilt-inThird-party blocklists
Memory Usage50-150MB150-300MB with Unbound
Filtering SyntaxAdGuard + hostsHosts + regex
APIComprehensive REST APIBasic API
DHCP ServerBuilt-inBuilt-in
Community SizeGrowingVery large
Update FrequencyRegularRegular
Best ForModern setups, per-client controlPi enthusiasts, established users

Conclusion

You now have a fully functional AdGuard Home installation with:

  • Network-wide ad and tracker blocking
  • Encrypted DNS using DoH, DoT, or DoQ
  • Per-client filtering and configuration
  • Comprehensive blocklist management
  • Automated backups and maintenance
  • Parental controls and safe browsing
  • Mobile device support with encrypted DNS

AdGuard Home provides a modern, efficient, and user-friendly alternative to Pi-hole with advanced features like per-client settings and native encrypted DNS support.

Next Steps

Consider these enhancements:

  • Set up a second AdGuard Home instance for high availability
  • Implement DNS load balancing
  • Integrate with Grafana using Prometheus metrics
  • Configure automated SSL certificate renewal
  • Create custom filtering rules for your specific needs
  • Explore API automation for dynamic filtering

For support and updates, visit the AdGuard Home GitHub repository at https://github.com/AdguardTeam/AdGuardHome and documentation at https://github.com/AdguardTeam/AdGuardHome/wiki