Como Validar Certificados SSL/TLS e Status HTTP em Lote com Python
Gerenciar dezenas ou centenas de domínios pode se tornar um pesadelo logístico. Um belo dia você acorda e descobre que um certificado SSL/TLS expirou silenciosamente, ou que um domínio está fora do ar gerando um erro `500 Server Error`.
Para resolver esse problema de forma automatizada e sem complicação, desenvolvemos um validador de certificados SSL/TLS e status HTTP que roda diretamente no terminal, **100% escrito em Python Puro** e com **zero dependências externas**.
Neste post, vamos explorar as funcionalidades deste script, como ele funciona nos bastidores e como você pode utilizá-lo na sua rotina de DevOps, SysAdmin ou Segurança.
---
## Principais Funcionalidades
Diferente de ferramentas simples que apenas testam a conexão, este script foi projetado para extrair o máximo de inteligência possível de cada domínio:
1. **Zero Dependências**: Funciona instantaneamente em qualquer máquina com Python 3 instalado. Sem `pip install`, sem ambientes virtuais (`venv`).
2. **Validação Completa de SSL/TLS**: Detecta se o certificado está ativo, expirado, com hostname incompatível ou se possui problemas na cadeia de confiança.
3. **Extração de Data de Expiração Nativa**: Mesmo se o certificado estiver quebrado ou expirado, o script consegue "puxar" a data exata da expiração e calcular os dias restantes.
4. **Fallback Inteligente de Status HTTP**: Se o SSL de um site estiver quebrado, o script realiza um bypass de validação TLS apenas para enviar a requisição HTTP e retornar o status do servidor (ex: `200 OK`, `403 Forbidden`, `404 Not Found`).
5. **Interface de Terminal Amigável**: Exibe um relatório colorido e formatado, com alertas visuais baseados na proximidade da expiração (Vermelho para expirados, Amarelo para expiração próxima de 30 dias e Verde para saudáveis).
6. **Saída em CSV Consolidada**: Salva todo o histórico de execuções no arquivo `validation.log` (formato CSV) para integração rápida com painéis, bancos de dados ou relatórios.
---
## Como Funciona por Trás dos Panos?
A grande mágica do script está na forma como ele lida com a conexão. Se usássemos uma biblioteca HTTP tradicional, a conexão seria abortada imediatamente ao encontrar um certificado inválido, impedindo-nos de ler o status HTTP ou os detalhes do certificado.
O script resolve isso em **três etapas**:
### 1. O Teste de Confiança (Validação SSL)
Primeiro, o script tenta estabelecer uma conexão de socket segura utilizando o contexto de SSL padrão do sistema (`ssl.create_default_context()`). Se o handshake funcionar, o certificado é 100% confiável.
### 2. O Parser ASN.1 DER (Extração da Expiração)
Para ler a data de expiração mesmo em domínios cujos certificados falharam no teste acima, o script cria uma conexão sob um contexto não verificado (`ssl._create_unverified_context()`).
Ele solicita o certificado em formato binário (`binary_form=True`) e vasculha a estrutura ASN.1 DER em busca das tags de tempo:
* **UTCTime** (Tag `0x17`, formato `YYMMDDHHMMSSZ`)
* **GeneralizedTime** (Tag `0x18`, formato `YYYYMMDDHHMMSSZ`)
Como a estrutura de um certificado X.509 define que a validade (`validity`) é a primeira sequência de datas na estrutura do certificado, as duas primeiras tags encontradas são matematicamente garantidas como `notBefore` (início da validade) e `notAfter` (data de expiração).
### 3. A Consulta de Status HTTP
Por fim, enviamos uma requisição HTTP utilizando um User-Agent moderno para evitar bloqueios por regras de Firewall/Cloudflare. Novamente, usamos o contexto SSL não verificado caso o certificado original esteja quebrado, garantindo que o servidor nos devolva o status code correto (como `200` ou `404`) em vez de simplesmente fechar a conexão.
---
## Como Utilizar
### 1. Prepare sua lista de URLs (`urls.csv`)
O script é inteligente e procura automaticamente por colunas chamadas `url`, `domain`, `site` ou lê a primeira coluna de qualquer CSV.
```csv
url
https://google.com
https://expired.badssl.com
https://wrong.host.badssl.com
https://httpbin.org/status/404
```
### 2. Execute o Script
Basta chamar o script passando o CSV como argumento:
```bash
python3 validate_certs.py urls.csv
```
### Exemplo de Saída no Terminal
```text
=== SSL/TLS Certificate & Expiration Validator ===
Reading URLs from: urls.csv
Logging all results to: validation.log
Found 4 URLs. Starting validation...
Domain / URL | SSL Certificate | Expiration Date | Days Left | HTTP Status
-------------------------------------------------------------------------------------------------------------------
google.com | Valid | 2026-08-10 14:22:15 | 80 | 200
expired.badssl.com | Verification Failed:... | 2015-04-12 23:59:59 | -4058 | 200
wrong.host.badssl.com | Verification Failed:... | 2027-03-02 19:15:00 | 284 | 200
httpbin.org | Valid | 2026-09-12 00:00:00 | 113 | 404
-------------------------------------------------------------------------------------------------------------------
=== Summary ===
Total checked: 4
Valid certs: 2
Invalid certs: 2
Log generated: validation.log (4 records written)
```
---
## O Relatório Consolidado (`validation.log`)
Ao término do processamento, a ferramenta gera um arquivo CSV completo com o mapeamento de todos os domínios:
| domain | cert validation | expiration date | days left | http status |
| :--- | :--- | :--- | :--- | :--- |
| `google.com` | `Valid` | `2026-08-10 14:22:15` | `80` | `200` |
| `expired.badssl.com` | `Verification Failed: CERTIFICATE_VERIFY_FAILED` | `2015-04-12 23:59:59` | `-4058` | `200` |
| `wrong.host.badssl.com` | `Verification Failed: CERTIFICATE_VERIFY_FAILED` | `2027-03-02 19:15:00` | `284` | `200` |
| `httpbin.org` | `Valid` | `2026-09-12 00:00:00` | `113` | `404` |
---
## Conclusão
Automatizar a verificação de certificados e a integridade de rotas é fundamental para manter qualquer infraestrutura web saudável. Ao utilizar Python nativo com sockets e manipulação direta de SSL, conseguimos criar uma ferramenta ultraveloz, portável e que não carrega o "peso" de bibliotecas pesadas de terceiros.
Sinta-se à vontade para clonar o script, configurar um agendamento (via `cron` no Linux ou Launchd no Mac) e integrar os resultados no seu Slack, Discord ou ferramentas de monitoramento!
*O código completo do script e exemplos de testes podem ser encontrados no repositório do projeto.*
André Jaccon