Hacker News new | ask | show | jobs
by 3dfan 2314 days ago

    You can point the _acme-challenge
    record to another domain using a CNAME
Yes. Then you need two domain name servers to serve your domain. And you need to write and maintain code to talk to the API of the second nameserver.

That's what I call a pain in the ass.

7 comments

> Then you need two domain name servers to serve your domain.

Or, as I explained further down, a sub-domain.

> And you need to write and maintain code to talk to the API of the second nameserver.

Which was several dozen lines of shell (used as a hook in our LE client), which we haven't needed to touch since we wrote it a year ago. Hardly a Sisyphean task.

> That's what I call a pain in the ass.

Often less of a pain than dealing with many CAs manually.

I mean it's a pain but why is this LE's problem? The company hosting your domain doesn't support programmatically updating records so the least-effort path ends up paying someone that does like the $0.20/month to host the records with an easier to use API.

Unless you're using a very obscure DNS hosting service you shouldn't need to write any code. There are already made plug-ins for just about everyone.

Can you name such a "someone"? I've been searching, but the space seems very spammy.
I'm gonna focus on certbot since it's the main player in this space but there are other ACME clients that might have better support for other providers.

* Route53. The plug-in is straightforward with the relevant IAM policy to allow a service account to change your records being already written for you. You end up just copying the tokens, and the arn of the zone into the config file and you're off.

* Google CloudDNS. Google's IAM system is a little more complicated if all you want is a DNS hosted zone but once you have a service account with the right permission and the JSON blob in place the plug-in is actually easier to use since it has the ability to programmatically find your zone based on the name instead of copying the arn.

* DNSimple and DigitalOcean. No IAM policy to fiddle with. Just grant an API token from your account, plug it into the config file, and you're done.

* RFC2136. Not super useful unless you're doing on-prem stuff but really nice if you are. The config format for this one is super finnicky and you'll be reading docs to generate the keys but once you have it it's pretty smooth.

For another example, Terraform's acme_certificate resource lists 60 DNS services it works with for the DNS challenge.
> Can you name such a "someone"?

How about anyone on the list that's supported by the lexicon utility:

> Lexicon provides a way to manipulate DNS records on multiple DNS providers in a standardized way. Lexicon has a CLI but it can also be used as a python library.

* https://github.com/AnalogJ/lexicon

Doing a quick count, they support 60 APIs.

Amazon Route 53 is one example, there are probably other vendors.
Azure DNS can be scripted from *nix using Azure CLI and from Windows using PowerShell. You can use the certbot verification hooks to run the requisite scripts.
No, you only need an additional name server to serve one name, and it doesn't even have to be particularly reliable or fast or anything for most uses, as long as it's available at some point for a cert renewal before the old cert expires.

So, you can just put that nameserver on any machine that has a static IP address, or even a semi-static address, like, your home router or something.

Additionally, there are pre-built tools designed for exactly this purpose (e.g. acme-dns), so it's not like you even have to write any code to set this up.
More of a pain in the ass then working with a traditional CA's web frontend, generating your signing certificate, waiting for them to call and verify because you want EV, then downloading the bundle from their site and extracting it then putting it into the (hopefully) automation that pushes it out to all of your servers needing the wildcard?
> Then you need two domain name servers to serve your domain.

If you are a mega-corp and have multiple country-specific domains that redirect (apple.ca/ -> apple.com/ca/) then having most of your DNS be "static" and your scripts only talk to one 'canonical' (sub-)domain (e.g., dnsauth.apple.com) may be less hassle: instead of dealing with scripting n>1 domains, you only have to deal with n=1.

Well known registrars wouldhave a maintained code. Sounds fine to me. Someone has to maintain it, but it is amortized over the population
I haven't looked at DNS in depth in a very very long time. My recollection is that it is a pretty simple protocol. Is that still the case?

If it is, I wonder if it would be reasonable to build a small stand-alone DNS server specifically to use with Let's Encrypt for this. You run this on your own server, and it only handles the domains that you need to satisfy Let's Encrypt.

Point the _acme-challenge record there with a CNAME on your "real" DNS server, and whenever you are getting or renewing a Let's Encrypt certificate, bring up the small stand-alone server.

When the certificate issues or is renewed, shut down the small stand-alone server.

Some Googling of the form "simple DNS server $LANG" for various programming languages $LANG turns up a few that could provide nice starting points.

Perl: on meta::cpan there is Net::DNS::Nameserver, meant to provide a local nameserver for testing local client resolvers, but would probably be adaptable.

Python: [1] under 50 lines and using no imports other than "socket". It's very minimal, but shows dealing with the protocol. [2] [3] [4] are all using something called "dnslib". [2] is nearly 150 lines, but it is more complicated than we need. It's even using multithreading. Same for [3]. [4] is much similar, and much smaller (comparable to using Net::DNS::Nameserver in Perl). Another library for simple DNS in Python is pydnserver [5].

PHP: I didn't find anything simple. All I found was much more full featured and many more lines of code than we need.

Go: [6].

Bash: [7]. I'm not sure what disturbs me more. That someone made this, or that I searched for it.

Ruby: [8].

[1] http://code.activestate.com/recipes/491264-mini-fake-dns-ser...

[2] https://gist.github.com/andreif/6069838

[3] https://gist.github.com/pklaus/b5a7876d4d2cf7271873

[4] https://stackoverflow.com/questions/33531551/how-to-create-a...

[5] https://pypi.org/project/pydnserver/

[6] https://gist.github.com/walm/0d67b4fb2d5daf3edd4fad3e13b162c...

[7] https://gist.github.com/CheRuisiBesares/f35f71f028926e65191d...

[8] https://github.com/socketry/rubydns