Skip to content

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

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

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