certbot renew: An authentication script must be provided
Published inFor a personal project of mine I’ve been using a wildcard TLS certificate
issued by Let’s Encrypt.
certbot made the process of creating the certificate
extremely easy, I just had to apt install certbot
and then run the following
command, duly copy-pasted from the Internet:
certbot --manual certonly --agree-tos --email ema@example.org --preferred-challenges=dns -d '*.example.org'
The command gave this output:
[...] Please deploy a DNS TXT record under the name _acme-challenge.example.org with the following value: 05REcrGYWuv_fTBQ3QQYTxmNm3f_LU2cN8JNf_f458z
resource "gandi_livedns_record" "acme" { zone = "example.org" name = "_acme-challenge" type = "TXT" ttl = 300 values = [ "05REcrGYWuv_fTBQ3QQYTxmNm3f_LU2cN8JNf_f458z" ] }
This was enough to issue the certificate, and I completely forgot about it till the nice Let’s Encrypt Expiry Bot emailed saying the certificate would expire in 20 days.
Didn’t I configure auto-renewal of the cert? I thought I did but then again who
knows, weeks have gone by! It turns out I did, with this wonderful
/etc/cron.weekly/certbot-renew
script:
#!/bin/sh certbot renew
Other than not being very advanced, the script was also failing claiming that The manual plugin is not working and that An authentication script must be provided with --manual-auth-hook:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Processing /etc/letsencrypt/renewal/example.org.conf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cert is due for renewal, auto-renewing... Non-interactive renewal: random delay of 293 seconds Could not choose appropriate plugin: The manual plugin is not working; there may be problems with your existing configuration. The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.') Attempting to renew cert (example.org) from /etc/letsencrypt/renewal/example.org.conf produced an unexpected error: The manual plugin is not working; there may be problems with your existing configuration. The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.'). Skipping. All renewal attempts failed. The following certs could not be renewed: /etc/letsencrypt/live/example.org/fullchain.pem (failure)
Unfortunately certbot did not guess that — even though the certificate was created manually — I wanted renewals to happen automatically. Luckily certbot also didn’t guess my Gandi API key.
When the certificate was issued, this
/etc/letsencrypt/renewal/example.org.conf
was created for me:
# renew_before_expiry = 30 days version = 0.31.0 archive_dir = /etc/letsencrypt/archive/example.org cert = /etc/letsencrypt/live/example.org/cert.pem privkey = /etc/letsencrypt/live/example.org/privkey.pem chain = /etc/letsencrypt/live/example.org/chain.pem fullchain = /etc/letsencrypt/live/example.org/fullchain.pem # Options used in the renewal process [renewalparams] account = redacted pref_challs = dns-01, authenticator = manual manual_public_ip_logging_ok = True server = https://acme-v02.api.letsencrypt.org/directory
The important line is authenticator = manual
in the renewalparams
section.
We need to replace that with a plugin for the Gandi DNS service. Thankfully
Yohann Leon was nice enough to
write one, and
Unit193 packaged it for Debian.
What I did to get certbot to automatically renew my wildcard certificate was:
1) installing the plugin with apt install python3-certbot-dns-gandi
2) replacing authenticator = manual
with authenticator = certbot-plugin-gandi:dns
3) adding certbot_plugin_gandi:dns_credentials = /etc/letsencrypt/gandi.ini
to tell the plugin where to find my credentials
4) creating /etc/letsencrypt/gandi.ini
with dns_gandi_api_key=REDACTED
Almost. Now certbot renew
failed saying that it cannot find certbot_plugin_gandi:dns_api_key
:
Attempting to renew cert (example.org) from /etc/letsencrypt/renewal/example.org.conf produced an unexpected error: Missing property in credentials configuration file /etc/letsencrypt/gandi.ini: * Property "certbot_plugin_gandi:dns_api_key" not found (should be API key for Gandi account).. Skipping.
So apparently something was wrong with step (4). Though
the docs
use dns_gandi_api_key
as the property name, it seems it should be
certbot_plugin_gandi:dns_api_key
instead.
And that’s it, here is the final configuration.
/etc/letsencrypt/renewal/example.org.conf
# renew_before_expiry = 30 days version = 0.31.0 archive_dir = /etc/letsencrypt/archive/example.org cert = /etc/letsencrypt/live/example.org/cert.pem privkey = /etc/letsencrypt/live/example.org/privkey.pem chain = /etc/letsencrypt/live/example.org/chain.pem fullchain = /etc/letsencrypt/live/example.org/fullchain.pem # Options used in the renewal process [renewalparams] authenticator = certbot-plugin-gandi:dns certbot_plugin_gandi:dns_credentials = /etc/letsencrypt/gandi.ini account = redacted pref_challs = dns-01, server = https://acme-v02.api.letsencrypt.org/directory
/etc/letsencrypt/gandi.ini
certbot_plugin_gandi:dns_api_key=REDACTED