Pular para o conteúdo principal

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:

  1. Você executa o Certbot solicitando um certificado
  2. Let's Encrypt gera um token único e envia para o Certbot
  3. Certbot cria automaticamente o arquivo em /.well-known/acme-challenge/TOKEN
  4. Let's Encrypt faz requisição HTTP para verificar o token
  5. Se validado, certificado é emitido
  6. 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.

ModoPluginO que faz
--nginxRequer pluginObtém certificado e configura Nginx
--apacheRequer pluginObtém certificado e configura Apache
certonlyNão requerApenas 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 para fullchain.pem
  • ssl_certificate_key: aponte para privkey.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:

  1. Timer/cron executa certbot renew
  2. Certbot verifica certificados instalados
  3. Identifica certificados com menos de 30 dias de validade
  4. Inicia processo de renovação (repete validação HTTP-01)
  5. Substitui certificado antigo pelo novo
  6. 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:

LimiteSignificadoExemplo
50 certificados/domínio/semanaMáximo de 50 certificados para subdomínios do seu domínioapi.site.com, www.site.com, etc. somados
5 duplicados/semanaMesmo certificado (exatos domínios) só pode ser emitido 5xEvita loops acidentais em scripts
10 contas/IP/3hCriação de novas contas ACME limitadaAfeta 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 comumO que aconteceu
Porta 80 bloqueadaFirewall mudou, Let's Encrypt não consegue validar
Servidor paradoNginx/Apache não estava rodando no momento da renovação
Domínio mudouDNS não aponta mais para o servidor
Disco cheioNã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