Certificates with acme.sh

The new ACME v2 protocol for Let’s Encrypt certificates is live! Among other things, this now allows wildcard certificates to be obtained. This allows many individual certificates (such as subdomains) to be reduced to one, and no additional certificates are required for multiple subdomains.

Of course I would like to use such universal certificates right away, but the acme-client I haden’t implemented the new ACME 2.0 protocol and will not be able to do so in the near future.
So far I use the ACME-Client from hlandau written in the Golang, which has served me well until today. It is only one single GO-binary required for certificate management and supports a wide range of configurations. Unlike other clients, it does not need a huge bunch of modules like the certbot written in Python.

After searching for a v2 compatible, simple ACME client, I chose acme.sh as my new companion. It supports the new ACME 2.0 protocol and its * certificates. This client can also store the challenge in the DNS server via nsupdate. This is very convenient for me, as I already use DNS challenges for obtaining the certificates for my domains.
The migration is very easy, I simply issue the new certificates with the acme.sh and use it in my services.

Install acme.sh

The installation is very simple and well described in the README of acme.sh.

# As root
curl https://get.acme.sh | sh


I create a cronjob for the regular and automatic renewal of certificates:

0 6 * * * * root /root/.acme.sh/acme.sh --cron --home "/root/.acme.sh" > /dev/null


To issue a wildcard certificate it needs an api to the DNS server, so that the challenge can be deposited there and checked by Letsencrypt. This verification is the only way to obtain the special certificate for several subdomains. I use nsupdate, a utility for the dynamic DNS update.

export NSUPDATE_SERVER="mockingjay.sandchaschte.ch"
export NSUPDATE_KEY="/root/.acme.sh/update.key"

# /root/.acme.sh/update.key
key "_acme-challenge" {
algorithm hmac-sha512;
secret "notmyrealsecret";
};


Create and install certificates

Now I can use acme.sh to issue the certificates. I choose the following options: --issue: Create certificate --dns dns_nsupdate: Using the DNS challenge with nsupdate -d sandchaschte.ch -d *.sandchaschte.ch: my domain for which I want to issue the wildcard certificate --dnssleep 10: Wait 10 seconds after the DNS entry with nsupdate before checking the challenge

acme.sh --issue --dns dns_nsupdate -d sandchaschte.ch -d *.sandchaschte.ch --dnssleep 10


Result

[Don Mar 15 20:17:42 CET 2018] Creating domain key
[Don Mar 15 20:17:42 CET 2018] The domain key is here: /root/.acme.sh/sandchaschte.ch/sandchaschte.ch.ch
[Don Mar 15 20:17:42 CET 2018] Multi domain='DNS:sandchaschte.ch,DNS:*.sandchaschte.ch'
[Don Mar 15 20:17:42 CET 2018] Getting domain auth token for each domain
[Don Mar 15 20:17:44 CET 2018] Getting webroot for domain='sandchaschte.ch'
[Don Mar 15 20:17:44 CET 2018] Getting webroot for domain='*.sandchaschte.ch'
[Don Mar 15 20:17:44 CET 2018] Found domain api file: /root/.acme.sh/dnsapi/dns_nsupdate.sh
[Don Mar 15 20:17:44 CET 2018] adding _acme-challenge.sandchaschte.ch. 60 in txt "gvJXepU-oQTVS8Fcgiqy7SVEDckFxcu4IUkP3c2i1-w"
[Don Mar 15 20:17:44 CET 2018] Found domain api file: /root/.acme.sh/dnsapi/dns_nsupdate.sh
[Don Mar 15 20:17:44 CET 2018] adding _acme-challenge.sandchaschte.ch. 60 in txt "ze-pMMuwmnrW55K4pqyTjzpyfLqSDRpGm4smJSC98tg"
[Don Mar 15 20:17:44 CET 2018] Sleep 10 seconds for the txt records to take effect
[Don Mar 15 20:17:55 CET 2018] Verifying:sandchaschte.ch
[Don Mar 15 20:17:58 CET 2018] Success
[Don Mar 15 20:17:58 CET 2018] Verifying:*.sandchaschte.ch
[Don Mar 15 20:18:01 CET 2018] Success
[Don Mar 15 20:18:01 CET 2018] Removing DNS records.
[Don Mar 15 20:18:01 CET 2018] removing _acme-challenge.sandchaschte.ch. txt
[Don Mar 15 20:18:01 CET 2018] removing _acme-challenge.sandchaschte.ch. txt
[Don Mar 15 20:18:01 CET 2018] Verify finished, start to sign.
[Don Mar 15 20:18:03 CET 2018] Cert success.


I now can activate the created certificates for my web server:

acme.sh --install-cert -d sandchaschte.ch --key-file /etc/ssl/keys/sandchaschte.ch.key --fullchain-file /etc/ssl/certs/sandchaschte.ch.pem --reloadcmd "systemctl restart nginx"


Done.

We are now enjoying the wildcard certificate:

openssl s_client -servername www.sandchaschte.ch -connect www.sandchaschte.ch:443 | openssl x509 -noout -text | grep DNS:
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = sandchaschte.ch
verify return:1
DNS:*.sandchaschte.ch, DNS:sandchaschte.ch