Encrypted DNS¶
Ferrous DNS supports encrypted DNS both as a client (upstream protocols) and as a server (serving encrypted DNS to your devices).
Upstream Protocols¶
When Ferrous DNS resolves a query, it can communicate with upstream servers using any of these protocols:
| Protocol | Standard | Description |
|---|---|---|
| Plain UDP | — | Traditional DNS, no encryption. Fastest, but exposes queries |
| Plain TCP | — | DNS over TCP. Used for large responses |
| DNS-over-HTTPS (DoH) | RFC 8484 | DNS inside HTTPS. Works through firewalls, hard to block |
| DNS-over-TLS (DoT) | RFC 7858 | DNS over TLS. Clean separation from HTTP traffic |
| DNS-over-QUIC (DoQ) | RFC 9250 | DNS over QUIC. Lowest latency of encrypted options |
| HTTP/3 | RFC 9114 | DoH over HTTP/3 (QUIC). Combines DoH benefits with QUIC performance |
Configuring Upstreams¶
[[dns.pools]]
name = "secure"
strategy = "Parallel"
priority = 1
servers = [
# DoQ — lowest latency encrypted
"doq://dns.adguard-dns.com:853",
"doq://dns.alidns.com:853",
# DoH — universal compatibility
"https://cloudflare-dns.com/dns-query",
"https://dns.google/dns-query",
"https://dns.quad9.net/dns-query",
# HTTP/3 (DoH over QUIC)
"h3://dns.google/dns-query",
# DoT
"tls://1.1.1.1:853",
"tls://8.8.8.8:853",
]
Public Resolver Reference¶
| Provider | DoH | DoT | DoQ |
|---|---|---|---|
| Cloudflare | https://cloudflare-dns.com/dns-query | tls://1.1.1.1:853 | — |
https://dns.google/dns-query | tls://8.8.8.8:853 | — | |
| Quad9 | https://dns.quad9.net/dns-query | tls://dns.quad9.net:853 | — |
| AdGuard | https://dns.adguard-dns.com/dns-query | tls://dns.adguard-dns.com:853 | doq://dns.adguard-dns.com:853 |
| NextDNS | https://dns.nextdns.io | — | — |
| CleanBrowsing | https://doh.cleanbrowsing.org/doh/security-filter/ | — | — |
Server-Side Encrypted DNS¶
Ferrous DNS can serve DNS-over-TLS and DNS-over-HTTPS directly to clients on your network, so devices can connect to Ferrous DNS securely.
Requirements¶
- A TLS certificate and private key in PEM format
- Open firewall ports (853 for DoT, 443 or custom for DoH)
Configuration¶
[server.encrypted_dns]
dot_enabled = true
dot_port = 853
doh_enabled = true
doh_port = 443 # optional: omit to co-host on web_port
tls_cert_path = "/data/cert.pem"
tls_key_path = "/data/key.pem"
Self-Signed Certificate¶
openssl req -x509 -newkey rsa:4096 -nodes \
-keyout key.pem -out cert.pem \
-days 365 \
-subj "/CN=dns.home.local" \
-addext "subjectAltName=IP:192.168.1.100,DNS:dns.home.local"
Copy to your data directory and reference in config.
Browsers and DoH with self-signed certificates
Browsers will reject DoH requests to a server with a self-signed certificate unless the certificate is explicitly trusted by the OS or browser. For browser-based DoH, use a Let's Encrypt certificate with a public domain. For DoT on Android and iOS, self-signed certificates are generally accepted.
Let's Encrypt Certificate¶
If your server has a public domain, use Certbot:
certbot certonly --standalone -d dns.yourdomain.com
# Certificate: /etc/letsencrypt/live/dns.yourdomain.com/fullchain.pem
# Key: /etc/letsencrypt/live/dns.yourdomain.com/privkey.pem
[server.encrypted_dns]
tls_cert_path = "/etc/letsencrypt/live/dns.yourdomain.com/fullchain.pem"
tls_key_path = "/etc/letsencrypt/live/dns.yourdomain.com/privkey.pem"
Client Configuration¶
DNS-over-TLS (DoT)¶
Settings > Network > Private DNS > Enter hostname:
Or with custom hostname:Use a .mobileconfig profile or a DNS app like DNSCloak. Set: - Server: 192.168.1.100 - Port: 853 - Protocol: TLS
DNS-over-HTTPS (DoH)¶
IPv6 Upstreams¶
Ferrous DNS fully supports IPv6 upstreams:
[[dns.pools]]
name = "ipv6-pool"
strategy = "Parallel"
priority = 1
servers = [
"https://[2606:4700:4700::1111]/dns-query", # Cloudflare IPv6
"https://[2001:4860:4860::8888]/dns-query", # Google IPv6
]
DNS Name Resolution for Upstreams¶
Upstream server hostnames are resolved at startup, so you can use domain names directly:
servers = [
"doq://dns.adguard-dns.com:853", # resolved at startup
"https://dns.google/dns-query", # resolved at startup
]
This avoids bootstrap DNS dependency issues — Ferrous DNS uses the system resolver once at startup to resolve upstream hostnames, then caches the IPs internally.