Tech Guide Certificates

Part 2 - Setting up AdGuard Home

Part two of the certificate authority series, covering AdGuard Home as the DNS layer for the environment.

Following Part 1, the first component to set up is AdGuard Home. I chose it because it blocks ads and unwanted services for VPN clients, gives me a usable GUI, and makes custom-domain management easier. I considered dnsmasq, but for this stack I decided to stay with AdGuard Home.

Docker Compose

The Docker Compose file and configuration of AdGuard Home is located in /containers/adguardhome base folder.

/containers/adguardhome/docker-compose.yaml

services:
  adguardhome:
    image: adguard/adguardhome:latest
    container_name: adguardhome
    restart: unless-stopped
    volumes:
      - '/containers/adguardhome/work:/opt/adguardhome/work'
      - '/containers/adguardhome/config:/opt/adguardhome/conf'
    networks:
      - webproxy
    ports:
      - '192.168.200.1:3000:30003/tcp' # initial setup port

      - '192.168.250.1:53:53/tcp' # listen for DNS on webproxy interface (tcp)
      - '192.168.250.1:53:53/udp' # listen for DNS on webproxy interface (udp)

      - '192.168.200.1:53:53/tcp' # listen for DNS on wireguard interface (tcp)
      - '192.168.200.1:53:53/udp' # listen for DNS on wireguard interface (udp)

networks:
  webproxy:
    external: true

In this setup, I have AdGuard Home listen on two interfaces:

  • the Docker webproxy interface so Docker can route its DNS requests to this resolver
  • the wireguard interface so WireGuard clients can optionally use the same resolver

With that in place, I run docker compose up so the container can create its working directories. From a WireGuard client, I then connect to http://192.168.200.1:3000/ to finish the initial AdGuard Home setup. I change the admin web interface from 80 to 8000, keep the DNS service listening on ALL interfaces on port 53, and set a strong username and password. Continue until the dashboard launch step. Because port 8000 is not exposed yet, direct access to it will fail until Caddy is in place.

AdGuard Home Setup
AdGuard Home Initial Setup

Once the setup is complete, I stop the container with CTRL+C and edit /containers/adguardhome/docker-compose.yaml again to remove 192.168.200.1:3000:30003/tcp. I no longer need that port because I will use caddy for the AdGuard Home admin UI.

I start the container again with docker compose up -d so it stays in the background.


Firewall

My VPS runs ufw as the firewall frontend so I have a rule that allows DNS traffic to traverse between the interfaces without being blocked. As the DNS server is not exposed on any of the public IP, this approach ensures there is no situation where a service or container will not be able to resolve any DNS queries

ufw allow proto udp from any to any port 53
ufw allow proto tcp from any to any port 53

The next step is to force Docker to use this DNS server for its requests. That keeps custom domain resolution consistent and returns the expected IP address for each service.


DNS for Docker

Create or edit the file /etc/docker/daemon.json and ensure a similar line to the following exists in it

{
  "dns": [
    "192.168.250.1"
  ]
}

using the IP address of the webproxy interface to force all containers to use this specific DNS instance. Make sure to restart Docker for these changes to take effect.


DNS for VPS

The last step is to force the VPS to route all DNS requests to this AdGuard Home instance. My instance uses systemd-networkd with systemd-resolved to set the IP address so I modified my existing network configuration file at /etc/systemd/network/20-wired.network with the following contents

[Match]
Name=enp1s0

[Network]
DHCP=yes
IPv6PrivacyExtensions=yes
Address=2404:1:2:3::1001/128
Address=2404:1:2:3::9999/128
DNS=192.168.250.1 # IP address of the `webproxy` interface

I prefer to reboot the VPS after these changes so I can confirm the resolver path is clean from boot. After the reboot, I verify it with dig and check the AdGuard Home logs for the query.

After this, my VPS will use AdGuard Home for all its DNS resolution. With this in place, we can move on to

Now we can proceed to Part 3 of the guide, setting up the Smallstep Certificate Authority server.

End of article

Part of: Certificate Authority

View the complete series

Continue reading

Series

Certificate Authority

Tags

Guides Linux Arch Linux Networking