Last updated: 2026-02-13
Unbound DNS over TLS/HTTPS Configuration Guide
This guide provides recommended DNS over TLS (DoT) and DNS over HTTPS (DoH) settings for Unbound recursive resolver. Encrypting DNS traffic prevents eavesdropping and tampering with DNS queries and responses.
Prerequisites
- Unbound 1.18 or later (for DoH support; 1.7.3+ for DoT)
- OpenSSL 1.1.1 or later
- SSL certificates (for serving DoT/DoH to clients)
RHEL/CentOS: Install with
dnf install unbound.Debian/Ubuntu: Install with
apt install unbound.
Certificate Setup
Place your certificates in a dedicated directory:
mkdir -p /etc/unbound/ssl
chmod 750 /etc/unbound/ssl
chown unbound:unbound /etc/unbound/ssl
cp server.crt /etc/unbound/ssl/server-cert.pem
cp server.key /etc/unbound/ssl/server-key.pem
cp ca.crt /etc/unbound/ssl/ca.pem
chmod 640 /etc/unbound/ssl/*.pem
chown unbound:unbound /etc/unbound/ssl/*.pem
Serving DNS over TLS (DoT)
Configure Unbound to accept DoT connections from clients on port 853.
DoT Server Configuration
Add to unbound.conf:
server:
# Standard DNS listener
interface: 0.0.0.0@53
interface: ::0@53
# DNS over TLS listener
interface: 0.0.0.0@853
interface: ::0@853
# TLS certificate and key
tls-service-key: /etc/unbound/ssl/server-key.pem
tls-service-pem: /etc/unbound/ssl/server-cert.pem
# TLS protocol settings
tls-ciphers: "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305"
tls-ciphersuites: "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"
# Require TLS on port 853
tls-port: 853
Serving DNS over HTTPS (DoH)
Unbound 1.18+ can natively serve DNS over HTTPS:
server:
# DNS over HTTPS listener
interface: 0.0.0.0@443
interface: ::0@443
tls-service-key: /etc/unbound/ssl/server-key.pem
tls-service-pem: /etc/unbound/ssl/server-cert.pem
tls-ciphers: "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305"
tls-ciphersuites: "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"
https-port: 443
http-endpoint: "/dns-query"
Forwarding over TLS (Upstream DoT)
Configure Unbound to forward queries to an upstream resolver over TLS. This encrypts the connection between Unbound and the upstream resolver:
server:
# Enable TLS for upstream connections
tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt
forward-zone:
name: "."
forward-tls-upstream: yes
forward-addr: 1.1.1.1@853#cloudflare-dns.com
forward-addr: 1.0.0.1@853#cloudflare-dns.com
forward-addr: 8.8.8.8@853#dns.google
forward-addr: 8.8.4.4@853#dns.google
Configuration Explained
- forward-tls-upstream: yes -- Sends queries to upstream servers over TLS instead of plaintext UDP/TCP.
- forward-addr -- Upstream resolver address with the TLS port (853) and authentication name after
#. - tls-cert-bundle -- Path to the system CA bundle used to verify upstream server certificates.
RHEL/CentOS: The CA bundle path is
/etc/pki/tls/certs/ca-bundle.crt.Debian/Ubuntu: The CA bundle path is
/etc/ssl/certs/ca-certificates.crt.
DNSSEC Validation
Unbound supports DNSSEC validation by default. Ensure it is enabled alongside DoT/DoH:
server:
# DNSSEC validation
auto-trust-anchor-file: /var/lib/unbound/root.key
val-clean-additional: yes
Complete Configuration
server:
# Network
interface: 0.0.0.0@53
interface: ::0@53
interface: 0.0.0.0@853
interface: ::0@853
# Access control
access-control: 127.0.0.0/8 allow
access-control: 10.0.0.0/8 allow
access-control: ::1/128 allow
# TLS certificates
tls-service-key: /etc/unbound/ssl/server-key.pem
tls-service-pem: /etc/unbound/ssl/server-cert.pem
# TLS protocol settings
tls-ciphers: "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305"
tls-ciphersuites: "TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"
tls-port: 853
# System CA bundle for upstream TLS verification
tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt
# DNSSEC
auto-trust-anchor-file: /var/lib/unbound/root.key
val-clean-additional: yes
# Forward all queries upstream over TLS
forward-zone:
name: "."
forward-tls-upstream: yes
forward-addr: 1.1.1.1@853#cloudflare-dns.com
forward-addr: 1.0.0.1@853#cloudflare-dns.com
forward-addr: 8.8.8.8@853#dns.google
forward-addr: 8.8.4.4@853#dns.google
Client Configuration
systemd-resolved
Configure systemd-resolved to use your Unbound server over DoT:
[Resolve]
DNS=192.168.1.1
DNSOverTLS=yes
Android / iOS
Modern Android (9+) and iOS (14+) support DoT and DoH natively. Configure your Unbound server's hostname as the private DNS provider in the device settings.
Verification
Check the configuration for errors:
unbound-checkconf /etc/unbound/unbound.conf
Test the DoT listener:
openssl s_client -connect dns.example.com:853
Test DNS resolution over TLS using kdig (from knot-dnsutils):
kdig @dns.example.com +tls example.com A
Test DNS resolution over standard port to verify Unbound is running:
dig @dns.example.com example.com A
Check Unbound logs:
journalctl -u unbound | grep -i tls