Subject: [Acme] .well-known for dns challenges

From: Stephen Farrell <[email-masked]>
Date: Sun, 14 Jul 2019 22:07:32 +0100

Hiya,

I've a couple of questions as to 1) whether there are
any security issues with a thing I've done, (described
below) and 2) if it'd be worthwhile documenting something
like this.

I've been working on encrypted SNI and as part of that
have built a test server. It seems sensible that some
web sites using ESNI might use wildcard certificates
so the DNS names that will be encrypted SNI values
don't need to appear in e.g. CT logs. So that's what
I've done. For wildcard certs, the CA I'm using
(letsencrypt) requires DNS challenges.

In my setup, I don't have an API that allows the web
server to write to the DNS. Many web server setups
might have such an API, but I suspect many others are
like mine, and do not. Instead I have a separate
"zone factory" machine that manages zone files and can
poll the web server to see if there are any new DNS
challenges that need publishing whenever a wildcard
cert is due for renewal. The zone factory then takes
care of updating the zone, DNSSEC re-signing, AXFR
etc.

What I've done is setup weekly cronjobs on the web server
and the zone factory machine, so when a wildcard cert
needs renewing and the CA sends some new DNS challenges
for the wildcard cert, I have the web server put those
in a JSON file that can be retrieved at:

   https://$DOMAIN/.well-known/acme/dhs-challenges

The zone factory polls (a few mins later) for new content
at the above URL, and if there is and all looks good,
updates the zone to put TXT RRs at _acme-challenge.$DOMAIN.

A few minutes after that's done the web server (via a
another cronjob) checks if the correct new values have
been published in the DNS, and once it sees that's been
done, it finishes off the ACME renewal process with the
CA.

Note that I'd be entirely happy to change the URL above
and/or the syntactic-sugar around the content expected to
be found there if there were a desire to document this.

As it happens, I had more or less the same issue with
updating ESNIKeys, and wrote up [1] for that. A read of
that short draft might provide more background if the
above's not clear.

So, again, I'm wondering if there're any security issues
with doing this - it seems ok for my use-case, but maybe
there're downsides if it were done in other situations,
or maybe I'm being dim and missing something obvious;-)

And secondly, I wonder if it'd be worth documenting it
and registering some new .well-known value for this.

Thanks in advance,
S.

[1] https://tools.ietf.org/html/draft-farrell-tls-wkesni

---

From: Ted Hardie <[email-masked]>
Date: Mon, 15 Jul 2019 09:00:33 -0700

Howdy,

A reply in-line.

> updates the zone to put TXT RRs at _acme-challenge.$DOMAIN.
So, if I were personally configuring a similar system, I would avoid
.well-known, because it makes the information available to anyone who polls
for it.  That gives information to an attacker about when the renewals are
occurring and what the challenges are.   They still need to successfully
mount an attack to make use of it, but I don't see the reason to put that
in a publicly accessible director.  I would probably personally use rsync
of a directory with a similar check.  If I had to use HTTPS for some
reason, I would probably put it in a directory which required a distinct
authorization from any other data on the web site and pull it that.

The rest of this flow looks fine.

> If you did document this, I would suggest modifying it as above.  I'm not
personally sure that this is any value to making the directory a standard.

Just an initial reaction, and I may be missing a goal of the set-up here,

Ted

> _______________________________________________
> Acme mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/acme
>

---

From: Jacob Hoffman-Andrews <[email-masked]>
Date: Mon, 15 Jul 2019 10:30:03 -0700

This seems like a clever idea! As Ted said, .well-known probably isn't 
the right directory for it. If you put something in .well-known, that 
suggests you plan to standardize it and register it with IANA.

I'll also note that you may have a bootstrapping problem: Assuming that 
you verify certificates on those polling requests to your web server, 
this solution won't work before you've actually issued your first 
certificate. Similarly, if there's every a problem that results in your 
live certificate expiring, this process would fail.

It's also worth noting that Let's Encrypt requires DNS challenges for 
wildcards because they demonstrate more control over the domain 
namespace, and are less vulnerable to temporary hacks of the web server. 
You fully control the namespace, so you definitely have the ability to 
delegate that control in any way you see fit. Just keep in mind that 
this allows someone with temporary access to your nameserver to get a 
more powerful wildcard certificate than they otherwise would be able to.

If you wanted to add some more security, you could narrow the scope of 
accepted certificates on the polling connection to your web host, or 
(even better) have some file-level signing of the fetched JSON. Since 
you control both sides, an HMAC (rather than a public key signature) 
would suffice.

Lastly, have you seen acme-dns? This might be another way to accomplish 
the same thing, and has the advantage that more people are using it and 
therefore more likely to find bugs. https://github.com/joohoi/acme-dns

---

From: Stephen Farrell <[email-masked]>
Date: Tue, 16 Jul 2019 17:44:36 +0100

Hiya,

> suggests you plan to standardize it and register it with IANA.

Sure, I'm not scared of .well-known or IANA:-)

IIUC, the .well-known registry rule is specification required,
so it'd not have to be a standard. Clearly though, if nobody
else wanted to use it, there's not much point in having it in
the registry.

> live certificate expiring, this process would fail.

Yes. For me, that's ok as I can sort both manually. I'm not sure
if it'd be worth trying to automate those, as people for whom those
are big issues are (I'm guessing, but don't know), likely to have
a DNS API to use.

But I'd be fine with adding some way to handle bootstrap and expiry
if there's something reasonable that can be done there.

> more powerful wildcard certificate than they otherwise would be able to.

Yep, in my case the zone factory is in total control of the zones.
I didn't say earlier but the script I run on the zone factory knows
the exact names that'll be handled in this manner, won't poll for
(challenges for) any other names, and hence I think it's ok in that
respect.

> you control both sides, an HMAC (rather than a public key signature)

Ack.

> therefore more likely to find bugs. https://github.com/joohoi/acme-dns

I hadn't seen that, no. Don't think it'd work for me, as we have an
existing DNS setup that we'd like to keep using.

Cheers,
S.

---

From: Stephen Farrell <[email-masked]>
Date: Tue, 16 Jul 2019 17:44:39 +0100

Hiya,

On 15/07/2019 17:00, Ted Hardie wrote:
> ..well-known, because it makes the information available to anyone who polls
> for it. 

Yep. OTOH so does the DNS once you know the name.

> That gives information to an attacker about when the renewals are
> in a publicly accessible director. 

That did bother me a bit. My reasoning was that since the challenge
gets published in the DNS it has to be ok to publish it elsewhere.

I was also a bit concerned that a bad actor can predict the timing,
but I think that's more down to the CA and the ACME client. With LE
for example, IIUC anyone can calculate likely times for renewal given
the current cert. It might be worth adding a bit of randomness in
there somewhere maybe.

> I would probably personally use rsync

That'd also work. In my case, I didn't want to have to configure
anything about the zone factory on the web server, just out of
sheer laziness:-) I considered maybe encrypting the challenges for
the zone factory (via PGP) as well, in case we ever end up with
some kind of challenge that'd need that, but in the end I guess
that's not needed.

> personally sure that this is any value to making the directory a standard.

I went for a .well-known for the same laziness reason - it
saves me having to configure anything except the name on the
zone factory.

Cheers,
S.

---

From: Benjamin Kaduk <[email-masked]>
Date: Fri, 19 Jul 2019 17:17:18 -0500

I don't have much to add, but...

> saves me having to configure anything except the name on the

... just in case it's not clear to anyone, you shouldn't put anything in
/.well-known unless you intend to register it or are willing to suffer the
consequences of someone else registering it [for different use].  I don't
have any arguments for or against /.well-known in this case that haven't
already been mentioned.

-Ben