Problemas com Letsencrypt

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.

1 curtida

basta adicionar seu endereço de e-mail no arquivo de configuração.

/var/discourse/containers/app.yml

## Se você adicionou o modelo Lets Encrypt, descomente abaixo para obter um certificado SSL gratuito
 LETSENCRYPT_ACCOUNT_EMAIL: gavin@truecode.co.za

execute ./launcher rebuild app

então você estará pronto para começar

Corrigimos isso há algumas semanas. Você tentou uma reconstrução?

3 curtidas

Não, não tentei. Estou executando a versão 2.8.0.beta4 e o sistema indica que estou atualizado. Preciso fazer uma reconstrução após as atualizações, ou há downloads automáticos entre as atualizações que exigiriam uma reconstrução? Tenho um endereço de e-mail configurado em LETSENCRYPT_ACCOUNT_EMAIL.

Posso fazer uma reconstrução. Preciso restaurar a versão original do script do letsencrypt primeiro, ou a reconstrução o atualizará automaticamente? Devo fazer uma reconstrução após cada atualização, ou existe algum método para me notificar quando isso for necessário? Até agora, nunca fiz uma reconstrução desde que o site foi criado inicialmente há cerca de seis meses, embora tenha aplicado atualizações regularmente.

Embora você possa atualizar o aplicativo pela interface web, de vez em quando precisamos enviar uma atualização para o ambiente subjacente em que o Discourse roda (a imagem do contêiner). Essas atualizações do ambiente exigem uma reconstrução.

Para desfazer suas alterações locais, você pode armazená-las com

cd /var/discourse
git stash
./launcher rebuild app
1 curtida

Essas “atualizações ambientais” são as atualizações do “docker-manager” que vejo após clicar no link “realizar atualizações aqui” na página de configurações de administrador? Acredito que estou um pouco confuso agora sobre quais atualizações devo obter, de onde e quando devo fazer uma reconstrução. Embora eu veja uma atualização nessa página, a página anterior ainda diz que estou atualizado.

Não, para obtê-las, você deve acessar o servidor via linha de comando e executar um rebuild.

OK. Fiz a reconstrução, mas não tenho certeza se funcionará em 90 dias, já que o certificado ainda não expirou e, portanto, não está tentando obter um novo. Verifiquei o script letsencrypt e ele mostra uma data de modificação nova (hoje), mas ao compará-lo com a versão antiga do script (a original, não após minhas modificações), eles são idênticos. Tentei invocar o script manualmente dentro do container usando --force, conforme indicado em um dos comentários das mensagens de saída, mas não funcionou. Portanto, neste ponto, terei que confiar que, quando o certificado expirar, ele será renovado corretamente.