Dear DNSOP,

At IETF 112, it was discussed whether owner names of bootstrapping records 
should be
- "plain", e.g. example.co.uk._dsauth.ns1.desec.io, or
- "hashed", e.g. example.<hash(co.uk)>._dsauth.ns1.desec.io.

Most people favored the plain form for its simplicity, and subsequently the 
authors removed the hashing logic from the draft. As a consequence of that, an 
ambiguity in the protocol has been exposed.

This message documents the details of that problem and potential ways of 
addressing it, both for future reference, and in order to move towards 
consensus regarding its resolution.

I am going to lay out the problem from scratch (apologies for the very long 
message; I hope it's worth the read!), and will be labeling the various 
arguments etc., so that it's easy to refer to them during discussion and to 
point at where exactly there is disagreement.

I'll start out with some presumed goals (which I call propositions for the sake 
of discussion). I would have thought that there is consensus about these, but 
some previous messages suggest that there isn't (although the discussion was 
not concluded back then; 
https://mailarchive.ietf.org/arch/msg/dnsop/hSDaiSbhLszrlln_TNfM0iKXwmU/). 
Generally, it would be interesting to establish consensus on which of these 
propositions the group considers goals for the DNS, and which it doesn't (even 
independently of the bootstrapping protocol).


# Proposition P1:
DNS protocols should aim to work on all levels of the DNS. As far as the 
bootstrapping protocol is concerned, it should thus not be restricted to 
delegations in an (effective) TLD zone, but work for DNSSEC-bootstrapping 
arbitrary delegations (at least in principle; deployment is a different 
question).

Rationale:
Otherwise, custom solutions are needed on other levels, indefinitely. We should 
be aiming to design a protocol that works everywhere, to avoid the extra 
complexity/effort/cost/source-of-error/... from custom solutions (at least in 
the long term). -- I can only speak for deSEC, where we do have custom 
mechanisms for DNSSEC management of internal delegations. If CDS/CDNSKEY-based 
bootstrapping and rollovers were natively supported in authoritative servers, 
we would *certainly* favor that over our custom stuff, which we would quickly 
get rid of.

In addition, zone owners should not have to worry about what's going on with zones in 
other parts of the DNS tree; things should "just work" for their domain, 
without cross-dependencies (whenever possible).


# Proposition P2:
Customers of DNS operators should be able to create zones that are not 
delegated yet. This includes creating multiple zones where one is a subzone of 
the other.

Rationale:
This allows preparing zone contents before delegation, to avoid downtimes etc.


# Proposition P3:
Bootstrapping records should be made available before delegation.

Rationale:
This is important because the parent's policy may be that only secure 
delegations will be performed (= setting NS and DS at the same time). (To my 
knowledge, there is at least one ccTLD registry working toward such a policy; I 
hope this will occur more frequently in the future.)


# Proposition P4:
DNS operators should make no assumptions about the order in which customers 
will create/delegate their zones, and should enable them to do so in any order. 
In particular, when a zone is configured, the operator cannot assume that the 
customer will not want to configure/delegate an ancestor zone (parent, 
grandparent, ...) at some later point in time.

Rationale:
Often, the higher-level domain will be delegated first. However, this is not 
always the case. For example, at deSEC, we have repeatedly observed that a 
customer who owns example.org first creates test.example.org and delegates the 
domain to us; once testing is completed, the customer creates their main zone 
example.org, and delegates that one to us. In this case, the parent gets 
delegated to us after the child is.

Another example is if a university hosts their own DNS service for example.edu 
(with DNSSEC), but (e.g.) conference stuff lives under conferences.example.edu 
which is delegated to some other provider. If the university later decides to 
migrate their main zone to the same provider (meanwhile going insecure 
temporarily), the parent will be delegated to that provider, who should then be 
able to *re-bootstrap* the delegation -- even as they are already operating the 
child (whose DNSSEC configuration remains untouched). It will not be 
understandable to the owner of example.edu why bootstrapping of that domain 
should not work in this case.

The same thing can happen with IPv6 reverse zones, where one is for a subnet of 
the other. Another case could be when _acme-challenge is delegated to a 
provider that integrates nicely with Let's Encrypt clients, and the main zone 
is migrated there later. In all of these cases, the DNS operator cannot foresee 
the order in which their customer will perform the delegations. It would be 
very unexpected for the customer (and look like a bug) if DNSSEC bootstrapping 
worked for some orders, but not for others.

(NB: Rejecting P4 by prescribing an order implies rejecting P1 as well, as the 
protocol wouldn't work on all levels at all times.)


# Proposition P5:
It should be possible for a DNS operator to structure a bootstrapping zone by 
introducing additional zone cuts below the _dsauth label.

Rationale:
Besides moving bootstrapping records for a certain parent to a subzone, there 
are other plausible reasons for zone cuts in the bootstrapping zone, such as 
when parts of the bootstrapping domain should run on a different nameserver, or 
use a new DNSSEC algorithm. I wouldn't know why an operator would want to do 
that now, but here's something I made up: let's say a computationally expensive 
post-quantum scheme is introduced; perhaps the operator wants to use that only 
to bootstrap domains whose parent (TLD) has adopted the algorithm, and save the 
cost otherwise.

(Other situations affected by this may include NS whitelabeling situations (I 
have not fully considered the implications here), and perhaps other future 
scenarios that are hard to foresee.)

Whether these scenarios make sense or not, I have a hard time justifying that 
operators would *never* want to do that and *not* run into an undesirable 
situation if this is made impossible by design. It thus seems worthwhile to me 
to keep that door open.

Having said that, rejecting P5 would also break with the history of the DNS, 
where zone cuts have been admissible and transparent everywhere in the tree.


# Consequences:
From propositions P1-P4, it follows that
C1. a DNS operator needs to allow a customer to create both test.example.org 
and example.org (regardless of whether they are delegated);
C2. the DNS operator needs to be able to provide bootstrapping records for both 
zones at the same time, at FQDNs like
        - test.example.org._dsauth.ns1.desec.io,
        - example.org._dsauth.ns1.desec.io;
C3. as a result, the DNS operator is not free to introduce a zone cut at 
example.org._dsauth.ns1.desec.io in the bootstrapping zone.

Conclusion C3 is in contradiction to proposition P5.

This is because bootstrapping records are of type CDS/CDNSKEY, which already 
have non-bootstrapping meaning when they occur at an apex (RFC 8078). It 
follows that a DNS operator cannot configure a zone cut within the 
bootstrapping zone (underneath the _dsauth level), because due to P4, they 
cannot assume that a customer would not create a zone which would require 
conflicting bootstrapping records at that same owner name. As a result, the 
bootstrapping records all have to live in one monolithic zone.

(If such a zone cut was done at, say, example.org._dsauth.ns1.desec.io, the CDS/CDNSKEY records at 
that name would turn on-apex, and as such would signal the key parameters for the 
"example.org._dsauth.ns1.desec.io" subzone and not the bootstrapping records for 
"example.org". This is the heart of the problem at hand.)


# Discussion
One can only accommodate the consequence C3 by asserting that structuring of a 
bootstrapping zone into subzones (in particular, by parental suffix) is not up 
to the DNS operator: zone cuts below _dsauth are effectively prohibited due to 
the semantic collision that otherwise arises. This is a (perhaps unexpected) 
departure from the tradtional way of things, in which zone cuts are pretty much 
orthogonal to anything else. The existence of zone cuts so far had no bearing 
on the semantics of zone data (ignoring cut-related records like NS and SOA). 
If such a restriction is desired, it should be explicitly specified as that.

Depending on which propositions one shares, one may dispute that there may be a 
problem in practice. But even then, as the ambiguity is known, the draft should 
address it one way or the other.

The following are the different solution approaches of which I am aware:


# Solution S1: Use a different record type, e.g. BDS/BDNSKEY ("bootstrapping 
DS/DNSKEY").

If this is done, the collision is removed completely. It requires more 
implementation work in DNS software (support by auth servers, client tools and 
libraries like dig/dnspython, etc.), but it is very clean.


# Solution S2: Use a hashed naming scheme to avoid the collision.

Contrary to intuition, this *is* practical to combine this with synthesis of 
bootstrapping responses (see below).

Mechanism: Fold all labels of the customer domain into a hash, except the 
first. With example.org and test.example.org, we would have the following 
bootstrapping names:
- example.<hash(org)>._dsauth.ns1.desec.io
- test.<hash(example.org)>._dsauth.ns1.desec.io

Bootstrapping records would always be at the leftmost level (off-apex), and 
zone cuts by parent suffix can be made at the second level from the left (and 
their CDS/CDNSKEY records can be used for RFC 8078 rollovers etc. as usual, 
without a collision).

Answering a query dynamically (with synthesis) requires reversing the hash, 
which means that a mapping needs to be stored. Note, however, that the mapping 
would *not* contain *each domain*, it would only contain *each immediate 
ancestor*. Typically, that would mean that the mapping would primarily contain 
*one entry per public suffix* used at the provider, changing only rarely.

The mapping could be stored via PTR records at the hashed label itself, e.g. 
<hash(co.uk)>._dsauth.ns1.desec.io IN PTR co.uk. This can be done at zone creation 
(or loading) time: when encountering example.co.uk, you would create this PTR record. 
Answering a query for example.<hash(co.uk)>._dsauth then requires an internal look-up 
of the PTR record at the hashed label, whose target is then appended to the first label of 
the query to construct the customer domain. This does not require any additional inverse 
search algorithms or reverse-indexed datastructures.

It also maximizes the applicability of the protocol to unusally long domain 
names (both in byte count and in number of labels) due to the fixed hash digest 
length.

A major downside is that to investigate bootstrapping records, administrators 
would have to deal with these hashes, at least as long as tools like dig 
wouldn't have built-in support.


# Solution S3: Allow bootstrapping only using the leaf domain under _dsauth.

If only the lowest level may be used for bootstrapping (and higher intermediate 
levels may not), one can put zone cuts at higher levels in the bootstrapping 
zone, with CDS/CDNSKEY records reserved for managing DNSSEC at the zone cut.

This approach violates P1, because the domain whose bootstrapping records would live at 
the zone cut can no longer be bootstrapped. Further, it violates P4, because 
bootstrapping would only work "in order" (from higher to lower level domains). 
This would mean that a customer who creates test.example.org for testing, and only later 
creates and delegates example.org, will be subject to silent failure of DNSSEC 
bootstrapping for their main domain. That is rather unexpected.

(Alternatively, DNS operators could prevent customers from creating the higher 
level zone (example.org) when a lower-level zone exists, so at least DNSSEC 
won't fail open silently. Additional logic / complexity / implementation 
requirements apart, this would violate P2.)

When taking this route, more complications arise: Should bootstrapping records 
be restricted to leaf names even if there is no zone cut above?
--> If yes, that violates P1 more strongly than necessary (that is, regardless 
of whether a zone cut would actually get in the way or not).
--> If no, then someone trying to make sense of CDS/CDNSKEY records at 
"example.org._dsauth.ns1.desec.io" would need to be aware of whether there is a zone cut, as the 
records' interpretation depends on it (bootstrapping records for "example.org" vs. RFC 8078-style 
rollover records for "example.org._dsauth.ns1.desec.io"). -- However, a client has no easy way of 
knowing this, nor should it have to implement [or remember to run, in case of an admin chasing a problem] 
complicated logic to figure out what the semantics are. (Besides, any such logic would be subject to race 
conditions, because the DNS is only eventually consistent.)


# Solution S4: Disallow CDS/CDNSKEY usage for DNSSEC management of subzones under _dsauth 
("bootstrapping has precedence").

This reserves CDS/CDNSKEY records anywhere under _dsauth for bootstrapping. If 
there is a zone cut, manual key management for it is required.

The price of this is to restrict the scope of on-apex CDS/CDNSKEY records, by 
making it illegal for them to appear below a _dsauth label. Issues in auth and 
library bug trackers would follow, discussing whether their input validation 
should catch such cases because no illegal data should be accepted, etc. People 
who have nothing to do with DNSSEC bootstrapping (e.g. dnspython maintainers) 
would be dragged into that stuff suddenly coming their way.

As a result, RFC 8078 key rollovers for subzones like 
"example.org._dsauth.ns1.desec.io" would be broken -- for no good reason except 
that a solution with less side effects was not found. It feels like a kludge to me and 
not like a sound technical solution.

In addition, P1 is violated, because the bootstrapping protocol wouldn't work 
to bootstrap subzones under _dsauth themselves.


# Solution S5: Disallow zone cuts under a _dsauth domain entirely.

In this case, all CDS/CDNSKEY records under a _dsauth domain are off-apex. The 
situation is effectively equivalent to S4, except that zone cuts would be 
forbidden (instead of requiring manual key management).

The proposal is simpler than S4 and does not require re-defining on-apex 
CDS/CDNSKEY semantics, but is also more restrictive. It codifies the departure 
from the previous custom that zone cuts could occur anywhere, violating P5.


# What now?
Solutions S3-S5 violate one or more of P1-P5, and/or break an existing standard (RFC 
8078) to some extent. I feel rather uneasy with that kind of "roadkill". For 
one, this is because the restrictions they introduce seem unnecessary to me: I'm not 
convinced that we need to compromise on the goals set out by P1-P5. I think we can do 
better.

Perhaps more importantly, I feel that S3-S5 intertwine different aspects of the 
DNS world that should not get entangled (e.g.: S4 touches the on-apex 
CDS/CDNSKEY specs although that should be orthogonal to off-apex use for 
bootstrapping; S3 introduces timing dependencies between zones and enforces 
related policies on DNS operators).

In order to minimize future headache, I think it is important to aim at minimal 
dependencies between components of the DNS, and we should strive for maximum 
orthogonality. (See also: "Orthogonality of features", 
https://blog.apnic.net/2018/03/29/the-dns-camel/)

S1 and S2 seem to approach the problem closer to its root cause: we have a (name, type) 
ambiguity, so the most "honest" solution would be to fix either the owner name 
(S2) or the record type (S1). Of course, these ideas have their disadvantages, too.

In any case: the current draft has nothing to say about the ambiguity problem, 
so it needs to be addressed one way or the other.

What does the WG think?

Best,
Peter


On 4/22/22 06:29, internet-dra...@ietf.org wrote:

A New Internet-Draft is available from the on-line Internet-Drafts directories.
This draft is a work item of the Domain Name System Operations WG of the IETF.

         Title           : Automatic DNSSEC Bootstrapping using Authenticated 
Signals from the Zone's Operator
         Authors         : Peter Thomassen
                           Nils Wisiol
        Filename        : draft-ietf-dnsop-dnssec-bootstrapping-00.txt
        Pages           : 14
        Date            : 2022-04-21

Abstract:
    This document introduces an in-band method for DNS operators to
    publish arbitrary information about the zones they are authoritative
    for, in an authenticated fashion and on a per-zone basis.  The
    mechanism allows managed DNS operators to securely announce DNSSEC
    key parameters for zones under their management, including for zones
    that are not currently securely delegated.

    Whenever DS records are absent for a zone's delegation, this signal
    enables the parent's registry or registrar to cryptographically
    validate the CDS/CDNSKEY records found at the child's apex.  The
    parent can then provision DS records for the delegation without
    resorting to out-of-band validation or weaker types of cross-checks
    such as "Accept after Delay" ([RFC8078]).

    This document updates [RFC8078] and replaces its Section 3 with
    Section 3.2 of this document.

    [ Ed note: Text inside square brackets ([]) is additional background
    information, answers to frequently asked questions, general musings,
    etc.  They will be removed before publication.  This document is
    being collaborated on at https://github.com/desec-io/draft-thomassen-
    dnsop-dnssec-bootstrapping/ (https://github.com/desec-io/draft-
    thomassen-dnsop-dnssec-bootstrapping/).  The authors gratefully
    accept pull requests. ]


The IETF datatracker status page for this draft is:
https://datatracker.ietf.org/doc/draft-ietf-dnsop-dnssec-bootstrapping/

There is also an HTML version available at:
https://www.ietf.org/archive/id/draft-ietf-dnsop-dnssec-bootstrapping-00.html


Internet-Drafts are also available by rsync at rsync.ietf.org::internet-drafts


_______________________________________________
DNSOP mailing list
DNSOP@ietf.org
https://www.ietf.org/mailman/listinfo/dnsop

--
Like our community service? 💛
Please consider donating at

https://desec.io/

deSEC e.V.
Kyffhäuserstr. 5
10781 Berlin
Germany

Vorstandsvorsitz: Nils Wisiol
Registergericht: AG Berlin (Charlottenburg) VR 37525

_______________________________________________
DNSOP mailing list
DNSOP@ietf.org
https://www.ietf.org/mailman/listinfo/dnsop

Reply via email to