Francesco Bonanno d1e32749e7
All checks were successful
continuous-integration/drone/push Build is passing
Bumping inventory submodule to commit n° 6971e321e5
2023-11-04 13:26:44 +01:00
2021-10-12 10:44:28 +02:00
2023-01-13 09:30:06 +01:00

ACME DNS Server and Client

in docs.fsfe.org

For some of the FSFE's services, we cannot rely on Let's Encrypt's HTTP/TLS authentication. For example:

  • Multiple servers for the same domain
  • XMPP server which uses fsfe.org but is on a separate host than the webserver

To avoid that all servers can modify DNS entries, we use a separate DNS server that is just used for ACME DNS challenges in an isolated zone.

Structure

  • acme-dns.fsfe.org is a VM that runs the server part. It is the authorative NS for all queries in its domain, and provides an API for registration/modification of entries.
  • Either via curl or with the acme-dns-client, clients can ask the acme-dns server for an "account" and a subdomain of acme-dns.fsfe.org. This separate subdomain is then set as the CNAME of _acme-challenge.example.fsfe.org.
  • Upon certificate request, LE provides a verfication string and queries _acme-challenge.example.fsfe.org (TXT) whether the string is present to confirm whether the domain belongs to us. Either via curl or the client binary, we update the TXT record accordingly at the acme-dns server. LE follows the CNAME and can confirm it.

Usage

You can include the client role in existing playbooks, or use it standalone.

1. Deploy acme-dns-client and register domains

Run the ansible playbook to deploy the client binary. It can apply to all servers in the baseline group, so limit carefully.

ansible-playbook -l example.fsfe.org --extra-vars="domains=['example.fsfe.org']" playbook.yml

The ansible domains variable can be a list (array), or a space-separated string.

The client role then registers the given domains with the ACME DNS server, and checks whether the CNAME has been set correctly. You might have to run the role twice: first to register the domain which then will probably fail because of the missing CNAME, and second to confirm the set CNAME (which you have to do manually).

To set a CNAME with your DNS server, it may look like the following:

_acme-challenge.example.fsfe.org.     IN      CNAME   93468d30-4ba5-4478-b43a-b5106340503a.acme-dns.fsfe.org.

2. Acquire the cert from LE

Once the CNAME is set, you can run certbot to request a certificate:

certbot certonly --manual --preferred-challenges dns --manual-auth-hook acme-dns-client -d example.fsfe.org

The settings will be saved in the renewal configuration of certbot, so this effort only has to be done once.

If you use dehydrated, you can try something like this, using the custom hook:

dehydrated -c --accept-terms -t dns-01 -d example.fsfe.org -k acme-dns-dehydrated-hook
Description
Server and client part to acquire TLS certs via DNS verification
Readme 2.2 MiB
Languages
INI 100%