What does HackerNews think of acme-dns?

Limited DNS server with RESTful HTTP API to handle ACME DNS challenges easily and securely.

Language: Go

Getting a wildcard certificate from LE might be a better option, depending on how easy the extra bit of if plumbing is with your lab setup.

You need to use DNS based domain identification, and once you have a cert distribute it to all your services. The former can be automated using various common tools (look at https://github.com/joohoi/acme-dns, self-hosted unless you are only securing toys you don't really care about, if you self host DNS or your registrar doesn't have useful API access) or you can leave that as an every ~ten weeks manual job, the latter involves scripts to update you various services when a new certificate is available (either pushing from where you receive the certificate or picking up from elsewhere). I have a little VM that holds the couple of wildcard certificates (renewing them via DNS01 and acmedns on a separate machine so this one is impossible to see from the outside world), it pushes the new key and certificate out to other hosts (simple SSH to copy over then restart nginx/Apache/other).

Of course you may decide that the shin if your own CA is easier than setting all this up, as you can sign long lived certificates for yourself. I prefer this because I don't need to switch to something else if I decide to give friends/others access to something.

Your top level (sub)domain for the wildcard is still in the transparency logs of course, but nothing under it is.

This leverages the ACME DNS server which has a REST API:

* https://github.com/joohoi/acme-dns

If your DNS provider has an API, you can hook into that for internal-only web servers; this handy code supports several dozen APIs so you don't have to re-invent the wheel:

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

* https://pypi.org/project/dns-lexicon/

* https://dns-lexicon.readthedocs.io/en/latest/user_guide.html

One of my inspirations for getlocalcert is a tool to make DNS-01 easier.

acme-dns let's you add a CNAME to another DNS zone, which let's you issue certificates for the former domain name using a convenient API for the latter zone. Seriously read about it, it's awesome.

https://github.com/joohoi/acme-dns/

That tool is open source and self-hostable. getlocalcert also provides this feature, but as a hosted service. Choose the method you prefer.

https://docs.getlocalcert.net/tips/validation-domain/

Once DNS-01 is easy, wildcard certs are easy. Here's the docs for setting up a wildcard cert via getlocalcert: https://docs.getlocalcert.net/acme-clients/lego/

acme-dns[1] is probably what you might want if you are up for running your own bit of infra. Implements a simple rest api for changing the txt records for acme verifications and nothing more. It works nicely as a delegated nameserver.

[1] https://github.com/joohoi/acme-dns

If anyone wants a generic utility for interfacing with various DNS APIs, see lexicon:

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

For CLI and Python.

Such a utility is handy if you want to use the dns-01 method for ACME/Let's Encrypt via DNS aliasing:

* https://dan.langille.org/2019/02/01/acme-domain-alias-mode/

* https://github.com/acmesh-official/acme.sh/wiki/DNS-alias-mo...

* https://news.ycombinator.com/item?id=28256326 (2020)

Deep dive on how ACME DNS validation works:

* https://www.eff.org/deeplinks/2018/02/technical-deep-dive-se...

Some folks have also written 'minimalist' DNS servers for DNS validation (delegate to a sub-domain that you control if your provider does not have an API):

* https://github.com/joohoi/acme-dns

DNS alias mode:

* https://dan.langille.org/2019/02/01/acme-domain-alias-mode/

* https://github.com/acmesh-official/acme.sh/wiki/DNS-alias-mo...

* https://www.eff.org/deeplinks/2018/02/technical-deep-dive-se...

You want the name "internal.example.com". In your external DNS you create a CNAME from "_acme-challenge.internal.example.com" and point it to (e.g.) "internal.example.net" or "internal.dns-auth.example.com"

When you request the certificate you specify the "dns-01" method. The issuer (e.g., LE) will go to the the external DNS server for the look up, see that it is a CNAME and then follow the CNAME/alias, and do the verification at the final hostname.

So your ACME client has to do a DNS (TXT) record update, which can often be done via various APIs, e.g.:

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

You can even run your own DNS server locally (in a DMZ?) if your DNS provider does not have an convenient API. There are servers written for this use case:

* https://github.com/joohoi/acme-dns

* https://github.com/joohoi/acme-dns-certbot-joohoi

* https://github.com/pawitp/acme-dns-server

You can use https://github.com/joohoi/acme-dns to issue letsencrypt certificates to your internal hosts using DNS validation.

All it takes is to setup an ACME-DNS server somewhere (or just use author's public ACME-DNS server if you don't care much), and create one CNAME record in your DNS.

You can use sub-domains as well: _acme-challenge.example.com -> _acme-challenge.DNSAUTH.example.com, _acme-challenge.foo.example.com -> _acme-challenge.foo.dnsauth.example.com.

You can then have a small VM handle answering DNS queries just for dnsauth.example.com. Folks have written servers to do just this:

* https://github.com/joohoi/acme-dns

A deep dive on how ACME DNS validation works:

* https://www.eff.org/deeplinks/2018/02/technical-deep-dive-se...

You can have a CNAME _acme-challenge.example.COM point to _acme-challenge.example.ORG or a sub-domain like _acme-challenge.DNSAUTH.example.com.

At work we use the sub-domain method and just have a small non-HA VM with some scripts that allow ACME clients to update particular TXT records. Each ACME client is given an individual key and allowed to only update a particular record.

Folks have specifically written DNS servers to do just this:

* https://github.com/joohoi/acme-dns

However we used BIND with some custom scripting.

I run this one: https://github.com/joohoi/acme-dns It's super simple and has a REST API for updating records.
I'm doing the same for my personal/home lab stuff. I've been using https://github.com/joohoi/acme-dns for the dns server running on a small vps for all my internal certificates and I haven't had any issues with it.
> If you want to use the www auth you need to allow outbound connections to any IP

Only for the time period when you're requesting the cert though: it does not have to be open to the entire Internet 24/7. While this may not satisfy your personal / particular level of security concern, but it is something worth keeping in mind. Using the dehydrated client as an example, the web server could be started and stopped (or the host's firewall rules altered) in the startup_hook() / exit_hook() functions, or the deploy_challenge() / clean_challenge() functions:

* https://github.com/dehydrated-io/dehydrated/blob/master/docs...

> otherwise you have the DNS option which means giving the server access to modify the DNS records which is also unsafe should the box get compromised.

Are you aware of LE/ACME's "DNS alias" mode?

* https://github.com/acmesh-official/acme.sh/wiki/DNS-alias-mo...

* https://www.eff.org/deeplinks/2018/02/technical-deep-dive-se...

Let us say you want to get a cert for foo.example.com. Letting an ACME client change the value of that could be a risk, as you state. So what you can do is (manually) create a CNAME _acme-challenge.foo.example.com, and point that elsewhere, like _acme-challenge.foo.dnsauth.example.com. You then allow the ACME client to alter (just) the TXT records of _acme-challenge.foo.dnsauth.

People have even written simple DNS server that allow for updating of records via a RESTful API, so you can server just the (e.g.) dnsauth sub-domain from it, leaving your main domain untouched (besides the initial CNAME addition):

* https://github.com/joohoi/acme-dns

There's also a CLI utility that can handle access the APIs of several dozen DNS companies so you don't have to roll your own if you want to server the sub-domain from your current provider:

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

And you don't have to use a sub-domain, but something else entirely too: instead of dnsauth.example.com you can point the CNAME to example-dnsauth.com or example.org. So if your primary DNS provider doesn't have an API, you can use another one that does. The destination CNAME does not matter as long as you control and can update it.

If your domain provider's API sucks, or doesn't exist, or requires generating a password/key with more permissions than you're willing to give a script, look at acme-dns [1] and delegated DNS challenges:

https://github.com/joohoi/acme-dns