Table of Contents
Wrapper for acme.sh to create Let’s Encrypt certificates using DNS authentication. It was written to create/ renew all needed certificates at a central system to deploy it from there (Ansible, Puppet, …).
License: GNU GPL 3.0 http://www.gnu.org/licenses/gpl-3.0.html
- acme.sh client
- dig (opional)
The acme script allows basic actions for certificates.
Central certificate server
We use Ansible on several local instances - on the machines of sysadmins and an AWX instance for scheduling tasks. To deploy certicates as files each system must have the certificate file up to date. Here we use a server that keeps the certificates on a single place (the “master” for certificates). All machines trigger creation or update on that server and sync its files before deploying a certificate to a target.
The focus is on handling certificates for domains with dns authentication or dns alias mode.
Abstracted logic: parameter ensure
On the certificate server are acme.sh and this wrapper. The wrapper has a parameter “ensure [FQDN [FQDN N]]” that handles the logic if a certificate must be
- created (if it does not exist) or
- renewed (it already exists) or
- re-created (the list of dns names in the certificate was changed)
It detects if a domain in the certificate can use a txt record or needs dns auth mode.
Pre check with dig
Accessing the API of Certificate provider can have limitations. Let’s encrypt will block you after reaching the limit.
To prevent making useless ssl requests for invalid hostnames that do not exist in dns they will be checked before starting the acme client.
Handle parallel requests
If you have multiple requests from different machines or parallel Ansible calls to deploy on multiple machines. That we do not run into conflict that 2 running requests handle the same certificate there is a queuing mechanism. This allows just a 1 task to perform certificate actions. Other started scripts will wait until the earlier started script is finished.
Copy cert files
After issue or renew a certificate with acme all files you need on the target system will be copied from acme to a certificate directory. That one contains the fqdn as directory and in it are
- the key
- the server certificate
- the intermediate certificate
- a chained certificate (server + intermediate certificate)
- the ca certificate
For Haproxy a 2nd chained certificate will be generated.
./certs/ +-- www.example.com/ +-- www.example.com.ca.cer +-- www.example.com.cert.cer +-- www.example.com.fullchain.cer +-- www.example.com.haproxy.pem +-- www.example.com.key.pem
Log creation/ renew/ delete
The script writes a log that contains timestamp and domain of a certificate. On 100+ domains it is handy to verify when what was done what for a given domain.
List old certificates
Automation is wonderful. You create systems and certificates for them on the fly. And you destroy test machines. A parameter “list-old” shows certiciates that were not renewed anymore and are older 90 days.
This is an overview of the components for issuing a certificate that take part: