Certificado TLS e segredo que vencem: alerta com semanas de folga e um dono
Faça o inventário do que tem data de validade, cheque os certificados do lado de fora com openssl, teste a renovação automática e mande o aviso para um canal que alguém lê.
Domingo, 9h, o cliente manda print: o navegador diz que a conexão com a loja não é segura. O certificado venceu à meia-noite. A renovação automática existia, mas parou em agosto, quando o site mudou de servidor e o firewall novo fechou a porta 80. Ninguém olhou a data porque "renova sozinho". O certificado avisou do jeito dele.
A resposta curta: liste tudo que tem data de validade, com um dono para cada item, e cheque as datas de fora para dentro, como o cliente vê, com alerta pelo menos três semanas antes. Para certificados automáticos, teste a renovação de verdade depois de qualquer mudança de servidor, DNS ou firewall. E mande o aviso para um canal que alguém lê, não para o e-mail de quem já saiu da empresa.
Por que a renovação automática para sem ninguém perceber
Certificados do Let's Encrypt valem 90 dias, e a indústria já aprovou reduzir gradualmente a validade máxima dos certificados públicos nos próximos anos. Isso torna a automação obrigatória, mas automação também quebra. As causas mais comuns:
- Validação bloqueada. O desafio HTTP-01 precisa que a porta 80 responda no domínio. Firewall novo, redirecionamento mal feito ou CDN na frente quebram a validação.
- Agendador sumiu. O servidor novo não tem o timer ou o cron do Certbot, ou ele está desativado.
- Renovou e ninguém recarregou. O arquivo novo está no disco, mas o Nginx continua servindo o antigo da memória até ser recarregado.
- DNS mudou. O domínio passou a apontar para outro lugar e a validação vai para a máquina errada.
- O aviso não chega. O Let's Encrypt encerrou os e-mails de aviso de expiração em 2025. Quem dependia deles ficou sem nenhum alarme.
E certificado TLS é só um item. Certificado digital A1 da empresa, usado para emitir nota fiscal, vence em um ano. Token de API do gateway de pagamento, segredo de aplicativo OAuth, certificado de push, chave de integração com marketplace, o próprio domínio: tudo tem data, e cada um derruba uma parte diferente do negócio.
Como montar o controle de validades, passo a passo
- Faça o inventário. Uma planilha ou arquivo no repositório com item, onde é usado, data de vencimento, dono e onde renovar.
- Dê um dono a cada linha. Uma pessoa com nome, e um substituto. "Equipe de TI" não renova nada.
- Cheque de fora para dentro. Para certificados TLS, consulte o que o servidor realmente entrega, não o arquivo no disco.
- Alerte com folga. 21 dias é um bom ponto de partida para TLS automático: dá tempo de a renovação falhar algumas vezes e de alguém consertar. Para itens manuais, como o certificado A1, 45 dias.
- Teste a renovação. Depois de cada mudança de servidor, firewall, proxy ou DNS, rode o teste da renovação e confira o agendador.
- Mande o alerta para um canal vivo. O mesmo sistema que avisa de disco cheio, como chamado, não como e-mail pessoal.
O inventário
Um arquivo validades.csv simples já resolve. Exemplo da loja:
item;dono;vence_em;onde_renovar
Certificado A1 da empresa (NF-e);Paula;2027-03-14;Certificadora, pedido no portal
Token API gateway de pagamento;Rafael;2026-11-30;Painel do gateway, menu Credenciais
Segredo OAuth login social;Rafael;2027-01-20;Console do provedor de login
Domínio exemplo.com.br;Paula;2027-06-02;Registro.br
Checar os certificados como o cliente vê
Este script conecta em cada domínio, lê o certificado servido e falha se faltar menos de 21 dias. O -servername é essencial quando vários sites dividem o mesmo IP, porque sem ele o servidor pode devolver o certificado de outro site.
#!/usr/bin/env bash
set -uo pipefail
DIAS_AVISO=21
LIMITE=$((DIAS_AVISO * 86400))
falhou=0
for host in loja.exemplo.com.br api.exemplo.com.br painel.exemplo.com.br; do
cert=$(echo | timeout 10 openssl s_client -connect "$host:443" -servername "$host" 2>/dev/null | openssl x509 2>/dev/null)
if [ -z "$cert" ]; then
echo "ERRO $host: não foi possível ler o certificado"
falhou=1
continue
fi
fim=$(echo "$cert" | openssl x509 -noout -enddate | cut -d= -f2)
if echo "$cert" | openssl x509 -noout -checkend "$LIMITE" > /dev/null; then
echo "ok $host vence em $fim"
else
echo "AVISO $host vence em $fim (menos de $DIAS_AVISO dias)"
falhou=1
fi
done
exit $falhou
O -checkend recebe segundos e devolve código de saída diferente de zero se o certificado vence dentro desse prazo. Rode o script uma vez por dia pelo agendador, de uma máquina diferente do servidor do site, e transforme a saída diferente de zero em alerta. Uma execução da loja mostrou:
ok loja.exemplo.com.br vence em Dec 29 03:12:40 2026 GMT
AVISO api.exemplo.com.br vence em Nov 2 18:40:11 2026 GMT (menos de 21 dias)
ok painel.exemplo.com.br vence em Jan 8 10:05:52 2027 GMT
A API estava num servidor que ninguém lembrava de ter migrado. Faltavam 16 dias, e o aviso chegou com tempo.
Checar o inventário manual
#!/usr/bin/env bash
set -euo pipefail
hoje=$(date +%s)
while IFS=';' read -r item dono vence onde; do
[ "$item" = "item" ] && continue
dias=$(( ( $(date -d "$vence" +%s) - hoje ) / 86400 ))
if [ "$dias" -le 45 ]; then
echo "$item vence em $dias dias. Dono: $dono. Renovar em: $onde"
fi
done < validades.csv
O date -d é do GNU coreutils, padrão nas distribuições Linux. No macOS a sintaxe é outra.
Testar a renovação do Certbot
sudo certbot certificates
sudo certbot renew --dry-run
systemctl list-timers | grep -i certbot
O primeiro lista os certificados e as datas que o Certbot conhece. O segundo simula a renovação contra o ambiente de teste do Let's Encrypt, sem gastar limite de emissão, e mostra o erro real se a porta 80 estiver fechada ou o DNS apontar para outro lugar. O terceiro confirma que existe um agendador; em algumas instalações ele é um cron em vez de timer do systemd. Para o Nginx passar a servir o certificado novo, configure a renovação com --deploy-hook "systemctl reload nginx".
Segredos de integração pedem rotação, não só renovação
Token que vence é chance de trocar do jeito certo: gere o novo, coloque em produção, confirme que funciona e só então revogue o antigo. Fazer na ordem inversa derruba a integração no meio da troca. O passo a passo está em Rotação de segredo tem dois passos. Para ambientes internos com certificado próprio, veja Certificado autoassinado: serve no laboratório.
Erros comuns
- Confiar que "renova sozinho". A automação para numa migração de servidor, e ninguém percebe até o navegador avisar o cliente.
- Checar o arquivo no disco, não o servidor. O certificado novo pode estar lá enquanto o Nginx serve o antigo, que vence.
- Omitir o
-servername. Com vários sites no mesmo IP, você confere o certificado errado e dorme tranquilo. - Aviso no e-mail de uma pessoa. Férias, demissão ou filtro de spam e o aviso não chega a ninguém.
- Esquecer o que não é TLS. O certificado A1 vence e a emissão de nota para; o token do gateway vence e o checkout para.
- Revogar o segredo antigo antes de pôr o novo. A integração cai no intervalo da troca.
Checklist
- Inventário com todo item que vence, com data, dono, substituto e onde renovar.
- Checagem diária dos certificados vista de fora, com
-servername. - Alerta com 21 dias para TLS automático e 45 para itens manuais.
- Alerta enviado para canal de equipe ou fila de chamados.
certbot renew --dry-runrodado depois de cada mudança de servidor, firewall ou DNS.- Agendador de renovação confirmado e recarga do servidor web configurada.
- Segredos de integração trocados com o novo ativo antes de revogar o antigo.
Qual certificado ou segredo do seu sistema vence nos próximos 40 dias, e qual é o nome da pessoa que vai receber o aviso? Se você precisou abrir o painel de três serviços para descobrir, o inventário é o primeiro passo.
Referência: https://letsencrypt.org/docs/