I’ve talked about how much I like Adguard Home before and even compared it to Pi-Hole (a service I’ve found lagging far behind the competition recently). So today, I want to highlight another incredible feature that Adguard Home has; it can be used as a DNS over TLS (DoT) server, so you can keep encrypted DNS connections while you’re out and about without a VPN. Before you run to the comments and tell me this is a bad idea, keep reading, and you’ll see that I am already planning to deal with the DNS amplification attack issues. With this guide, you’ll set up AdguardHome as a DNS over TLS server to receive DNS requests from your devices remotely while using ACLs to limit who can send those requests.
There is only one requirement (outside of having something to run Adguard Home on): You must own a domain name.
Step 1: Set up Adguard:
I’m not going to dive into this because I assume you already have Adguard Home set up or plan to. If needed, here are Adguard’s official Instructions: GitHub – AdguardTeam/AdGuardHome: Network-wide ads & trackers blocking DNS server.
Step 2: Create a wildcard A record for your domain
This will differ between DNS hosts, but typically, you only need to assign a * to the root domain and point it at your IP.
Step 3: Install Certbot
The easiest way to do this is through Snapd (please don’t stone me for saying that). Most Ubuntu distros have Snap installed by default because of Canonical, but if you don’t (or are on a different distro), it can be easily installed using apt.
sudo apt update && sudo apt install snapd
Afterward, you can install certbot directly from Snap
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
Next, you must install the DNS plugin for your specific registrar. For me, it was Cloudflare, but it might be different for you. Check this website to see if certbot supports your registrar User Guide — Certbot 3.1.0.dev0 documentation
sudo snap install certbot-dns-cloudflare
Each registrar has a different way of handling DNS API keys, so check the specific configuration settings for your registrar off the same page above. For Cloudflare, I used these steps.
mkdir -p ~/.secrets/certbot/cloudflare.ini
nano ~/.secrets/certbot/cloudflare.ini
Then, in your ini file, place the following information
dns_cloudflare_api_token = yourAPIKey
With Cloudflare, limit your API access to DNS: Edit only and to the specific domain (if you have more than one registered there).
After this, the command for certbot is:
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini \
--dns-cloudflare-propagation-seconds 60 \
-d *.your.domain
If you follow the steps, certbot should generate two files (a fullchain.pem and a privkey.pem) in the following directories
/etc/letsencrypt/live/domain/fullchain.pem
/etc/letsencrypt/live/domain/privkey.pem
Step 4: Load the certs in Adguard
In adguard, go to Settings -> Encryption
Enable Encryption, put your root domain in the “server name” block,
Go down to the certificates field. In that field, paste the location of the “fullchain.pem” file from earlier.
Don’t worry if Adguard says the “certificate chain is invalid.” This setup still works. As far as I can tell, the issue is with Adguard’s dislike of wildcard certificates.
In the Private Key field, place the location of privkey.pem from earlier.
Hit save configuration, and you should be good.
Step 5: Configure ACLs
This next part is essential for preventing rouge DNS queries from unauthorized clients.
Go to Settings -> DNS Settings, then scroll to the bottom to “Allowed clients.”
Alright, so before we get into this, let’s explain how Adguard Home handles DoT because it’s incredible.
In earlier steps, we set up a wildcard cert that allows us to use any domain name for the DoT. Adguard Home uses the subdomain to identify individual clients, which it calls ClientIDs Clients · AdguardTeam/AdGuardHome Wiki · GitHub.
This means we can generate unique client IDs by having our clients use individual subdomains when connecting to DoT. It also means we can lock down which clients can use our Adguard Home.
In the “Allowed Clients” field, put the subdomain (ClientIDs) you plan to use. (Also, make sure you put your home’s private IP range, or Adguard Home will drop any DNS requests not using the subdomain, which will be most of your homes’ DNS requests).
Click Save Configuration.
Step 6: Port Forward
In your router, forward port 853 to the Adguard Home host (If you’re using Docker, make sure you map port 853 from the host to the container).
Step 7: Configure DoT on your device.
There are many different ways to do this depending on the device you’re using, but I’m assuming you’re looking to do this because you want to use your encrypted private DNS server while on the go.
Go to your Connection settings -> More Connection Settings -> Private DNS for Android. Set that to On and make sure the subdomain is set to one of the ClientIDs you used in the “Allowed Clients” section earlier. Your phone should connect; if it has issues, you’ll get an error that says “Could not connect” or “Mobile network has no internet access.”
If you get one of those errors, go back through the sets above and ensure everything is correct from Step 2 on.
Conclusion
Now that your device is connected, you should see the ClientID appear in your Adguard Home logs. In the Settings -> Client Settings tab, you can apply custom rules to this Client.
Congratulations. You have now configured Adguard Home to listen for and respond to DNS over TLS requests while locking it down to only the clients you approve of. Technically, someone could still guess the subdomain you used for your ClientID, so make it complicated and unique for you.