Overview
This guide walks you through setting up a private, secure DNS server using AdGuard Home (for ad-blocking and management) backed by Unbound (for recursive DNS resolution). This configuration enhances privacy by querying root DNS servers directly instead of relying on third-party providers.Prerequisites
Server Setup
Use any hosting provider. This guide requires Debian 13 x64.Firewall Rules
In your provider’s networking or firewall settings, add the following Inbound Rules and attach them to your server:1
Core DNS & Web Traffic
Add these inbound rules using the preset types where available:
2
Temporary Setup Access (delete-later)
Add one more Custom TCP inbound rule for the AdGuard Home setup wizard — remove this rule after setup is complete:
Update Your Server
SSH into your server using its public IP address and prepare the system:Press
Y when prompted to confirm package upgrades. This may take a few
minutes.Step 1: Install AdGuard Home
AdGuard Home provides the web interface, ad-blocking, and DNS query logging.Initial Configuration
- Navigate to
http://[YOUR_EXTERNAL_IP]:3000in your browser - Proceed through the setup wizard to Step 3
DNS Settings Configuration
Configure Settings → DNS Settings with these values:
Blocking & Cache Settings:
We’ll reconfigure caching in Step 3 after installing Unbound for optimal
performance.
Add Blocklists
Go to Filters → DNS Blocklists and add these lists:- hapara.fail Blocklist
- HaGeZi Normal
- Name:
hapara.fail Blocklist - URL:
https://cdn.jsdelivr.net/gh/hapara-fail/blocklist@main/blocklist.txt
Step 2: Set Up Unbound (Recursive Resolver)
Unbound replaces third-party DNS providers by querying root servers directly, enhancing privacy and control.Install Unbound
Configure Unbound
We’ll run Unbound on port5335 to avoid conflicts with AdGuard Home (which uses port 53).
-
Create the configuration file:
- Paste this optimized configuration:
- Save and exit (
Ctrl+X,Y,Enter)
Download Root Hints
Root hints tell Unbound where the authoritative root DNS servers are:This cron job runs at midnight on the 1st of each month.
Start and Test Unbound
-
Restart the service:
-
Check service status:
✅ Success: You should see
active (running) -
Test DNS resolution:
✅ Success: Look for
status: NOERRORand an IP address in theANSWER SECTION
Step 3: Connect AdGuard Home to Unbound
Now we’ll point AdGuard Home to use your local Unbound instance instead of Cloudflare.Update Upstream DNS
- In AdGuard Home, go to Settings → DNS Settings
- Upstream DNS servers:
- Delete all existing entries
- Add only:
127.0.0.1:5335
- Parallel requests: Select Parallel requests (recommended for stability)
- Bootstrap DNS servers: These resolve IPs for DNS-over-HTTPS/TLS hostnames (not needed for our IP-based upstream, but good practice):
- Private Reverse DNS servers: (Optional) Point to your router if you want local hostname resolution (e.g.,
192.168.1.1) - DNSSEC: ☑ Enable (Unbound validates, but this provides a second check)
- Click Test Upstreams → Should show “Server is working” ✅
- Click Apply
Optimize Cache Settings
Since Unbound has superior caching with prefetching, we’ll minimize AdGuard’s cache:- Go to Settings → DNS Settings → DNS Cache Configuration
- Configure:
Step 4: Secure with SSL/TLS (DoH & DoT)
Enable encrypted DNS protocols: DNS-over-HTTPS (DoH) and DNS-over-TLS (DoT).Install Certbot
Obtain SSL Certificate
Let’s Encrypt needs port 80 to verify domain ownership. We’ll temporarily stop AdGuard Home:Follow the Certbot prompts to enter your email and agree to the Terms of
Service.
Configure Encryption in AdGuard
- Go to Settings → Encryption Settings
- Configure:
-
Certificate & Key Paths (⚠️ Use file paths, NOT file contents):
- Certificate path:
/etc/letsencrypt/live/example.org/fullchain.pem - Private key path:
/etc/letsencrypt/live/example.org/privkey.pem
- Certificate path:
- Click Save Settings
Automate Certificate Renewal
Because AdGuard Home occupies port 80, Certbot needs AGH to be stopped before it can complete the HTTP-01 challenge. Create a pre and post hook to handle this automatically:Certbot automatically renews certificates. These hooks ensure AdGuard reloads
the new certificate without manual intervention.
Update Firewall Rules
- Delete the temporary
delete-laterrule (port 3000 is no longer needed)- In your provider’s firewall settings, find the Custom TCP 3000 inbound rule and remove it.
Setup Complete!
Your DNS server is now fully operational with:- Privacy: Direct recursive resolution via Unbound
- Security: DNSSEC validation, encrypted protocols (DoH/DoT/DoQ)
- Ad-blocking: Custom blocklists via AdGuard Home
- Automation: Auto-renewing SSL certificates
Need help? Check the AdGuard Home
documentation or the Unbound
documentation.