SANOG 41 DNS workshop
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

DoT and DoH Lab

Goal of this lab is to setup DoT (DNS over TLS) as well as DoH (DNS over HTTPS). This lab requires following ports to be available:

Port Application
53 Unbound
853 DNS over TLS
443 DNS over HTTPS

Step 1 - Ensure port 53 is available

If you have authoritative DNS running from previous labs, then stop it to release the port 53.

sudo systemctl stop pdns && sudo systemctl disable pdns 

Step 2 - Install certbot

sudo apt install certbot 

Step 3 - Use Certbot’s standalone mode to request for TLS certificates

Use hostname of your server i.e for attendee 01: a01.learndns.info

sudo certbot certonly --standalone --preferred-challenges http -d a01.learndns.info

Sample output of successful run:

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): me@anuragbhatia.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.4-April-3-2024.pdf. You must agree in
order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: N
Account registered.
Requesting a certificate for a01.learndns.info

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/a01.learndns.info/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/a01.learndns.info/privkey.pem
This certificate expires on 2024-07-19.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
 * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
 * Donating to EFF:                    https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Note the location of the certificate and the key from the above output

Certificate is saved at: /etc/letsencrypt/live/a01.learndns.info/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/a01.learndns.info/privkey.pem

Step 4: Setup cronjob for autorenewal of certificates

Enter crontab edit mode using following command:

crontab -e

Add following value for autorenwal cron:

0 0 * * * /usr/bin/certbot renew

This will trigger renewal every night at 0th hour, 0th min i.e 12am.


Step 5: Add DoT & DoH config in Unbound

Create dot_doh.conf in /etc/unbound/unbound.conf.d and following:

server:
    # DoT Config 
    interface: 0.0.0.0@853
    tls-port: 853
    tls-service-key: "/etc/letsencrypt/live/a01.learndns.info/privkey.pem"
    tls-service-pem: "/etc/letsencrypt/live/a01.learndns.info/fullchain.pem"

    # DoH Config
    interface: 0.0.0.0@443
    tls-service-key: "/etc/letsencrypt/live/a01.learndns.info/privkey.pem"
    tls-service-pem: "/etc/letsencrypt/live/a01.learndns.info/fullchain.pem"

Step 6: Permit Unbound to read certificates by updating AppArmor

By default AppArmor would prevent unbound from reading anything outside of /etc/unbound, /var/lib/unbound/, /etc/openssl. More about this can be read in discussion on serverfault here.

We can add a override to this by allowing unbound to read location where out certificates are placed:

Create /etc/apparmor.d/local/usr.sbin.unbound and add following:

/etc/letsencrypt/archive/** r,
/etc/letsencrypt/live/** r,

and next, activate the changes using:

apparmor_parser --replace /etc/apparmor.d/usr.sbin.unbound

Step 7: Restart Unbound

sudo systemctl restart unbound

If the restart is successful, unbound is ready to accept both DoT (DNS over TLS) as well as DoH (DNS Over HTTPS) queries. The recursor ACL as setup on day 1 still applies regardless on the type of query.


Step 8: Test DoT

Query using dig +tls

dig +tls sanog.org ns 

; <<>> DiG 9.18.18-0ubuntu0.22.04.2-Ubuntu <<>> +tls sanog.org ns
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 60531
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;sanog.org.                     IN      NS

;; ANSWER SECTION:
sanog.org.              3597    IN      NS      pdns03.domaincontrol.com.
sanog.org.              3597    IN      NS      pdns04.domaincontrol.com.

;; Query time: 44 msec
;; SERVER: 127.0.0.1#853(127.0.0.1) (TLS)
;; WHEN: Sat Apr 20 21:42:17 UTC 2024
;; MSG SIZE  rcvd: 97

Step 9: Test for DoH

Query using dig +https

dig +https sanog.org mx 

; <<>> DiG 9.18.18-0ubuntu0.22.04.2-Ubuntu <<>> +https sanog.org mx
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 60849
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;sanog.org.                     IN      MX

;; ANSWER SECTION:
sanog.org.              3600    IN      MX      5 ALT1.ASPMX.L.GOOGLE.COM.
sanog.org.              3600    IN      MX      5 ALT2.ASPMX.L.GOOGLE.COM.
sanog.org.              3600    IN      MX      10 ALT3.ASPMX.L.GOOGLE.COM.
sanog.org.              3600    IN      MX      10 ALT4.ASPMX.L.GOOGLE.COM.
sanog.org.              3600    IN      MX      1 ASPMX.L.GOOGLE.COM.

;; Query time: 308 msec
;; SERVER: 127.0.0.1#443(127.0.0.1) (HTTPS)
;; WHEN: Sat Apr 20 22:12:57 UTC 2024
;; MSG SIZE  rcvd: 156