DNS queries over TLS
Following on from my previous post on Unbound, this post is going to look at encrypting DNS traffic using TLS.
Standard DNS traffic
DNS traffic is normally sent unencrypted over port 53. tcpdump can be used to demonstrate this:
$ tcpdump -nX host 220.127.116.11 or host 18.104.22.168 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on enp0s3, link-type EN10MB (Ethernet), capture size 262144 bytes 22:55:09.183176 IP 10.0.2.15.38783 > 22.214.171.124.domain: 58055+ A? example.com. (29) 0x0000: 4500 0039 8545 0000 4011 e75e 0a00 020f [email protected]^.... 0x0010: 0101 0101 977f 0035 0025 0e47 e2c7 0100 .......5.%.G.... 0x0020: 0001 0000 0000 0000 0765 7861 6d70 6c65 .........example 0x0030: 0363 6f6d 0000 0100 01 .com..... 22:55:09.210108 IP 126.96.36.199.domain > 10.0.2.15.38783: 58055 1/0/0 A 188.8.131.52 (45) 0x0000: 4500 0049 01bf 0000 4011 6ad5 0101 0101 [email protected] 0x0010: 0a00 020f 0035 977f 0035 9e04 e2c7 8180 .....5...5...... 0x0020: 0001 0001 0000 0000 0765 7861 6d70 6c65 .........example 0x0030: 0363 6f6d 0000 0100 01c0 0c00 0100 0100 .com............ 0x0040: 000d 9b00 045d b8d8 22 .....].."
In the example above two packets are displayed, the request sent to look up
example.com, followed by the response from the remote DNS server. Anyone with
access to the network will be able to read both the request and response.
In the previous post on Unbound, the following configuration was used to forward traffic to CloudFlare's DNS servers:
forward-zone: name: "." forward-addr: 184.108.40.206 forward-addr: 220.127.116.11
CloudFlare's DNS servers can also be accessed via TLS. To do this the configuration above can be modified as follows:
forward-zone: name: "." forward-addr: [email protected]#cloudflare-dns.com forward-addr: [email protected]#cloudflare-dns.com forward-ssl-upstream: yes
In the configuration above
@853 specifies the port and
specifies the hostname which should be validated when the TLS connection is
established. Unfortunately name verification was only recently added (bug
658); so if you're using an earlier version of Unbound
#cloudflare-dns.com will be ignored.
Once the Unbound configuration has been updated, restart the service with the following command:
systemctl restart unbound.service
Any queries made by unbound will now be sent over an encrypted TLS connection,
tcpdump can be used to verify this:
10.0.2.15.36284 > 18.104.22.168.853: Flags [S], cksum 0x0e3f (incorrect -> 0x0b08), seq 574903500, win 29200, options [mss 1460,sackOK,TS val 701611 ecr 0,nop,wscale 7], length 0
From a privacy perspective encrypting DNS traffic is great, unfortunately there is a down side. Unlike DNS using UDP packets, DNS over TLS requires time to establish a TLS connection before making the query. As a result initial queries can take over a second:
$ time host example.com 127.0.0.1 Using domain server: Name: 127.0.0.1 Address: 127.0.0.1#53 Aliases: example.com has address 22.214.171.124 example.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946 real 0m1.559s user 0m0.009s sys 0m0.004s
Compared to a fraction of a second for queries over UDP:
$ time host example.com 126.96.36.199 Using domain server: Name: 188.8.131.52 Address: 184.108.40.206#53 Aliases: example.com has address 220.127.116.11 example.com has IPv6 address 2606:2800:220:1:248:1893:25c8:1946 real 0m0.288s user 0m0.007s sys 0m0.006s