HTTP-01 Challenge
Quando você solicita um certificado, o Let's Encrypt precisa verificar que você controla o domínio ou subdomínio específico para o qual está solicitando. O HTTP-01 Challenge verifica isso fazendo uma requisição HTTP na porta 80.
Por exemplo: se você solicita certificado para api.domain.com, o Let's Encrypt valida apenas esse subdomínio, não o domínio inteiro. Para cobrir múltiplos subdomínios, você precisa solicitar certificado para cada um ou usar wildcard via DNS-01 Challenge que veremos mais adiante.
Pré-requisito de DNS: Apenas o registro A/CNAME apontando para o IP do servidor (já existente se o site funciona). Não é necessário criar nenhum registro adicional.
Pré-requisito do servidor:
- Porta 80 acessível publicamente
- Servidor web respondendo requisições HTTP
Como funciona:
- Você executa o Certbot solicitando um certificado
- Let's Encrypt gera um token único e envia para o Certbot
- Certbot cria automaticamente o arquivo em
/.well-known/acme-challenge/TOKEN - Let's Encrypt faz requisição HTTP para verificar o token
- Se validado, certificado é emitido
- Certbot remove automaticamente o arquivo de token
O Certbot é o cliente ACME oficial desenvolvido pela Electronic Frontier Foundation (EFF) em parceria com o Let's Encrypt. Ele automatiza todo o processo de obtenção e renovação de certificados.
Precisa criar conta? Não! O Certbot cria uma conta automaticamente na primeira execução. Ele apenas solicita um email (opcional) para avisos de expiração. As credenciais ficam em /etc/letsencrypt/accounts/.
Como o ACME é um protocolo aberto, existem outros clientes compatíveis: acme.sh (shell script), Caddy (servidor web), Traefik (proxy reverso), cert-manager (Kubernetes).
Certbot é ferramenta, não serviço. Você instala uma única vez e ele gerencia múltiplos certificados para diferentes domínios no mesmo servidor inclusive. Após a primeira execução, o Certbot configura automaticamente um systemd timer (ou cron job) que verifica renovações 2x ao dia. Se um certificado está próximo do vencimento, renova automaticamente.
Importante: Você não precisa criar nenhum arquivo manualmente. O Certbot cuida de todo o processo.
O Certbot é uma aplicação completamente separada da sua aplicação real. Arquitetura:
Instalação do Certbot
# Ubuntu/Debian
sudo apt update
sudo apt install certbot
# Plugin para Nginx se necessário
sudo apt install python3-certbot-nginx
# Plugin para Apache se necessário
sudo apt install python3-certbot-apache
# CentOS/RHEL/Rocky + plugin
sudo dnf install certbot python3-certbot-nginx
Os plugins não são obrigatórios, mas se quiser usar os comandos --nginx ou --apache, que veremos adiante, irá facilitar bastante pois já configuram esses servidores web automaticamente. Sem plugin, use certonly e configure manualmente.
| Modo | Plugin | O que faz |
|---|---|---|
--nginx | Requer plugin | Obtém certificado e configura Nginx |
--apache | Requer plugin | Obtém certificado e configura Apache |
certonly | Não requer | Apenas obtém certificado (configuração manual) |
Obter certificado
# Com Nginx (recomendado - configura automaticamente)
sudo certbot --nginx -d subdomain.domain.com.br
# Com Apache
sudo certbot --apache -d subdomain.domain.com.br
# Apenas certificado (sem configurar servidor)
sudo certbot certonly --webroot -w /var/www/html -d subdomain.domain.com.br
O Certbot faz automaticamente: recebe o token, cria o arquivo em /.well-known/acme-challenge/, aguarda validação, remove o arquivo e instala o certificado criar o times parar renovação no sistema.
Comandos Úteis
# Verificar o timer de renovação automática
systemctl list-timers | grep certbot
# Listar todos os certificados gerenciados
certbot certificates
# Renovar todos os certificados (executado automaticamente pelo timer)
certbot renew
Onde Ficam os Certificados
Após validação bem-sucedida, o Certbot armazena os certificados em /etc/letsencrypt/:
/etc/letsencrypt/
├── live/
│ └── domain.com/
│ ├── cert.pem # Certificado do servidor
│ ├── chain.pem # Cadeia intermediária
│ ├── fullchain.pem # cert.pem + chain.pem (use este no servidor)
│ └── privkey.pem # Chave privada (proteger!)
├── archive/ # Histórico de certificados anteriores
├── renewal/ # Configurações de renovação
└── accounts/ # Credenciais da conta ACME
Na configuração do servidor, use:
ssl_certificate: aponte parafullchain.pemssl_certificate_key: aponte paraprivkey.pem
# Verificar certificados instalados
sudo certbot certificates
# Saída esperada:
# Certificate Name: domain.com
# Domains: domain.com
# Expiry Date: 2024-04-15 (VALID: 89 days)
# Certificate Path: /etc/letsencrypt/live/domain.com/fullchain.pem
# Private Key Path: /etc/letsencrypt/live/domain.com/privkey.pem
Renovação Manual (sistemas antigos)
Em sistemas sem systemd timer, adicione um cron job:
# Editar crontab
sudo crontab -e
# Adicionar linha para renovação 2x ao dia
0 0,12 * * * certbot renew --quiet --post-hook "systemctl reload nginx"
Fluxo de renovação:
- Timer/cron executa
certbot renew - Certbot verifica certificados instalados
- Identifica certificados com menos de 30 dias de validade
- Inicia processo de renovação (repete validação HTTP-01)
- Substitui certificado antigo pelo novo
- Executa post-hook para recarregar servidor web
Riscos e Considerações de Segurança
1. Rate Limits
Como o Let's Encrypt é gratuito, existem limites para evitar abuso:
| Limite | Significado | Exemplo |
|---|---|---|
| 50 certificados/domínio/semana | Máximo de 50 certificados para subdomínios do seu domínio | api.site.com, www.site.com, etc. somados |
| 5 duplicados/semana | Mesmo certificado (exatos domínios) só pode ser emitido 5x | Evita loops acidentais em scripts |
| 10 contas/IP/3h | Criação de novas contas ACME limitada | Afeta apenas primeira instalação |
Na prática: Esses limites raramente afetam uso normal. Problemas surgem em:
- Scripts com bugs que pedem certificados em loop
- Ambientes de teste/desenvolvimento sem usar staging
Solução: Use --test-cert (staging) para testes - tem limites muito maiores:
# Ambiente de testes (não gera certificado válido, mas testa todo o processo)
certbot certonly --test-cert --nginx -d test.domain.com
# Produção (certificado real)
certbot certonly --nginx -d prod.domain.com
2. E se a Renovação Falhar?
Se o timer automático falhar em renovar, o certificado expira e seu site fica sem HTTPS. Isso pode acontecer por:
| Causa comum | O que aconteceu |
|---|---|
| Porta 80 bloqueada | Firewall mudou, Let's Encrypt não consegue validar |
| Servidor parado | Nginx/Apache não estava rodando no momento da renovação |
| Domínio mudou | DNS não aponta mais para o servidor |
| Disco cheio | Não consegue salvar novo certificado |
Como verificar se está tudo ok:
# Ver status dos certificados e quando expiram
sudo certbot certificates
# Testar se a renovação vai funcionar (sem renovar de verdade)
sudo certbot renew --dry-run
Monitoramento simples: Adicione um alerta por email se a renovação falhar:
# Adicionar no crontab (sudo crontab -e)
0 8 * * * certbot renew --dry-run --quiet || echo "ALERTA: Renovação SSL falhou!" | mail -s "Certbot Falhou" [email protected]
Isso roda todo dia às 8h e só envia email se houver problema.
3. Protegendo seu Domínio com CAA Records
Qualquer pessoa pode tentar obter um certificado para seu domínio. Se um atacante conseguir acesso temporário ao seu servidor ou DNS, ele poderia obter um certificado válido.
Para solucionar essa situação temos o CAA (Certificate Authority Authorization) que é um registro DNS que diz "apenas ESTA autoridade certificadora pode emitir certificados para meu domínio".
# Adicione estes registros DNS no seu provedor (Cloudflare, Route53, etc.)
# Apenas Let's Encrypt pode emitir certificados para este domínio
domain.com. CAA 0 issue "letsencrypt.org"
# Bloqueia emissão de wildcards (opcional)
domain.com. CAA 0 issuewild ";"
# Receber email se alguém tentar emitir certificado não autorizado
domain.com. CAA 0 iodef "mailto:[email protected]"
Verificar se CAA está configurado:
dig CAA domain.com
4. Protegendo a Chave Privada
A chave privada (privkey.pem) é o segredo mais importante. Quem tiver acesso pode se passar pelo seu site.
# Verificar permissões (deve ser 600, só root lê)
ls -la /etc/letsencrypt/live/domain.com/
# Corrigir se necessário
sudo chmod 600 /etc/letsencrypt/live/domain.com/privkey.pem
sudo chown root:root /etc/letsencrypt/live/domain.com/privkey.pem
Nunca faça:
- Copiar chaves para repositórios git
- Enviar chaves por email/chat
- Dar permissão de leitura para outros usuários