|
@@ -0,0 +1,161 @@
|
|
1
|
+---
|
|
2
|
+date: 2017-12-17
|
|
3
|
+title: DNS-over-TLS on the EdgeRouter Lite
|
|
4
|
+url: /2017/12/17/dns-over-tls-on-edgerouter-lite/
|
|
5
|
+---
|
|
6
|
+
|
|
7
|
+<div class="image left">
|
|
8
|
+ <img src="/res/images/erl/edgerouter.jpg" alt="EdgeRouter Lite">
|
|
9
|
+</div>
|
|
10
|
+
|
|
11
|
+DNS-over-TLS is a fairly recent specificiation described in
|
|
12
|
+[RFC7858](https://tools.ietf.org/html/rfc7858), which enables DNS clients to
|
|
13
|
+communicate with servers over a TLS (encrypted) connection instead of requests
|
|
14
|
+and responses being sent in plain text. I won't ramble on about why it's a good
|
|
15
|
+thing that your ISP, government, or neighbour can't see your DNS requests...
|
|
16
|
+
|
|
17
|
+I use an [EdgeRouter Lite](https://www.ubnt.com/edgemax/edgerouter-lite/) from
|
|
18
|
+Ubiquiti Networks at home, and recently configured it to use DNS-over-TLS for
|
|
19
|
+all DNS queries. Here's how I did it.
|
|
20
|
+
|
|
21
|
+<!--more-->
|
|
22
|
+
|
|
23
|
+### Installing unbound
|
|
24
|
+
|
|
25
|
+Out of the box, the ERL uses `dnsmasq` to service DNS requests from local
|
|
26
|
+clients. To get DNS-over-TLS support I switched to using
|
|
27
|
+[Unbound](https://unbound.net/), an open source DNS resolver with support
|
|
28
|
+for many modern features such as DNSSEC and DNS-over-TLS.
|
|
29
|
+
|
|
30
|
+Installing unbound on the ERL is a simple case of SSHing in, and then:
|
|
31
|
+
|
|
32
|
+{{< highlight text >}}
|
|
33
|
+sudo apt-get update
|
|
34
|
+sudo apt-get install unbound
|
|
35
|
+{{< / highlight >}}
|
|
36
|
+
|
|
37
|
+And then configuring the ERL to use the new local resolver for DNS requests,
|
|
38
|
+turn off dnsmasq, and and tell DHCP clients to send DNS requests to it
|
|
39
|
+(obviously substituting network names and subnets as appropriate):
|
|
40
|
+
|
|
41
|
+{{< highlight text >}}
|
|
42
|
+set system name-server 127.0.0.1
|
|
43
|
+set service dhcp-server shared-network-name lan1 subnet 192.168.1.0/24 dns-server 192.168.1.1
|
|
44
|
+set service dhcp-server use-dnsmasq disable
|
|
45
|
+set service dns
|
|
46
|
+{{< / highlight >}}
|
|
47
|
+
|
|
48
|
+At this point DNS should still work, but Unbound will still be sending requests
|
|
49
|
+out in plain text.
|
|
50
|
+
|
|
51
|
+### Configuration
|
|
52
|
+
|
|
53
|
+The unbound configuration lives in `/etc/unbound/unbound.conf`, here's a basic
|
|
54
|
+example that I use to enable DNS-over-TLS:
|
|
55
|
+
|
|
56
|
+{{< highlight yaml >}}
|
|
57
|
+# Unbound configuration file for Debian.
|
|
58
|
+#
|
|
59
|
+# See the unbound.conf(5) man page.
|
|
60
|
+#
|
|
61
|
+# See /usr/share/doc/unbound/examples/unbound.conf for a commented
|
|
62
|
+# reference config file.
|
|
63
|
+
|
|
64
|
+server:
|
|
65
|
+ auto-trust-anchor-file: "/var/lib/unbound/root.key"
|
|
66
|
+ verbosity: 1
|
|
67
|
+ interface: 0.0.0.0
|
|
68
|
+ interface: ::0
|
|
69
|
+ port: 53
|
|
70
|
+ do-ip4: yes
|
|
71
|
+ do-ip6: yes
|
|
72
|
+ do-udp: yes
|
|
73
|
+ do-tcp: yes
|
|
74
|
+ access-control: 192.168.0.0/16 allow
|
|
75
|
+ access-control: 127.0.0.0/8 allow
|
|
76
|
+ access-control: 10.0.0.0/8 allow
|
|
77
|
+ root-hints: "/var/lib/unbound/root.hints"
|
|
78
|
+
|
|
79
|
+ hide-identity: yes
|
|
80
|
+ hide-version: yes
|
|
81
|
+ harden-glue: yes
|
|
82
|
+ harden-dnssec-stripped: yes
|
|
83
|
+
|
|
84
|
+ cache-min-ttl: 900
|
|
85
|
+ cache-max-ttl: 14400
|
|
86
|
+ prefetch: yes
|
|
87
|
+ rrset-roundrobin: yes
|
|
88
|
+ ssl-upstream: yes
|
|
89
|
+ use-caps-for-id: yes
|
|
90
|
+
|
|
91
|
+ private-address: 192.168.0.0/16
|
|
92
|
+ private-address: 172.16.0.0/12
|
|
93
|
+ private-address: 10.0.0.0/8
|
|
94
|
+
|
|
95
|
+ logfile: "/var/lib/unbound/unbound.log"
|
|
96
|
+ verbosity: 0
|
|
97
|
+ val-log-level: 3
|
|
98
|
+
|
|
99
|
+forward-zone:
|
|
100
|
+ name: "."
|
|
101
|
+ forward-addr: 9.9.9.9@853
|
|
102
|
+{{< / highlight >}}
|
|
103
|
+
|
|
104
|
+Notice the server directive `ssl-upstream`, and that the forward zone specifies
|
|
105
|
+the [quad9](https://www.quad9.net/) resolver on its TLS port (853).
|
|
106
|
+
|
|
107
|
+#### DNSSEC
|
|
108
|
+
|
|
109
|
+To enable Unbound to validate DNSSEC signatures, we need to provide it with
|
|
110
|
+some information about the root nameservers that we trust. First, download the
|
|
111
|
+list of root nameservers to the `root-hints` file specified in the unbound
|
|
112
|
+config:
|
|
113
|
+
|
|
114
|
+{{< highlight text >}}
|
|
115
|
+wget ftp://FTP.INTERNIC.NET/domain/named.cache -O /var/lib/unbound/root.hints
|
|
116
|
+{{< / highlight >}}
|
|
117
|
+
|
|
118
|
+Then we need to add the root keys to the `auto-trust-anchor-file`. The trust
|
|
119
|
+anchor at the time of writing is below, but you can get the latest values from
|
|
120
|
+the [IANA](https://data.iana.org/root-anchors/).
|
|
121
|
+
|
|
122
|
+{{< highlight text >}}
|
|
123
|
+. 172800 IN DNSKEY 257 3 8 AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexTBAvkMgJzkKTOiW1vkIbzxeF3+/4RgWOq7HrxRixHlFlExOLAJr5emLvN7SWXgnLh4+B5xQlNVz8Og8kvArMtNROxVQu
|
|
124
|
+. 172800 IN DNSKEY 257 3 8 AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjFFVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoXbfDaUeVPQuY
|
|
125
|
+{{< / highlight >}}
|
|
126
|
+
|
|
127
|
+### Redirecting unencrypted requests
|
|
128
|
+
|
|
129
|
+I have a slew of devices on my network that, over time, I have configured to
|
|
130
|
+use 8.8.8.8 as a DNS server. They're not going to care about the DHCP reply,
|
|
131
|
+and I don't really feel like going around checking every weird and wonderful
|
|
132
|
+internet-connected device in the house, so I decided to just intercept requests
|
|
133
|
+to 8.8.8.8 and send them to Unbound. A simple NAT rule does the trick:
|
|
134
|
+
|
|
135
|
+{{< highlight text >}}
|
|
136
|
+set service nat rule 1 description "HonestDNS Redirect"
|
|
137
|
+set service nat rule 1 destination address 8.8.8.8
|
|
138
|
+set service nat rule 1 destination port 53
|
|
139
|
+set service nat rule 1 inbound-interface eth0
|
|
140
|
+set service nat rule 1 inside-address address 192.168.1.1
|
|
141
|
+set service nat rule 1 inside-address port 53
|
|
142
|
+set service nat rule 1 log disable
|
|
143
|
+set service nat rule 1 protocol tcp_udp
|
|
144
|
+set service nat rule 1 type destination
|
|
145
|
+{{< / highlight >}}
|
|
146
|
+
|
|
147
|
+You could of course redirect any traffic to port 53, but that would prevent you
|
|
148
|
+from explicitly querying any other DNS server. By just intercepting traffic to
|
|
149
|
+8.8.8.8 I'm taking care of the vast majority of my statically configured
|
|
150
|
+devices, and can still issue manual queries to other resolves when needed.
|
|
151
|
+
|
|
152
|
+### Validating
|
|
153
|
+
|
|
154
|
+To check that everything is working, you can use `tcpdump` on the router to
|
|
155
|
+inspect packets on the WAN interface directed at port 53:
|
|
156
|
+
|
|
157
|
+{{< highlight text >}}
|
|
158
|
+sudo tcpdump -Xi eth0 port 53
|
|
159
|
+{{< / highlight >}}
|
|
160
|
+
|
|
161
|
+You should, hopefully, not see anything.
|