Parece que algumas mudanças ocorreram no serviço Let’s Encrypt a partir de 1º de agosto. Meu certificado só venceria hoje, então só fui afetado pelas mudanças hoje. Os scripts que o Discourse usa para gerenciar o serviço Let’s Encrypt foram atualizados para usar, por padrão, um novo serviço chamado ZeroSSL em vez do Let’s Encrypt. Infelizmente, o ZeroSSL aparentemente exige registro com um endereço de e-mail antes de funcionar, então, quando meu certificado existente venceu esta manhã, o site parou de funcionar.
Após bastante investigação, descobri qual era o problema e, embora tenha conseguido contorná-lo de certa forma, não acho que o que fiz para corrigir seja necessariamente a solução “correta”. Primeiro, aqui estão as mensagens de erro que apareciam no 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
Tentei registrar a conta manualmente dentro do container e, embora tenha dito que foi registrado, ao reiniciar o container, obtive o mesmo erro. Então, localizei os scripts e aquele que faz isso está dentro do container em /etc/runit/1.d/letsencrypt. Aqui está o script original:
#!/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
Como o registro por e-mail não funcionou, decidi incluir a opção para que o script acme.sh voltasse a usar o Let’s Encrypt original em vez do ZeroSSL. As instruções sobre como fazer isso estão disponíveis neste site: https://community.letsencrypt.org/t/the-acme-sh-will-change-default-ca-to-zerossl-on-august-1st-2021/144052
Primeiro, tentei inserir isso como a terceira linha do script, logo após a instrução “/usr/sbin/nginx -c /etc/nginx/letsencrypt.conf”:
/shared/letsencrypt/acme.sh --set-default-ca --server letsencrypt
O log mostrou uma mensagem de que o padrão foi alterado, mas logo em seguida obtive o mesmo erro sobre a falta de e-mail registrado para o ZeroSSL. Houve um atraso de cerca de 6 segundos no log entre essa mensagem e as mensagens de erro, o que me faz pensar que o script acme.sh deve estar mantendo informações de estado por meio de variáveis de ambiente e que as execuções subsequentes do comando estavam rodando em um contexto diferente, perdendo assim a variável. Então, o que acabei tendo que fazer foi alterar todas as invocações do acme.sh no script letsencrypt para adicionar o operando “–server letsencrypt” ao comando. Quando fiz isso e reiniciei o container, um novo certificado foi gerado pelo Let’s Encrypt em vez do ZeroSSL, e o site voltou a funcionar.
Aqui está a versão modificada do script letsencrypt que usei:
#!/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
Também deixei o comando original que havia inserido para tentar definir o serviço padrão, apenas por precaução, mas pode não ser necessário.
Portanto, o que precisa acontecer é que este script seja alterado para: definir explicitamente o serviço Let’s Encrypt a ser usado em todas as invocações do acme.sh; ou descobrir como o acme.sh salva as informações de estado para que uma única invocação do comando padrão funcione; ou, por fim, adicionar suporte ao ZeroSSL e à necessidade de coletar e salvar um endereço de e-mail.
Estou assumindo que o que fiz será sobrescrito na próxima vez que eu atualizar as versões e terei que fazer novamente, caso isso não seja resolvido.
Se perdi algo aqui ou se isso foi de alguma forma resolvido de outra maneira que não exija alteração nos scripts, por favor, me avise.