-
Notifications
You must be signed in to change notification settings - Fork 73
Update docs around DNSSEC #345
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 5 commits
b7795c8
048177e
a1f6296
6604a53
c430093
597499a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -31,6 +31,47 @@ The public key cryptography underpinning SSL/TLS operates in a similar manner, b | |
|
||
For a more detailed explanation of how the DNSSEC validation is performed, please refer to the [Simplified 12-step DNSSEC validation process](https://bind9.readthedocs.io/en/latest/dnssec-guide.html#the-12-step-dnssec-validation-process-simplified) guide from ISC. | ||
|
||
## DNS daemons | ||
Ubuntu supports multiple DNS resolvers, covering a variety of usecases. Most of them support DNSSEC validation, but it might not be activated and set-up with valid trust-anchors automatically. | ||
|
||
<!-- Using non-breaking hyphen & non-breaking space for improved table spacing. --> | ||
| Daemon | Type | DNSSEC support | | ||
| --- | --- | --- | | ||
| systemd‑resolved | Stub Resolver (local) | Yes. Enabled by default via `DNSSEC=allow-downgrade` setting. | | ||
| dnsmasq | Stub Resolver | Yes. Disabled by default. Controlled via `dnssec` and `conf-file=../trust-anchors.conf` settings. | | ||
| bind9 | Recursive Resolver | Yes. Enabled by default via `dnssec-validation auto;` setting. | | ||
<!-- TODO: What about "unbound"? --> | ||
|
||
The **systemd-resolved** stub resolver is pre-installed by default and comes with DNSSEC enabled in fallback mode (as of Ubuntu 25.10). This mode configures the `DNSSEC=allow-downgrade` setting in `/usr/lib/systemd/resolved.conf.d/00-enable-dnssec.conf` (installed by the *systemd-resolved-dnssec* package) and tries to validate the DNSSEC records whenever possible, but at the same time accepts unsigned responses for backwards compatibility with unsigned zones. | ||
slyon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
The functionality of DNSSEC in **systemd-resolved** can be confirmed, using the `dig` command on the local stub resolver at `127.0.0.53:53`, by checking for the existence of the **ad** (Authenticated Data) flag: | ||
``` | ||
$ dig @127.0.0.53 isc.org +dnssec | ||
[...] | ||
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 1 | ||
``` | ||
|
||
Should authenticity of DNS records be a concern to you, it's advised to override the default DNSSEC validation settings through an additional drop-in configuration in `/etc/systemd/resolved.conf.d/10-dnssec.conf`, which would reject any unsigned records, after reloading the configuration: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree that this needs clarification. The manpage uses the expression "support DNSSEC properly", and that leaves a lot of room for interpretation, both in the context of documentation, but also in what the correct response of the service is. For the "yes" value, it says "If the DNS server does not properly support DNSSEC all validations will fail.". |
||
``` | ||
$ cat /etc/systemd/resolved.conf.d/10-dnssec.conf | ||
[Resolve] | ||
DNSSEC=yes | ||
|
||
$ systemctl reload systemd-resolved.service | ||
slyon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
``` | ||
```{warning} | ||
Be aware that enforcing DNSSEC can lead to errors like `DNS_PROBE_FINISHED_NXDOMAIN` in your browser, especially for local, unsigned domains and you would only be able to reach such services by accessing them through their IP address directly. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why single out the browser? You could get errors everywhere, no? |
||
<!-- TODO: What about DNS64? (https://blog.apnic.net/2016/06/09/lets-talk-ipv6-dns64-dnssec/) --> | ||
``` | ||
|
||
Once DNSSEC validation is enforced, you should also be able to confirm it through higher level checks in your browser, e.g. using those 3rd party services: | ||
* https://internet.nl/test-connection/ | ||
* https://wander.science/projects/dns/dnssec-resolver-test/ | ||
|
||
```{note} | ||
In case of issues with Domain Name resolution, make sure to remove any drop-in configs for **systemd-resolved**, execute `systemctl reload systemd-resolved.service` and `apt remove systemd-resolved-dnssec`. This will reset any DNSSEC configuration to `DNSSEC=no` and can be confirmed by executing `resolvectl dnssec`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There could also be drop-in configs for resolved.conf, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't it easier to also, or perhaps instead of, instruct to remove the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In fact, those are only drop-ins for resolved.conf. And I need to re-phrase this whole section, as the |
||
``` | ||
|
||
## New Resource Records (RRs) | ||
DNSSEC introduces a set of new Resource Records. Here are the most important ones: | ||
|
||
|
@@ -112,6 +153,10 @@ This stub resolver has its own configuration for which recursive DNS servers to | |
DNS Servers: 10.10.17.1 | ||
DNS Domain: lxd | ||
|
||
```{note} | ||
Starting with Ubuntu 25.10 the *systemd-resolved-dnssec* package is pre-installed enabling the fallback mode as `DNSSEC=allow-downgrade/supported` | ||
slyon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
``` | ||
|
||
This configuration is usually provided via {term}`DHCP`, but could also be set via other means. In this particular example, the DNS server that the stub resolver (`systemd-resolved`) will use for all queries that go out on that network interface is 10.10.17.1. The output above also has `DNSSEC=no/unsupported`: we will get back to that in a moment, but it means that `systemd-resolved` is not performing the DNSSEC cryptographic validation. | ||
|
||
Given what we have: | ||
|
@@ -138,6 +183,10 @@ This is the case if you install the BIND9 DNS server: the default configuration | |
... | ||
}; | ||
|
||
```{note} | ||
Starting with version `1:9.18.34-1` in Ubuntu 24.10 and above, the `dnssec-validation auto` setting became the implicit default and does not need to be set explicitly in `named.conf.options` anymore. | ||
``` | ||
|
||
A critical aspect of this deployment model is the trust in the network segment between the stub resolver and the Validating Resolver. If this network is compromised, the security benefits of DNSSEC can be undermined. While the Validating Resolver performs DNSSEC checks and returns only verified responses, the response could still be tampered with on the final ("last mile") network segment. | ||
|
||
This is where the `trust-ad` setting from `/etc/resolv.conf` comes into play: | ||
|
@@ -159,7 +208,7 @@ Specifying `trust-ad` in `/etc/resolv.conf` implies in these assumptions: | |
|
||
When using `systemd-resolved` as a stub resolver, as configured above, the network path to the local DNS resolver is inherently trusted, as it is a localhost interface. However, the actual nameserver used is not 127.0.0.53; it depends on `systemd-resolved`'s configuration. Unless local DNSSEC validation is enabled, `systemd-resolved` will strip the ad bit from queries sent to the Validating Resolver and from the received responses. | ||
|
||
This is the default case in Ubuntu systems. | ||
This is the default case in Ubuntu systems until Ubuntu 25.04. | ||
|
||
Another valid configuration is to not use `systemd-resolved`, but rather point at the Validating Resolver of the network directly, like in this example: | ||
|
||
|
@@ -176,14 +225,15 @@ As these assumptions have a higher chance of not being true, this is not the def | |
In any case, having a Validating Resolver in the network is a valid and very useful scenario, and good enough for most cases. And it has the extra benefit that the DNSSEC validation is done only once, at the resolver, for all clients on the network. | ||
|
||
### Local DNSSEC validation | ||
Some stub resolvers, such as systemd-resolved, can perform DNSSEC validation locally. This eliminates the risk of network attacks between the resolver and the client, as they reside on the same system. However, local DNSSEC validation introduces additional overhead in the form of multiple DNS queries. For each DNS query, the resolver must fetch the desired record, its digital signature, and the corresponding public key. This process can significantly increase latency, and with multiple clients on the same network request the same record, that's duplicated work. | ||
Some stub resolvers, such as systemd-resolved, can perform DNSSEC validation locally. This eliminates the risk of network attacks between the resolver and the client, as they reside on the same system. However, local DNSSEC validation introduces additional overhead in the form of multiple DNS queries. For each DNS query, the resolver must fetch the desired record, its digital signature, and the corresponding public key. This process can increase latency, and with multiple clients on the same network request the same record, that's duplicated work. | ||
|
||
In general, local DNSSEC validation is only required in more specific secure environments. | ||
In general, local DNSSEC validation is still the most secure approach, validating the records end-to-end, without the need to trust any DNS server along the way. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a generic note, so we could even mention DoH, too. As both DoT and DoH could be used to increase privacy. |
||
|
||
As an example, let's perform the same query using `systemd-resolved` with and without local DNSSEC validation enabled. | ||
|
||
Without local DNSSEC validation. First, let's show it's disabled indeed: | ||
|
||
$ sudo resolvectl dnssec eth0 false | ||
$ resolvectl dnssec | ||
Global: no | ||
Link 44 (eth0): no | ||
|
@@ -194,7 +244,7 @@ Now we perform the query: | |
isc.org IN MX 10 mx.ams1.isc.org -- link: eth0 | ||
isc.org IN MX 5 mx.pao1.isc.org -- link: eth0 | ||
|
||
-- Information acquired via protocol DNS in 229.5ms. | ||
-- Information acquired via protocol DNS in 37.2ms. | ||
-- Data is authenticated: no; Data was acquired via local or encrypted transport: no | ||
-- Data from: network | ||
|
||
|
@@ -252,3 +302,4 @@ But even when the validation is local, simpler clients might not get the full pi | |
* [Tool to visualize the DNSSEC chain of trust of a domain](https://dnsviz.net/) | ||
* [DANE](https://en.wikipedia.org/wiki/DNS-based_Authentication_of_Named_Entities) | ||
* [RFC 4255](https://datatracker.ietf.org/doc/html/rfc4255) - Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints | ||
* {ref}`dnssec-troubleshooting` |
Uh oh!
There was an error while loading. Please reload this page.