A quanto pare, a partire dal 1° agosto si sono verificati alcuni cambiamenti nel servizio Let’s Encrypt. Il mio certificato non sarebbe scaduto fino a oggi, quindi sono stato interessato dai cambiamenti solo oggi. Gli script che Discourse utilizza per gestire il servizio Let’s Encrypt sono stati aggiornati per utilizzare di default un nuovo servizio chiamato ZeroSSL invece di Let’s Encrypt. Purtroppo, a quanto pare, ZeroSSL richiede una registrazione con un indirizzo email prima di funzionare, quindi questa mattina, quando il mio certificato esistente è scaduto, il sito non ha funzionato.
Dopo un’ampia indagine ho capito qual era il problema e, sebbene in qualche modo l’abbia aggirato, non credo che quanto ho fatto per risolverlo sia necessariamente la “giusta” soluzione. Innanzitutto, ecco i messaggi di errore che ho ricevuto nel log:
[Wed 01 Sep 2021 05:33:58 PM UTC] Reload error for :
[Wed 01 Sep 2021 05:34:03 PM UTC] Using CA: https://acme.zerossl.com/v2/DV90
[Wed 01 Sep 2021 05:34:04 PM UTC] No EAB credentials found for ZeroSSL, let's get one
[Wed 01 Sep 2021 05:34:04 PM UTC] acme.sh is using ZeroSSL as default CA now.
[Wed 01 Sep 2021 05:34:04 PM UTC] Please update your account with an email address first.
[Wed 01 Sep 2021 05:34:04 PM UTC] acme.sh --register-account -m my@example.com
[Wed 01 Sep 2021 05:34:04 PM UTC] See: https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA
[Wed 01 Sep 2021 05:34:04 PM UTC] Please check log file for more details: /shared/letsencrypt/acme.sh.log
Ho provato a registrare manualmente l’account all’interno del container e, sebbene abbia confermato la registrazione, al riavvio del container ho ricevuto lo stesso errore. Quindi ho rintracciato gli script e quello che esegue questa operazione si trova all’interno del container in /etc/runit/1.d/letsencrypt. Ecco lo script originale:
#!/bin/bash
/usr/sbin/nginx -c /etc/nginx/letsencrypt.conf
issue_cert() {
LE_WORKING_DIR="${LETSENCRYPT_DIR}" /shared/letsencrypt/acme.sh --issue $2 -d mudtoemanor.baronshire.org --keylength $1 -w /var/www/discourse/public
}
cert_exists() {
[[ "$(cd /shared/letsencrypt/mudtoemanor.baronshire.org$1 && openssl verify -CAfile ca.cer fullchain.cer | grep "OK")" ]]
}
########################################################
# RSA cert
########################################################
issue_cert "4096"
if ! cert_exists ""; then
# Try to issue the cert again if something goes wrong
issue_cert "4096" "--force"
fi
LE_WORKING_DIR="${LETSENCRYPT_DIR}" /shared/letsencrypt/acme.sh \
--installcert \
-d mudtoemanor.baronshire.org \
--fullchainpath /shared/ssl/mudtoemanor.baronshire.org.cer \
--keypath /shared/ssl/mudtoemanor.baronshire.org.key \
--reloadcmd "sv reload nginx"
########################################################
# ECDSA cert
########################################################
issue_cert "ec-256"
if ! cert_exists "_ecc"; then
# Try to issue the cert again if something goes wrong
issue_cert "ec-256" "--force"
fi
LE_WORKING_DIR="${LETSENCRYPT_DIR}" /shared/letsencrypt/acme.sh \
--installcert --ecc \
-d mudtoemanor.baronshire.org \
--fullchainpath /shared/ssl/mudtoemanor.baronshire.org_ecc.cer \
--keypath /shared/ssl/mudtoemanor.baronshire.org_ecc.key \
--reloadcmd "sv reload nginx"
if cert_exists "" || cert_exists "_ecc"; then
grep -q 'force_https' "/var/www/discourse/config/discourse.conf" || echo "force_https = 'true'" >> "/var/www/discourse/config/discourse.conf"
fi
/usr/sbin/nginx -c /etc/nginx/letsencrypt.conf -s stop
Poiché la registrazione tramite email non ha funzionato, ho deciso di inserire l’opzione per far sì che lo script acme.sh tornasse a utilizzare il originale Let’s Encrypt invece di ZeroSSL. Le istruzioni su come farlo sono state fornite su questo sito web: https://community.letsencrypt.org/t/the-acme-sh-will-change-default-ca-to-zerossl-on-august-1st-2021/144052
Inizialmente ho provato a inserire questa riga come terza riga dello script, subito dopo l’istruzione “/usr/sbin/nginx -c /etc/nginx/letsencrypt.conf”:
/shared/letsencrypt/acme.sh --set-default-ca --server letsencrypt
Il log ha mostrato un messaggio che indicava il cambio del server predefinito, ma subito dopo ho ricevuto lo stesso errore riguardante la mancanza di un’email registrata per ZeroSSL. C’era un ritardo di circa 6 secondi nel log tra quel messaggio e i messaggi di errore, il che mi fa pensare che lo script acme.sh debba mantenere le informazioni di stato tramite variabili d’ambiente e che le successive esecuzioni del comando siano avvenute in un contesto diverso, perdendo così la variabile. Quindi, ciò che ho dovuto fare è stato modificare tutte le invocazioni di acme.sh nello script letsencrypt per aggiungere l’operando “–server letsencrypt” al comando. Quando l’ho fatto e ho riavviato il container, è stato generato un nuovo certificato da Let’s Encrypt invece di ZeroSSL e il sito è tornato online.
Ecco la versione modificata dello script letsencrypt che ho utilizzato:
#!/bin/bash
/usr/sbin/nginx -c /etc/nginx/letsencrypt.conf
/shared/letsencrypt/acme.sh --set-default-ca --server letsencrypt
issue_cert() {
LE_WORKING_DIR="${LETSENCRYPT_DIR}" /shared/letsencrypt/acme.sh --server letsencrypt --issue $2 -d mudtoemanor.baronshire.org --keylength $1 -w /var/www/discourse/public
}
cert_exists() {
[[ "$(cd /shared/letsencrypt/mudtoemanor.baronshire.org$1 && openssl verify -CAfile ca.cer fullchain.cer | grep "OK")" ]]
}
########################################################
# RSA cert
########################################################
issue_cert "4096"
if ! cert_exists ""; then
# Try to issue the cert again if something goes wrong
issue_cert "4096" "--force"
fi
LE_WORKING_DIR="${LETSENCRYPT_DIR}" /shared/letsencrypt/acme.sh \
--installcert \
-d mudtoemanor.baronshire.org \
--fullchainpath /shared/ssl/mudtoemanor.baronshire.org.cer \
--keypath /shared/ssl/mudtoemanor.baronshire.org.key \
--server letsencrypt \
--reloadcmd "sv reload nginx"
########################################################
# ECDSA cert
########################################################
issue_cert "ec-256"
if ! cert_exists "_ecc"; then
# Try to issue the cert again if something goes wrong
issue_cert "ec-256" "--force"
fi
LE_WORKING_DIR="${LETSENCRYPT_DIR}" /shared/letsencrypt/acme.sh \
--installcert --ecc \
-d mudtoemanor.baronshire.org \
--fullchainpath /shared/ssl/mudtoemanor.baronshire.org_ecc.cer \
--keypath /shared/ssl/mudtoemanor.baronshire.org_ecc.key \
--server letsencrypt \
--reloadcmd "sv reload nginx"
if cert_exists "" || cert_exists "_ecc"; then
grep -q 'force_https' "/var/www/discourse/config/discourse.conf" || echo "force_https = 'true'" >> "/var/www/discourse/config/discourse.conf"
fi
/usr/sbin/nginx -c /etc/nginx/letsencrypt.conf -s stop
Ho anche lasciato il comando originale che avevo inserito per provare a impostare il servizio predefinito, nel caso fosse necessario, anche se potrebbe non esserlo.
Quindi, ciò che deve accadere è che questo script venga modificato per definire esplicitamente il servizio Let’s Encrypt da utilizzare in tutte le invocazioni di acme.sh, oppure per capire come acme.sh salva le informazioni di stato in modo che una singola invocazione del comando predefinito funzioni, oppure infine per aggiungere il supporto per ZeroSSL e la necessità di raccogliere e salvare un indirizzo email.
Presumo che quanto ho fatto verrà sovrascritto la prossima volta che aggiornerò le versioni e dovrò rifarlo, se ciò non verrà risolto.
Se ho perso qualcosa o se questo è stato affrontato in qualche altro modo che non richiede modifiche agli script, fammi sapere.