A primeira vez que recebi um lembrete da Redsift de que meus certificados iriam expirar em uma semana. Normalmente, o Discourse renova os certificados com bastante antecedência. Desta vez não, antes de começar a reconstruir (o que supostamente resolve o problema), @Falco, há algo que você gostaria que eu verificasse e postasse aqui para ajudar a chegar à raiz do motivo pelo qual os certificados não foram renovados?
A raiz do certificado é ISRGX1 e aqui estão as informações do certificado que está expirando:
Mas já se passou mais de um dia desde que atualizei o software do fórum e o certificado ainda não parece ter sido atualizado. Faltam 5 dias para expirar, então ele realmente precisa ser renovado em breve.
Estou no branch estável do Discourse, se isso fizer alguma diferença. É possível que a correção do endpoint não tenha sido retroportada?
Seria ótimo se alguém pudesse verificar se o web.ssl.template está se comportando corretamente no discourse-docker, pareceu-me que a porta 80 não estava servindo nenhum URL de /.well-known/ usado pelo Let’s Encrypt, todos os URLs estavam redirecionando para SSL, incluindo arquivos de teste que coloquei manualmente em /var/www/discourse/public/.well-known/. Tive que editar /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf diretamente dentro do contêiner do aplicativo.
O mesmo aqui. Não recebi um aviso sobre a expiração do certificado. Entrar no servidor e iniciar uma reconstrução /var/discourse % ./launcher rebuild resolveu o problema.
Em meus testes em uma instalação vanilla do nginx (1.18.0, mas acho que é o mesmo para 1.26.3), uma linha de configuração do nginx return 301 https://thehostname$request_uri; fora de um location substitui completamente qualquer bloco location anterior, em vez de ser um catch-all. Acredito que /.well-known/ simplesmente não é servido na porta 80, a menos que o redirecionamento 301 seja especificamente para outro location, como / no final do bloco server. Poderia ser o mesmo problema que este post do stackoverflow?
Fico feliz que o rebuild funcione, mas como o certificado já havia sido renovado para mim, não pude confirmar se um rebuild permitiria que os servidores de validação do Let’s Encrypt chegassem lá se um certificado tivesse expirado. Talvez um rebuild inicie a renovação do certificado antes que essa linha de template esteja em vigor ou algo semelhante, em vez de corrigir os templates, mas não consigo confirmar se é por isso que o rebuild faz a renovação funcionar.
Posso confirmar que a renovação do Letsencrypt falha. Tenho executado uma instalação Discourse auto-hospedada por anos, e muito estranhamente a renovação falhou para mim duas vezes seguidas nos últimos meses. A segunda vez foi hoje de manhã, e então comecei a investigar.
Eu rastreei até os seguintes dois commits:
E a linha relevante vinculada:
Existem dois problemas, eu acho.
Primeiro, return 301 https://${DISCOURSE_HOSTNAME}$request_uri; se transforma em return 301 https://<MEU NOME DO SERVIDOR> sem um $request_uri no final. Eu verifiquei na minha instalação auto-hospedada, e também na instalação auto-hospedada de um amigo que foi configurada na última semana. Eu não entendo como o template do Discourse funciona, então não sei por que ele é descartado.
Segundo, como @lessLost mencionou, o redirecionamento 301 está fora do bloco location. Eu acredito que um redirecionamento no nível do servidor anula todos os blocos location. O LetsEncrypt usa http para renovações. No entanto, qualquer tentativa de curl -I http://SEU_DOMINIO/.well-known/acme-challenge/test retornará um 301 para https, em vez de um 404 (que é o comportamento esperado; queremos um 404, não um 301).
Eu corrigi isso manualmente na minha instalação auto-hospedada, mas espero que qualquer atualização substitua minhas alterações. Infelizmente, eu não entendo os templates o suficiente para enviar um pull request@pfaffman — ou eu faria isso também.
Editado para adicionar:
Eu acredito que isso está incorreto —
Tenho certeza de que o LetsEncrypt usa http por padrão (por razões óbvias, se o certificado estiver expirado, ele não pode ser renovado!) Mas colocar o 301 no nível do bloco server força todas as requisições a redirecionar para https, o que é inconsistente com esta estratégia de renovação.
Esta manhã, cerca de 10 minutos depois de eu acordar, visitei meu fórum e percebi que o certificado havia expirado novamente. (Reconstruir foi o que renovou da última vez que expirou para mim — há cerca de 3 meses?)
Acho que eles fizeram alterações desde então que corrigiram esse problema, mas como leva 3 meses para descobrir, o júri ainda não decidiu. Você pode definir um lembrete algumas semanas antes de o certificado atual expirar.
A nova instalação do site do meu amigo foi de uma semana atrás. A linha 37 do modelo acima diz: return 301 https://${DISCOURSE_HOSTNAME}$request_uri; mas no contêiner do Discourse Docker, tanto o dela (quanto o meu) /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf diz return 301 https://<seu_site_discourse>; Note como $request_uri é removido. Algo está fazendo com que isso desapareça! (Eu não sei o quê).
Eu fiz uma renovação forçada simulada esta manhã como parte da minha investigação. Falhou. Eu então mudei /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf. Teve sucesso!
Na verdade, tudo bem; eu apenas editarei manualmente 20-redirect-http-to-https.conf toda vez que eu atualizar o Discourse. Para aqueles que encontrarem este comentário, o comando a ser executado é:
Eu não tenho total certeza do que está causando essa falha, mas sei que modificar o conf acima resolve. Mas eu também modifiquei as notificações para que as renovações do letsencrypt não falhem silenciosamente — para que eu possa ter algum aviso prévio. Só pensei que você gostaria de saber!