Re: [DNSOP] I-D Action: draft-ietf-dnsop-dnssec-bootstrapping-00.txt

Peter Thomassen <peter@desec.io> Wed, 27 April 2022 03:13 UTC

Return-Path: <peter@desec.io>
X-Original-To: dnsop@ietfa.amsl.com
Delivered-To: dnsop@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 68829C1B1614 for <dnsop@ietfa.amsl.com>; Tue, 26 Apr 2022 20:13:53 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -3.753
X-Spam-Level:
X-Spam-Status: No, score=-3.753 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, NICE_REPLY_A=-1.857, RCVD_IN_ZEN_BLOCKED_OPENDNS=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001, URIBL_DBL_BLOCKED_OPENDNS=0.001, URIBL_ZEN_BLOCKED_OPENDNS=0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=a4a.de
Received: from mail.ietf.org ([50.223.129.194]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id skSYKApUcC7N for <dnsop@ietfa.amsl.com>; Tue, 26 Apr 2022 20:13:48 -0700 (PDT)
Received: from mail.a4a.de (mail.a4a.de [IPv6:2a01:4f8:10a:1d5c:8000::8]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 5916CC1B1603 for <dnsop@ietf.org>; Tue, 26 Apr 2022 20:13:48 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=a4a.de; s=20170825; h=Content-Transfer-Encoding:Content-Type:In-Reply-To:From: References:To:Subject:MIME-Version:Date:Message-ID:Sender:Reply-To:Cc: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=Umfvgvqcn9D4UbNPYBC1zD3GYTAixRZJuASRETCDG1w=; b=MDaduQdFPDa0L21kry5hCOyRt6 YCxYXGpHwqOA4OcK9xvcHkGVFHgMIpKrTU4dmXU1yJ9HgTwF3JHLtTfMw4ue2doHalmG4R0AcKuxT QggnaoBs/WG/W3NBti9s4Z88Mw2Y/uEF2I0JB/3FTTsLMXa0UhGR+cx50S8nDRZ5dwFA0GPvm0eQ6 S0O8jVdGKyKl8+e7RLsDkeD2MBNRxeYYO3+6lYZjCMYMZNpuJBomAWj0UDSY9DZ+ZyN9s6MQUbcZJ 7S9oOVbCEVec38YQDuzpX08yHRhn+6MSAGBFulb1IC7RzcZmHb7bmEADwnaG1w+B8HWfMC+mIAPna Bc7B9VMw==;
Received: from 2603-9001-0e08-d96f-3639-29c8-2f55-9aff.inf6.spectrum.com ([2603:9001:e08:d96f:3639:29c8:2f55:9aff]) by mail.a4a.de with esmtpsa (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from <peter@desec.io>) id 1njY7d-0000un-8Q for dnsop@ietf.org; Wed, 27 Apr 2022 05:13:45 +0200
Message-ID: <d4e523b5-d86f-e3d0-c855-6cc2eb265dc5@desec.io>
Date: Wed, 27 Apr 2022 05:13:40 +0200
MIME-Version: 1.0
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.8.0
Content-Language: en-US
To: dnsop@ietf.org
References: <165060179936.9371.9524090867766025543@ietfa.amsl.com>
From: Peter Thomassen <peter@desec.io>
In-Reply-To: <165060179936.9371.9524090867766025543@ietfa.amsl.com>
Content-Type: text/plain; charset="UTF-8"; format="flowed"
Content-Transfer-Encoding: 8bit
Archived-At: <https://mailarchive.ietf.org/arch/msg/dnsop/FE5Sm5vzZtq9VgKxgkfmv4VuVI8>
Subject: Re: [DNSOP] I-D Action: draft-ietf-dnsop-dnssec-bootstrapping-00.txt
X-BeenThere: dnsop@ietf.org
X-Mailman-Version: 2.1.34
Precedence: list
List-Id: IETF DNSOP WG mailing list <dnsop.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/dnsop>, <mailto:dnsop-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/dnsop/>
List-Post: <mailto:dnsop@ietf.org>
List-Help: <mailto:dnsop-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/dnsop>, <mailto:dnsop-request@ietf.org?subject=subscribe>
X-List-Received-Date: Wed, 27 Apr 2022 03:13:53 -0000

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-drafts@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