Re: [DNSOP] [DNSSEC-Bootstrapping] Fwd: New Version Notification for draft-thomassen-dnsop-dnssec-bootstrapping-02.txt

Paul Wouters <paul.wouters@aiven.io> Tue, 09 November 2021 21:54 UTC

Return-Path: <paul.wouters@aiven.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 C5E9B3A118C for <dnsop@ietfa.amsl.com>; Tue, 9 Nov 2021 13:54:08 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.098
X-Spam-Level:
X-Spam-Status: No, score=-2.098 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, SPOOF_COM2OTH=0.001, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (1024-bit key) header.d=aiven.io
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id qQdqm0g7rWuO for <dnsop@ietfa.amsl.com>; Tue, 9 Nov 2021 13:54:03 -0800 (PST)
Received: from mail-ed1-x529.google.com (mail-ed1-x529.google.com [IPv6:2a00:1450:4864:20::529]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 95BBC3A1184 for <dnsop@ietf.org>; Tue, 9 Nov 2021 13:54:03 -0800 (PST)
Received: by mail-ed1-x529.google.com with SMTP id ee33so2147879edb.8 for <dnsop@ietf.org>; Tue, 09 Nov 2021 13:54:03 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aiven.io; s=google; h=from:date:to:cc:subject:in-reply-to:message-id:references :mime-version; bh=T7usfStJbuDGg4apZP+r/J8YP2NMPEMaBKnJp8ZSB7I=; b=qqJsL7xaxQf/o2DdW3BpR+3Wmu6CFRCKUDQ/kevUqCMHwZEzeGKyZSMIW9CdzUDp6c HNmW+vWTWD8OfCIthTfqkEsOjNWIpyhlmakNn+fNVqLgRJsoOrukeb4uuHkSojQhNBEq iTBE4Y5M8V9J2M1GEUGzErJMk91PsVY/espwQ=
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:date:to:cc:subject:in-reply-to:message-id :references:mime-version; bh=T7usfStJbuDGg4apZP+r/J8YP2NMPEMaBKnJp8ZSB7I=; b=hG1jv0/9n288d+kGUlUoouVg52CE14B+HUSpRDSSu2t3/yFulfuzooBfEcBSX4/o/F NqjWqStaSuixAiZZiWCYOzcn2J+HLCj5j1Vc3AxoogyfTPLI9pojBZWHt2eo9NW2+VRw iOPmhDGD+k4R0KFFOLhaOwpXWvUAsjjL+hfBjcyuFzybRPc/IZXweU7kimZ0xgwexDkR eG0bEd4s9gP/PmmgLYXj8K5CoilLkyWyQhb1tugBWgF0bMcNlWDwqL6T3gCpaFOYG/aH D+g524Mayq0U2Dj6ByBmnFKZAvP+qyJmH5A3+DxJtb4FmsE9lp9GFi/H2ZQhBJBTKOKf OzFg==
X-Gm-Message-State: AOAM530w6WYnhW0LREjWCTzcf4+tzb5DjXWkyCip1I3JilFXuMwwA5Ad wgEj1/i+XNdmZEB5Ss/fTTm64A==
X-Google-Smtp-Source: ABdhPJyRoble/09lwV0v5hFIHfsr3WT73yOHAIIo7JgyNm1n8oRQsSa6zdazdqfR5x+pdB7IFlY75w==
X-Received: by 2002:a17:907:7d86:: with SMTP id oz6mr13512050ejc.193.1636494840515; Tue, 09 Nov 2021 13:54:00 -0800 (PST)
Received: from bofh.nohats.ca (bofh.nohats.ca. [193.110.157.194]) by smtp.gmail.com with ESMTPSA id hc16sm8381481ejc.12.2021.11.09.13.53.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Nov 2021 13:54:00 -0800 (PST)
From: Paul Wouters <paul.wouters@aiven.io>
X-Google-Original-From: Paul Wouters <paul@nohats.ca>
Date: Tue, 09 Nov 2021 16:53:56 -0500
To: Peter Thomassen <peter@desec.io>
cc: Paul Wouters <paul.wouters@aiven.io>, Paul Wouters <paul.wouters=40aiven.io@dmarc.ietf.org>, "dnsop@ietf.org WG" <dnsop@ietf.org>, dnssec-bootstrapping@ietf.org
In-Reply-To: <26f99653-0b88-1226-fa7d-6ce6267c9eea@desec.io>
Message-ID: <608f2d3d-6e63-7e33-2c52-bd78aa4e9f39@nohats.ca>
References: <163520620129.17275.16274772439094875607@ietfa.amsl.com> <91154628-0ca3-15d8-c6bd-b71232b2e64b@desec.io> <8d3b2ae-70e3-74b4-40a0-70e848acc4aa@nohats.ca> <66e2a81b-b971-cdea-0f40-cfed68be574f@desec.io> <705c1434-532-6840-8ae4-545bde91822@nohats.ca> <37fa7324-643a-9c3c-4256-97abe52f1118@desec.io> <2c8d972a-1388-2f42-994-56a58fe03916@nohats.ca> <26f99653-0b88-1226-fa7d-6ce6267c9eea@desec.io>
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="1858192029-566812725-1636494839=:281022"
Archived-At: <https://mailarchive.ietf.org/arch/msg/dnsop/hSDaiSbhLszrlln_TNfM0iKXwmU>
X-Mailman-Approved-At: Tue, 09 Nov 2021 13:57:41 -0800
Subject: Re: [DNSOP] [DNSSEC-Bootstrapping] Fwd: New Version Notification for draft-thomassen-dnsop-dnssec-bootstrapping-02.txt
X-BeenThere: dnsop@ietf.org
X-Mailman-Version: 2.1.29
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: Tue, 09 Nov 2021 21:54:09 -0000

On Tue, 9 Nov 2021, Peter Thomassen wrote:

> On 11/9/21 3:56 PM, Paul Wouters wrote:
>>>  Now let's consider bootstrapping for dedyn.io *itself* (not one of its
>>>  children!).  The location of the bootstrapping records for this domain
>>>  would be dedyn.io._boot.ns1.desec.io, which is the same as the name of
>>>  the *zone* which constains bootstrapping records for domains *under*
>>>  dedyn.io, such as at example.dedyn.io._boot.ns1.desec.io.
>>
>>  Aren't you saying here that you want to be able to boostrap dedyn.io,
>>  meaning it is currently unsigned, while also having a problem with
>>  containing its "children", eg it is already used for boostrapping
>>  other domains, while it it unsigned yet itself ?
>
> In such a situation, a domain like dedyn.io (which has other subzones
> on the same nameserver) is not necessarily already being used for
> bootstrapping.
>
> Example: Imagine a DNS operator which supports both DNSSEC and
> bootstrapping.  They have a customer with the zone example.com and
> a subzone foo.example.com, but DNSSEC is currently off.
>
> Suppose the customer turns on DNSSEC in the operator's service portal.
> What will happen now is that the _boot zones under the operator's
> nameserver hostnames will be populated with bootstrapping records for
> these domains, with prefixes example.com._boot and
> foo.example.com._boot.

I think in this case, you cannot start foo.example.com._boot. because
its parental agent (which happens to be you too but should still follow
the RFC) detects that the parent zone example.com is not signed and
thus cannot perform a bootstrap of foo.example.com. Doing them at once
would be a race condition. You'd really want to do these one after the
other.

> Remember, the bootstrapping records are of type CDS/CDNSKEY, and they
> will now show up both at the level of "foo.example.com._boot" and one
> level up, at the level of "example.com._boot".

But can't you still publish all of these? like:

in dedyn.io zone (or ns1.dedyn.io zone or _boot.ns1.dedyn.io zoe):

example.<hash-of-example.com>._boot.ns1.dedyn.io IN CDNSKEY [...]
foo.<hash-of-foo.example.com>._boot.ns1.dedyn.io IN CDNSKEY [...]

in your example.com zone:

example.com. IN CDNSKEY [...]

In your foo.example.com zone:

foo.example.com. IN CDNSKEY [...]

> As a result, the DNS operator is no longer free to make a delegation
> at "example.com._boot", because that would change the meaning of the
> bootstrapping records.  (CDS/CDNSKEY records have a conflicting meaning
> when they occur at an apex.)

I still don't see the APEX problem?

> However, there's nothing wrong with enabling bootstrapping records
> for both these domains at once.

I think there is. You can't boostrap a domain whose parent is not
already fully DNSSEC enabled. As those parents are not valid candidates
to take in CDS records.

>  There's no reason why DS records for
> foo.example.com should not be put into example.com while
> bootstrapping for example.com is running in parallel.

There is because the parent is unsigned and so whatever it is publishing
about its children is lacking trust.

>  (It's not
> even necessary for example.com to ever be securely delegated, if there
> is another trust root for it, e.g. in an enterprise setting.)

There is. nothing under example.com will ever DNSSEC validate. It cannot
make claims abouts its sub delegations via DS records as those DS
records would be bogus.

> DS bootstrapping does not require the parent of the bootstrapped domain
> to be secure.  The protocol should not concern itself with the chain of
> trust above the domain that is being bootstrapped.

This intension was not clear to me from reading the draft. You want to
DNSSEC bootstrap "islands of trust" ? I think that should be out of
scope. You are then already in enterprise/provisioning territory where
this provisioning can just be added without this new protocol.

> The protocol should not make any assumptions like that, so that
> bootstrapping of several domains along the same branch in the DNS tree
> (e.g. example.com, and foo.example.com) can be fully orthogonal.

I disagree. Sure you can have an island of trust, eg a manually
configured trust anchor for internal.example.com with a DS trust anchor,
but then you should still insist on all checks from internal.example.com
to be securely delegated. So you first have to do foo.internal.example.com
before you can do bar.foo.internal.example.com.

While I think this is true from a security and logical point of view, I
think you will run into practical issues if you are attempting to
retrieve or publish DS records that lack DNSSEC validation.

> Let's consider the bootstrapping namespace under _boot.ns1.desec.io.
> There would usually be NS/DS records at this name.
>
> However, it should be possible to introduce zone cuts underneath that
> name, so operators can control the size and churn of the zones involved
> in bootstrapping.  This idea madeit into the draft based on feedback
> by John Levine, who pointed out that scalability should be a very
> strong priority.
>
> So, there may be additional NS/DS rrsets at com._boot.ns1.desec.io, or
> dedyn.io._boot.ns1.desec.io.

But then you are most certainly better of without hashing, because then
you can make a zone for each <tld>._boot.ns1.desec.io. Or when you see
that foo.tld is a generic domain too that is becoming too large, create
a zone for foo.tld._boot.ns1.desec.io.

Whereas with hashes, you just have an unpredictable flat <blob>._boot.ns1.desec.io zone.

> Adding such a delegation turns the corresponding name into an apex, and
> thus requires that there are no bootstrapping CDS/CDNSKEY records at
> that name, because they would silently change in meaning.

Ok, so I think you are saying that for:

example.com._boot.ns1.desec.io. IN CDS [..]

or

example.<hash-of-com>._boot.ns1.desec.io. IN CDS [..]

or

com._boot.ns1.desec.io. IN CDS [..]

That without the <hash> method, having a zone cut at
com._boot.ns1.desec.io. could somehow change the meaning ?

You would have an NS and DS record for com._boot.ns1.desec.io., but
not for example.com._boot.ns1.desec.io. where you would have a CDS
or CDNSKEY. In fact, the lack of NS for example.com._boot.ns1.desec.io. means
that you are not using CDS to update a DS.

I don't see the "silently change in meaning" ?

> The problem is that if we now put bootstrapping records at these
> delegation points, they suddenly take on the meaning of conventional
> (non-bootstrapping) CDS/CDNSKEY records for these subzones.

So for com._boot.ns1.desec.io. I dont see that happening, but I guess
if you do both example.com._boot.ns1.desec.io. and
foo.example.com._boot.ns1.desec.io, then you have:

com._boot.ns1.desec.io. IN NS ....
com._boot.ns1.desec.io. IN DS ....
example.com._boot.ns1.desec.io. IN CDS ....

If this last record is treated in the "regular" way, that means that example.com._boot.ns1.desec.io.
is signaling to com._boot.ns1.desec.io to update its DS record. But
there is no zone cut there, so the "traditional" meaning has no effect.

In a way, this is just the same as me publishing www.example.com IN CDS [...]. No one will ever
ask for the record since there is no NS for www.example.com. So there is
no way for "current deployed software" to do anything wrong. In your
document, you could simply say "no bootraps are allowed under a _boot"
delegation.

I don't think this issue is improved by using hashes.

Now let's say you want to use CDS for com._boot.ns1.desec.io. to notify boot.ns1.desec.io.

You would publish:

com._boot.ns1.desec.io. IN CDS ....

Now someone could think you are boosttrapping for com. Someone could
fake the (unsigned) com NS records to be ns1.desec.io. And they could
possible convince com's parent to do dnssec bootstrap. If the attacker
manages to trigger the boostrap in com's parent, the parent would still
find com is either A) already signed so only CDS in com directly can be
used to update, not this bootstrap, or B) unsigned, in which case I
again press my point that nothing under an unsinged delegation should
qualify for booststrap anyway. Still the common non-attack case here
would be that com has no nameserver ns2.desec.io so the bootstrap would
be aborted. Meanwhile, your nameservers involved in the com._boot.ns1.desec.io.
and _boot.ns1.desec.io zones can still use regular CDS updating,
verifying the CDS/CDNSKEY is really in use for that domain and proceed
with publication of the updated DS record.

>>>  Now let's consider bootstrapping for dedyn.io *itself* (not one of its
>>>  children!).  The location of the bootstrapping records for this domain
>>>  would be dedyn.io._boot.ns1.desec.io, which is the same as the name of
>>>  the *zone* which constains bootstrapping records for domains *under*
>>>  dedyn.io, such as at example.dedyn.io._boot.ns1.desec.io.
>>
>>  So as stated above, I don't think this is a valid use case, as you need
>>  the bootstrap already in place ?
>
> You don't need that.
>
> You only need a validation path to exist for each NS hostname (and the
> _boot zone underneath).

We disagree. I think the boostrap should only extend the validation path
from a parent zone to the child zone. It should not try to skip a
zonecut in the hierarchy. Yes this causes a delay to deploy, but you
need some delay for security anyway and people won't be deploying 7
delegations deep dnssec bootstraps, or if they do, a 7*1 day delay is
fine.

>>>  This has nothing to do with in-bailiwick.  The problem occurs because
>>>  bootstrapping records cannot be at the apex (as to not overload the
>>>  meaning of apex CDS/CDNSKEY records), but by "inheriting" the structure
>>>  under dedyn.io, a situation arises where this condition is not met.
>>>
>>>  The solution is to not "inherit", but flatten the hierarchy, which is
>>>  what the hash does.  With hashing, children of dedyn.io would have
>>>  their bootstrapping records under h(dedyn.io)._boot.ns1.desec.io, such
>>>  as example.h(dedyn.io)._boot.ns1.desec.io.
>>
>>  I would think you could still use exmaple.dedyn.io._boot.ns1.desec.io.
>>  (regardless of hashing or not). But you need desec.io to already be DNSSEC
>>  signed, and since you control desec.io, it should be trivial to add NS
>>  and DS for _boot.dedyn.io, or TLD._boot.dedyn.io without needing to
>>  bootstrap?
>
> I am not following.

the boostrap is usually needed to bridge the gap of Registrar and DNS
Hoster. If the DNS hoster already has signed dnshoster.com, then they
can just atomically create NS/DS records for _boot.ns1.dnshoster.com.
They are not depending on another party that lacks the automation to
deploy DNSSEC.

>>>  It is unclear to me how such situations would properly be dealt with if
>>>  the bootstrapping owner names retained the target domains' hierarchy.
>>
>>  Can you explain why the above wouldn't work ?
>
> In the general case, there will be a collision between bootstrapping
> records and conventional apex-level CDS/CDNSKEY records, unless
> delegations within the _boot subtree are prohibited.

Yes :) But I hope I managed to point out you can still use CDS/DS within
your bootstrap without the double meaning of the names outside the
bootstrap chain.

>>>  One could of course specify that you can only ever bootstrap *one*
>>>  name along a certain branch of the DNS tree.  But what would be the
>>>  motivation for such a limitation?
>>
>>  No, you should be able to do all the domains you want, as long as you
>>  prefix them into the _boot zone?
>
> Only if you enforce there are no delegations there, within the _boot
> zone.

See above. I think you can.

>>>  I'm sure the situation could be complicated futher by considering more
>>>  sophisticated delegation hierarchies (e.g. dedyn.io is at ns1.desec.io,
>>>  foo.dedyn.io is not, but bar.foo.dedyn.io is again at ns1.desec.io, and
>>>  so on).  These are all things the protocol should be ignorant of.
>>
>>  I don't think that needs to matter, you can even run NS/DS onto
>>  _boot.ns1.dedyn.io with only ns1 as its nameserver and _boot.ns2.dedyn.io
>>  with only ns2 as its nameserver?
>
> I am not following.

I was trying to say that I think these all work fine, with or without
delegations in the FQDN path of the bootstrap names.

>>>  The hash ensures that *different things* get *different names*.
>>
>>  But the DNS is already pretty good at that with FQDNs?
>
> The DNS provides sufficient naming capabilities, yes.  My point is that
> in your proposal, when dedyn.io and its children are hosted on the same
> nameserver, two different things will turn up with the same name:
>
> 1.) the name of the bootstrapping records for dedyn.io
> 2.) the name of the zone containing bootstrapping records for children
>     of dedyn.io
>
> The name in question is: dedyn.io._boot.ns1.desec.io
>
> CDS/CDNSKEY records at that name can now mean two things:
>
> - They could mean "thing 1", i.e. bootstrapping records for dedyn.io

Yes.

> - They could mean "thing 2", that is DS rollover for the bootstrapping
>   zone *itself* (dedyn.io._boot.ns1.desec.io)

No?

If your zone cut is at io._boot.ns1.desec.io or _boot.ns1.desec.io, then
CDS dedyn.io._boot.ns1.desec.io does not have a traditional (C)DS record meaning,
as there is no NS (zonecut) for dedyn.io._boot.ns1.desec.io.

If your zone cut is at dedyn.io._boot.ns1.desec.io because you have many
delegations for <customers>.dedyn.io then the interpretation of CDS cannot
be for boostrap because dedyn.io is already DNSSEC signed (or else you
cannot / should not accept secure delegations for <customers>), so its
intepretation is always for a classic DNSKEY roll signaling of the zone
dedyn.io._boot.ns1.desec.io to its parent (either io._boot.ns1.desec.io
or _boot.ns1.desec.io or ns1.desec.io or even desec.io). If you would
try to mean it as this protocol and old software reads it as
traditional, that software would abort too if it is unsigned. So I don't
think you can accidentally break things either?

> It's not explicit what's meant, so there's an ambiguity.  Worse, if
> you add or remove the delegation at dedyn.io_boot.ns1.desec.io, the
> meaning of CDS/CDNSKEY records at that name silently changes.

But the meaning only changes from one invalid use to another invalid
use?

> So, yes, the DNS is good at naming things differently, but we have to
> create a naming scheme that is free of collisions.

I am not convinced. See above. I think it is clear based on where the
(C)DS records are and who would even query for it at that particular
location.

I don't think it helps scaling either because large zones are pretty
trivial these days and all these records are fairly short lived
(days). I doubt we will see 60M of these on 1 nameserver. Can you (or
John) explain what you think is the scale that would no longer work on
a DNSSEC system? And how would that scaling compare to the CPU/disk
required to generate new DNSKEYs for all those new DNSSEC domains,
signing the domains and creating CDNSKEY/CDS records for them?

And regardless, you can create delegatations for com._boot just as
easilly as <hash-of-com>._boot.

I think it only helps prevent hitting the theoretical but non-real
FQDN limit of 255, but as I said before, anything that prepends an
_underscore prefix will always have a limit under 255. Not using hashes
would reduce the max length to 128 minues the _boot prefix length versus
255 - 64 (length of base64(sha256)) - _boot prefix length.  So more or
less reduce support of FQDNs from ~200 to ~128. This already requires a
minimum of 3 subdelegations, but since most TLDs dont exceed ~10 to
~20, would require 4+ delegations. At which point you should really be in
part of the DNS tree where you control all parties to provision zones
without needing the bootstrap, that is mainly aimed at Registrar - DNS
Operator limitations. Eg you would be using catalog zones with your
nameservers that would be able to do CDS -> DS because of existing XFR
or NSUPDATE based trust relationships, or would even run on the same
nameserver to completely automated DS updates when hosting both child
and parent.

Anyway, just to reflect, I _do_ like and this idea, but strongly prefer no
hashing and not using it to go two delegations deep over unsigned parents.

Paul