CLI AI

Verificar o vencimento de certificado SSL com openssl

2026-06-27

A forma mais rápida de saber quando um certificado SSL vence é echo | openssl s_client -servername host -connect host:443 2>/dev/null | openssl x509 -noout -enddate, que imprime a data notAfter exata sem abrir um navegador. A partir daí dá para transformar essa data num número de dias, montar uma checagem pronta para cron, ou passar por uma lista inteira de domínios de uma vez. Este é o fluxo completo, não só o comando que todo mundo já conhece.

1. Quando o certificado de um site vence

clai
$ clai quando vence o certificado do cliai.tech→ echo | openssl s_client -servername cliai.tech -connect cliai.tech:443 2>/dev/null | openssl x509 -noout -enddate -subjectnotAfter=Nov  2 10:19:50 2026 GMTsubject=CN=cliai.tech

echo | fecha a entrada padrão, senão o s_client fica esperando entrada interativa. -servername define o SNI e é obrigatório sempre que um mesmo IP serve mais de um site — o que é quase sempre o caso.

2. Quantos dias faltam

clai
$ clai quantos dias faltam para o certificado do cliai.tech vencer→ exp=$(echo | openssl s_client -servername cliai.tech -connect cliai.tech:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2); echo $(( ($(date -d "$exp" +%s) - $(date +%s)) / 86400 )) days

date -d interpreta o formato de data do OpenSSL, e o resto é aritmética comum em segundos. Esse é o número que você compara com um limite no monitoramento.

3. Uma checagem sem fazer aritmética

clai
$ clai verifica se o certificado vence nos próximos 30 dias→ echo | openssl s_client -servername cliai.tech -connect cliai.tech:443 2>/dev/null | openssl x509 -noout -checkend 2592000 && echo "ok" || echo "expires within 30 days"

-checkend recebe segundos e devolve um código de saída, não texto. 2592000 são 30 dias. Pronto para entrar num script — nada para interpretar.

4. Uma lista inteira de domínios de uma vez

clai
$ clai verifica o vencimento de certificados para uma lista de domínios de um arquivo→ while read d; do printf '%-28s ' "$d"; echo | openssl s_client -servername "$d" -connect "$d":443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2; done < domains.txt

O mesmo truque, em loop. Mantenha o domains.txt junto do script — atualizar a lista é mais fácil do que editar o comando.

5. Um arquivo de certificado local

clai
$ clai mostra o vencimento deste arquivo de certificado→ openssl x509 -in /etc/ssl/certs/example.pem -noout -dates

Para um arquivo que já está no disco, nem precisa do s_client. -dates mostra notBefore e notAfter — o primeiro importa quando um certificado foi emitido "para o futuro" e ainda não é válido.

6. Ver a cadeia inteira

clai
$ clai mostra a cadeia de certificados deste site→ echo | openssl s_client -servername cliai.tech -connect cliai.tech:443 -showcerts 2>/dev/null | grep -E 's:|i:'

-showcerts devolve a cadeia inteira; linhas s: são o subject, linhas i: são o issuer. Uma cadeia incompleta é um motivo comum para um site carregar bem no navegador mas falhar no curl ou num app mobile.

Pegadinhas

  • Sem -servername você pode acabar checando o certificado errado. Num IP compartilhado, um servidor sem SNI devolve o certificado padrão, e você mede o vencimento de outro site.
  • date -d é só do GNU. No macOS você precisa de date -j -f '%b %d %T %Y %Z', com o formato de entrada escrito manualmente.
  • Vencimento de certificado e vencimento de domínio são coisas diferentes. Renovar o certificado automaticamente não adianta se o domínio em si expira ou o desafio ACME quebra.

Perguntas relacionadas

Como verifico um certificado numa porta não padrão? Troque a porta em -connect, por exemplo -connect mail.example.com:993, e adicione -starttls imap para protocolos que fazem upgrade da conexão.

Por que o navegador mostra um certificado válido e o curl reclama? Normalmente é uma cadeia incompleta: o navegador baixa o intermediário que falta sozinho, o curl não. Veja a saída de -showcerts.

Como automatizo o alerta? Coloque a versão com -checkend no cron e notifique quando o código de saída for diferente de zero. Um limite de 30 dias dá margem para reagir.

Veja também

Pare de escrever comandos openssl na mão — descreva o que precisa e o CliAI escreve o comando. Instale em uma linha.