You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

398 lines
16 KiB

  1. # Stubby for OpenWRT
  2. ## Stubby Description
  3. [Stubby](https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Daemon+-+Stubby) is
  4. an application that acts as a local DNS Privacy stub resolver (using
  5. DNS-over-TLS). Stubby encrypts DNS queries sent from a client machine to a DNS
  6. Privacy resolver increasing end user privacy.
  7. Stubby is useful on an OpenWRT device, because it can sit between the usual DNS
  8. resolver (dnsmasq by default) and the upstream DNS resolver and be used to
  9. ensure that DNS traffic is encrypted between the OpenWRT device and the
  10. resolver.
  11. Stubby is developed by the [getdns](http://getdnsapi.net/) project.
  12. For more background and FAQ see the [About
  13. Stubby](https://dnsprivacy.org/wiki/display/DP/About+Stubby) page.
  14. ## Installation
  15. Installation of this package can be achieved at the command line using `opkg
  16. install stubby`, or via the LUCI Web Interface. Installing the stubby package
  17. will also install the required dependency packages, including the
  18. `ca-certificates` package.
  19. ## Configuration
  20. The default configuration of the package has been chosen to ensure that stubby
  21. should work after installation.
  22. By default, configuration of stubby is integrated with the OpenWRT UCI system
  23. using the file `/etc/config/stubby`. The configuration options available are
  24. also documented in that file. If for some reason you wish to configure stubby
  25. using the `/etc/stubby/stubby.yml` file, then you simply need to set `option
  26. manual '1'` in `/etc/config/stubby` and all other settings in
  27. `/etc/config/stubby` will be ignored.
  28. ### Stubby port and addresses
  29. The default configuration ensures that stubby listens on port 5453 on the
  30. loopback interfaces for IPv4 and IPv6. As such, by default, stubby will respond
  31. only to lookups from the OpenWRT device itself.
  32. By setting the listening ports to non-standard values, this allows users to keep
  33. the main name server daemon in place (dnsmasq/unbound/etc.) and have that name
  34. server forward to stubby.
  35. ### Upstream resolvers
  36. The default package configuration uses the CloudFlare resolvers, configured for
  37. both IPv4 and IPv6.
  38. CloudFlare have not published SPKI pinsets, and even though they are available,
  39. they have made no commitment to maintaining them. Using the currently known SPKI
  40. pinsets for CloudFlare brings the risk that in the future they may be changed by
  41. CloudFlare, and DNS would stop working. The default configuration has those SPKI
  42. entries commented out for this reason.
  43. [CloudFlare's privacy
  44. statement](https://developers.cloudflare.com/1.1.1.1/commitment-to-privacy/)
  45. details how they treat data from DNS requests.
  46. More resolvers are available in the [upstream stubby example
  47. configuration](https://github.com/getdnsapi/stubby/blob/develop/stubby.yml.example)
  48. and the [DNS Privacy
  49. list](https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Test+Servers).
  50. ## Integration of stubby with dnsmasq
  51. The recommended way to use stubby on an OpenWRT device is to integrate it with a
  52. caching resolver. The default caching resolver in OpenWRT is dnsmasq.
  53. ### Set dnsmasq to send DNS requests to stubby
  54. Since dnsmasq responds to LAN DNS requests on port 53 of the OpenWRT device by
  55. default, all that is required is to have dnsmasq forward those requests to
  56. stubby which is listening on port 5453 of the OpenWRT device. To achieve this,
  57. we need to set the `server` option in the dnsmasq configuration in the
  58. `/etc/config/dhcp` file to `'127.0.0.1#5453'`. We also need to tell dnsmasq not
  59. to use resolvers found in `/etc/resolv.conf` by setting the dnsmasq option
  60. `noresolv` to `1` in the same file. This can be achieved by editing the
  61. `/etc/config/dhcp` file directly or executing the following commands at the
  62. command line:
  63. uci add_list dhcp.@dnsmasq[-1].server='127.0.0.1#5453'
  64. uci dhcp.@dnsmasq[-1].noresolv=1
  65. uci commit && reload_config
  66. The same outcome can be achieved in the LUCI web interface as follows:
  67. 1. Select the Network->DHCP and DNS menu entry.
  68. 2. In the "General Settings" tab, enter the address `127.0.0.1#5453` as the only
  69. entry in the "DNS Forwardings" dialogue.
  70. 3. In the "Resolv and Host files" tab tick the "Ignore resolve file" checkbox.
  71. ### Disable sending DNS requests to ISP provided DNS servers
  72. The configuration changes in the previous section ensure that DNS queries are
  73. sent over TLS encrypted connections *once dnsmasq and stubby are started*. When
  74. the OpenWRT device is first brought up, there is a possibility that DNS queries
  75. can go to ISP provided DNS servers ahead of dnsmasq and stubby being active. In
  76. order to mitigate this leakage, it's necessary to ensure that upstream resolvers
  77. aren't available, and the only DNS resolver used by the system is
  78. dnsmasq+stubby.
  79. This requires setting the option `peerdns` to `0` and the option `dns` to the
  80. loopback address for both the `wan` and `wan6` interfaces in the
  81. `/etc/config/network` file. This can be achieved by editing the
  82. `/etc/config/network` file directly, or by executing the following commands:
  83. uci set network.wan.peerdns='0'
  84. uci set network.wan.dns='127.0.0.1'
  85. uci set network.wan6.peerdns='0'
  86. uci set network.wan6.dns='0::1'
  87. uci commit && reload_config
  88. The same outcome can also be achieved using the LUCI web interface as follows:
  89. 1. Select the Network->Interfaces menu entry.
  90. 2. Click on Edit for the WAN interfaces.
  91. 3. Choose the Advanced Settings tab.
  92. 4. Unselect the "Use DNS servers advertised by peer" checkbox
  93. 5. Enter `127.0.0.1` in the "Use custom DNS servers" dialogue box.
  94. 6. Repeat the above steps for the WAN6 interface, but use the address `0::1`
  95. instead of `127.0.0.1`.
  96. ### Enabling DNSSEC
  97. The configuration described above ensures that DNS queries are executed over TLS
  98. encrypted links. However, the responses themselves are not validated; DNSSEC
  99. provides the ability to validate returned DNS responses, and mitigate against
  100. DNS poisoning risks.
  101. With the combination of stubby+dnsmasq there are two possible ways to enable
  102. DNSSEC:
  103. 1. Configure stubby to perform DNSSEC validation, and configure dnsmasq to proxy
  104. the DNSSEC data to clients.
  105. 2. Configure stubby not to perform DNSSEC validation and configure dnsmasq to
  106. require DNSSEC validation.
  107. Either option achieves the same outcome, and there appears to be little reason
  108. for choosing one over the other other than that the second option is easier to
  109. configure in the LUCI web interface. Both options are detailed below, and both
  110. require that the `dnsmasq` package on the OpenWRT device is replaced with the
  111. `dnsmasq-full` package. That can be achieved by running the following command:
  112. opkg install dnsmasq-full --download-only && opkg remove dnsmasq && opkg install dnsmasq-full --cache . && rm *.ipk
  113. #### DNSSEC by stubby
  114. Configuring stubby to perform DNSSEC validation requires setting the stubby
  115. configuration option `dnssec_return_status` to `'1'` in `/etc/config/stubby`,
  116. which can be done by editing the file directly or by executing the commands:
  117. uci set stubby.global.dnssec_return_status=1
  118. uci commit && reload_config
  119. With stubby performing DNSSEC validation, dnsmasq needs to be configured to
  120. proxy the DNSSEC data to clients. This requires setting the option `proxydnssec`
  121. to 1 in the dnsmasq configuration in `/etc/config/dhcp`. That can be achieved by
  122. the following commands:
  123. uci set dhcp.@dnsmasq[-1].proxydnssec=1
  124. uci commit && reload_config
  125. #### DNSSEC by dnsmasq
  126. Configuring dnsmasq to perform DNSSEC validation requires setting the dnsmasq
  127. option `dnssec` to `1` in the `/etc/config/dhcp` file. In addition, it is
  128. advisable to also set the dnsmasq option `dnsseccheckunsigned` to `1`. this can
  129. be achieved by editing the file `/etc/config/dhcp` or by executing the following
  130. commands:
  131. uci set dhcp.@dnsmasq[-1].dnssec=1
  132. uci set dhcp.@dnsmasq[-1].dnsseccheckunsigned=1
  133. uci commit && reload_config
  134. The same options can be set in the LUCI web interface as follows:
  135. 1. Select the "Network->DHCP and DNS" menu entry.
  136. 2. Select the "Advanced Settings" tab.
  137. 3. Ensure both the "DNSSEC" and "DNSSEC check unsigned" check boxes are ticked.
  138. #### Validating DNSSEC operation
  139. Having configured DNSSEC validation using one of the two approaches above, it's
  140. important to check it's actually working. The following command can be used:
  141. dig dnssectest.sidn.nl +dnssec +multi @192.168.1.1
  142. This command should return output like the following:
  143. ; <<>> DiG 9.11.4-P1-RedHat-9.11.4-5.P1.fc28 <<>> dnssectest.sidn.nl +dnssec +multi @192.168.1.1
  144. ;; global options: +cmd
  145. ;; Got answer:
  146. ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26579
  147. ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
  148. ;; OPT PSEUDOSECTION:
  149. ; EDNS: version: 0, flags: do; udp: 512
  150. ;; QUESTION SECTION:
  151. ;dnssectest.sidn.nl. IN A
  152. ;; ANSWER SECTION:
  153. dnssectest.sidn.nl. 14399 IN A 213.136.9.12
  154. dnssectest.sidn.nl. 14399 IN RRSIG A 8 3 14400 (
  155. 20181104071058 20181005071058 42033 sidn.nl.
  156. YAQl3tef36M9EQUOmCneHKCCkxox3csLpfUOql5i/6ND
  157. zPrQFsNr3g32HPoxOsi+hD2BE5+bEsnARayDSVLyx0qU
  158. 6Hpi2rzQ0zGNZZkCJhCsdp3wnM1BWlMgPrCD0iIsJDok
  159. +DH5zu+yYufVUdSLQrMqA3MZDFUIqDUqSZuYDF4= )
  160. ;; Query time: 77 msec
  161. ;; SERVER: 192.168.1.1#53(192.168.1.1)
  162. ;; WHEN: Sat Oct 06 20:36:25 BST 2018
  163. ;; MSG SIZE rcvd: 230
  164. The key thing to note is the `flags: qr rd ra ad` part - the `ad` flag signifies
  165. that DNSSEC validation is working. If that flag is absent DNSSEC validation is
  166. not working.
  167. ## Appendix: stubby configuration options
  168. This section details the options available for use in the `/etc/config/stubby`
  169. file. The `global` configuration section specifies the configuration parameters
  170. for the stubby daemon. One or more `resolver` sections are used to configure
  171. upstream resolvers for the stubby daemon to use.
  172. ### `global` section options
  173. #### `option manual`
  174. Specify whether to use this file to configure the stubby service. If this is set
  175. to `'1'` stubby will be configured using the file `/etc/stubby/stubby.yml`. If this
  176. is set to `'0'`, configuration options will be taken from this file, and the service
  177. will be managed through UCI.
  178. #### `option trigger`
  179. This specifies an interface to trigger stubby start up on; stubby startup will
  180. be triggered by a procd signal associated with this interface being ready. If
  181. this interface is restarted, stubby will also be restarted.
  182. This option can also be set to `'timed'`, in which case a time, specified by the
  183. option `triggerdelay`, will be waited before starting stubby.
  184. #### `option triggerdelay`
  185. If the `trigger` option specifies an interface, this option sets the time that
  186. is waited after the procd signal is received before starting stubby.
  187. If `trigger` is set to `'timed'` then this is the delay before starting stubby.
  188. This option is specified in seconds and defaults to the value `'2'`.
  189. #### `list dns_transport`
  190. The `dns_transport` list specifies the allowed transports. Allowed values are:
  191. `GETDNS_TRANSPORT_UDP`, `GETDNS_TRANSPORT_TCP` and `GETDNS_TRANSPORT_TLS`. The
  192. transports are tried in the order listed.
  193. #### `option tls_authentication`
  194. This option specifies whether TLS authentication is mandatory. A value of `'1'`
  195. mandates TLS authentication, and is the default.
  196. If this is set to `'0'`, and `GETDNS_TRANSPORT_TCP` or `GETDNS_TRANSPORT_UDP`
  197. appears in the `dns_transport` list, stubby is allowed to fall back to non-TLS
  198. authenticated lookups. You probably don't want this though.
  199. #### `option tls_query_padding_blocksize`
  200. This option specifies the block size to pad DNS queries to. You shouldn't need
  201. to set this to anything but `'128'` (the default), as recommended by
  202. https://tools.ietf.org/html/draft-ietf-dprive-padding-policy-03
  203. #### `option tls_connection_retries`
  204. This option specifies the number of connection failures stubby permits before
  205. Stubby backs-off from using an individual upstream resolver. You shouldn't need
  206. to change this from the default value of `'2'`.
  207. #### `option tls_backoff_time`
  208. This option specifies the maximum time in seconds Stubby will back-off from
  209. using an individual upstream after failures. You shouldn't need to change this
  210. from the default value of `'3600'`.
  211. #### `option timeout`
  212. This option specifies the timeout on getting a response to an individual
  213. request. This is specified in milliseconds. You shouldn't need to change this
  214. from the default value of ` '5000'`.
  215. #### `option dnssec_return_status`
  216. This option specifies whether stubby should require DNSSEC validation. Specify
  217. to `'1'` to turn on validation, and `'0'` to turn it off. By default it is off.
  218. #### `option appdata_dir`
  219. This option specifies the location for storing stubby runtime data. In
  220. particular, if DNSSEC is turned on, stubby will store its automatically
  221. retrieved trust anchor data here. The default value is `'/var/lib/stubby'`.
  222. #### `option trust_anchors_backoff_time`
  223. When Zero configuration DNSSEC failed, because of network unavailability or
  224. failure to write to the appdata directory, stubby will backoff trying to refetch
  225. the DNSSEC trust-anchor for a specified amount of time expressed in milliseconds
  226. (which defaults to two and a half seconds).
  227. #### `option dnssec_trust_anchors`
  228. This option sets the location of the file containing the trust anchor data used
  229. for DNSSEC validation. If this is not specified, stubby will automatically
  230. retrieve a trust anchor at startup. It's unlikely you'll want to manage the
  231. trust anchor data manually, so in most cases this is not needed. By default,
  232. this is unset.
  233. #### `option edns_client_subnet_private`
  234. This option specifies whether to enforce ECS client privacy. The default is
  235. `'1'`. Set to `'0'` to disable client privacy.
  236. For more details see Section 7.1.2 [here](https://tools.ietf.org/html/rfc7871).
  237. #### `option idle_timeout`
  238. This option specifies the time (in milliseconds) to hold TLS connections open to
  239. avoid the overhead of opening a new connection for every query. You should not
  240. normally need to change this from the default value (currently `'10000'`).
  241. See [here](https://tools.ietf.org/html/rfc7828) for more details.
  242. #### `option round_robin_upstreams`
  243. This option specifies how stubby will use the upstream DNS resolvers. Set to
  244. `'1'` (the default) to instruct stubby to distribute queries across all
  245. available name servers - this will use multiple simultaneous connections which
  246. can give better performance in most (but not all) cases. Set to `'0'` to treat
  247. the upstream resolvers as an ordered list and use a single upstream resolver
  248. until it becomes unavailable, then use the next one.
  249. #### `list listen_address`
  250. This list sets the addresses and ports for the stubby daemon to listen for
  251. requests on. the default configuration configures stubby to listen on port 5453
  252. on the loopback interface for both IPv4 and IPv6.
  253. #### `option log_level`
  254. If set, this option specifies the level of logging from the stubby
  255. daemon. By default, this option is not set.
  256. The possible levels are:
  257. '0': EMERG - System is unusable
  258. '1': ALERT - Action must be taken immediately
  259. '2': CRIT - Critical conditions
  260. '3': ERROR - Error conditions
  261. '4': WARN - Warning conditions
  262. '5': NOTICE - Normal, but significant, condition
  263. '6': INFO - Informational message
  264. '7': DEBUG - Debug-level message
  265. #### `option command_line_arguments`
  266. This option specifies additional command line arguments for
  267. stubby daemon. By default, this is an empty string.
  268. ### `resolver` section options
  269. #### `option address`
  270. This option specifies the resolver IP address, and can either be an IPv4 or an
  271. IPv6 address.
  272. #### `option tls_auth_name`
  273. This option specifies the upstream domain name used for TLS authentication with
  274. the supplied server certificate
  275. #### `list spki`
  276. This list specifies the SPKI pinset which is verified against the keys in the
  277. server cerrtificate. The value takes the form `'<digest type>/value>'`, where
  278. the `digest type` is the hashing algorithm used, and the value is the Base64
  279. encoded hash of the public key. At present, only `sha256` is
  280. supported for the digest type.
  281. This should ONLY be used if the upstream resolver has committed to maintaining
  282. the pinset. CloudFlare have made no such commitment, and so we do not specify
  283. the SPKI values in the default configuration, even though they are available.