Como gerar certificado SSL grátis com Let's Encrypt (passo a passo)
Redes & Segurança · Por Kevin Marcondes · Publicado em · Atualizado em · 8 min de leitura
Neste tutorial, você aprende como gerar certificado SSL grátis com Let's Encrypt usando o Certbot. Vamos cobrir instalação, emissão com HTTP-01 ou DNS-01, configuração no Nginx/Apache, renovação e verificação. Requer acesso root e cuidado para não interromper serviços. O passo a passo é prático, direto e funciona para a maioria dos servidores Linux.
Pré-requisitos e quando usar Let's Encrypt
Antes de começar, garanta que seu domínio aponte para o servidor e que você tenha permissões administrativas. Para sites públicos, blogs, APIs e lojas, Let’s Encrypt atende bem com certificados DV (Domain Validation). Para ambientes internos sem acesso público, prefira DNS-01.
Pré-requisitos essenciais:
- Domínio ativo (ex.: exemplo.com) apontando para o servidor.
- Acesso root ou sudo ao servidor Linux.
- Portas 80 (HTTP) e 443 (HTTPS) liberadas no firewall e na nuvem.
- Servidor web (Nginx ou Apache) instalado ou possibilidade de parar o serviço para modo standalone.
- Tempo de DNS propagado (aguarde alguns minutos a horas após alterar A/AAAA/CNAME).
Escolha do desafio: HTTP-01 ou DNS-01
O Let’s Encrypt valida a posse do domínio de duas formas principais. Escolha conforme o seu cenário. Wildcards (*.exemplo.com) exigem DNS-01.
Se você também precisa proteger APIs com boas práticas de autenticação e rate limiting, aprofunde em proteger APIs.
| Método | Quando usar | Requisitos | Observações |
|---|---|---|---|
| HTTP-01 | Site público respondendo na porta 80 | Porta 80 aberta; conteúdo acessível | Mais simples; funciona com webroot, nginx ou apache plugins |
| DNS-01 | Wildcard, serviços atrás de proxy/CDN, sem porta 80 | Acesso ao DNS para criar TXT | Automatize via API do seu provedor de DNS quando possível |
Instalar o Certbot no servidor
O Certbot é o cliente recomendado para obter e renovar certificados. A seguir, opções para Ubuntu/Debian (snap) e RHEL/CentOS (dnf). Execute como root ou prefixe com sudo.
# Ubuntu/Debian via snap (recomendado)
sudo snap install core && sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
certbot --version
# Alternativa Ubuntu/Debian via APT (se não usar snap)
sudo apt-get update
sudo apt-get install -y certbot python3-certbot-nginx python3-certbot-apache
# RHEL/CentOS 8/9
sudo dnf install -y epel-release
sudo dnf install -y certbot python3-certbot-nginx python3-certbot-apache
certbot --version
Emitir o certificado com o Certbot
Escolha a opção que melhor se encaixa. Para HTTP-01, você pode usar o plugin do Nginx/Apache ou o modo webroot. O modo standalone liga um servidor temporário (porta 80). Parar o servidor web causa indisponibilidade temporária.
# Substitua "exemplo.com" e adicione -d para cada domínio/subdomínio
# 1) Plugin Nginx (detecta e configura automaticamente)
sudo certbot --nginx -d exemplo.com -d www.exemplo.com
# 2) Plugin Apache
sudo certbot --apache -d exemplo.com -d www.exemplo.com
# 3) Somente certificado (webroot): informe a raiz pública do site
sudo certbot certonly --webroot -w /var/www/html \
-d exemplo.com -d www.exemplo.com
# 4) Standalone (para quando não há servidor web ativo)
# ATENÇÃO: isso usa a porta 80 temporariamente
sudo systemctl stop nginx || true
sudo systemctl stop apache2 httpd || true
sudo certbot certonly --standalone -d exemplo.com
sudo systemctl start nginx || true
sudo systemctl start apache2 httpd || true
Configurar HTTPS no Nginx ou Apache
Após emitir, os arquivos ficam em /etc/letsencrypt/live/SEU_DOMINIO/. Abaixo, exemplos de configuração. Ajuste caminhos e upstreams conforme seu ambiente.
Você também pode automatizar reloads pós-deploy no seu pipeline. Veja ideias em CI/CD com GitHub Actions.
# Nginx: redirecionar HTTP -> HTTPS
server {
listen 80;
server_name exemplo.com www.exemplo.com;
return 301 https://$host$request_uri;
}
# Nginx: servidor HTTPS
server {
listen 443 ssl http2;
server_name exemplo.com www.exemplo.com;
ssl_certificate /etc/letsencrypt/live/exemplo.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/exemplo.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
root /var/www/html;
index index.html index.php;
location / {
try_files $uri $uri/ =404;
}
}
# Apache: habilitar sites com SSL (exemplo mínimo)
# Arquivo: /etc/apache2/sites-available/exemplo-ssl.conf
# Habilite módulos: a2enmod ssl rewrite && a2ensite exemplo-ssl && systemctl reload apache2
<VirtualHost *:443>
ServerName exemplo.com
ServerAlias www.exemplo.com
DocumentRoot /var/www/html
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/exemplo.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/exemplo.com/privkey.pem
</VirtualHost>
# Redireciono HTTP para HTTPS (Apache):
<VirtualHost *:80>
ServerName exemplo.com
ServerAlias www.exemplo.com
Redirect "/" "https://exemplo.com/"
</VirtualHost>
Renovação automática e teste do processo
Certificados do Let’s Encrypt expiram em cerca de 90 dias. O Certbot instala um timer (systemd) ou você pode agendar via cron. Teste a renovação sem riscos com --dry-run.
Após renovar, recarregue o servidor web para aplicar o novo certificado.
# Testar renovação (sem emitir de fato)
sudo certbot renew --dry-run
# Ver timers do systemd relacionados ao certbot
systemctl list-timers | grep -i certbot || true
# Cron alternativo (executa 2x ao dia)
# /etc/crontab
# 0 3,15 * * * root certbot renew --quiet --deploy-hook "systemctl reload nginx || systemctl reload apache2 || systemctl reload httpd"
Como confirmar que funcionou
Valide o HTTPS no navegador e por linha de comando. Verifique cabeçalhos, emissor, datas e cadeia de certificados. Confirme que o redirecionamento 301 de HTTP para HTTPS está ativo.
Para confiabilidade contínua, considere monitoramento 24h de servidores Linux.
# Verificar resposta e cabeçalhos
curl -I https://exemplo.com
# Conferir certificado apresentado (emissor, sujeito e validade)
openssl s_client -connect exemplo.com:443 -servername exemplo.com </dev/null \
| openssl x509 -noout -issuer -subject -dates
Solução de problemas comuns
Veja problemas frequentes e como checar. Ajuste conforme sua distribuição e ambiente de rede.
- Desafio HTTP-01 falha: porta 80 bloqueada, webroot incorreto, proxy impedindo acesso. - DNS não propagou: aguarde TTL; confirme registros A/AAAA/CNAME. - Wildcard: use DNS-01. - Reverse proxy/balanceador: rode o Certbot no edge ou use DNS-01. - Permissões: caminhos de certificado legíveis pelo serviço web.
- Libere portas 80/443 no firewall e na nuvem.
- Confirme o caminho webroot; teste um arquivo em .well-known/acme-challenge/.
- Cheque logs do Certbot para mensagens detalhadas.
- Verifique DNS com dig/nslookup.
- Se precisar, troque para DNS-01 e automatize via API do provedor.
# Portas abertas localmente?
sudo ss -tulpen | egrep ':80|:443' || true
# UFW (Ubuntu):
sudo ufw allow 'Nginx Full' || sudo ufw allow 80,443/tcp
# firewalld (RHEL/CentOS):
sudo firewall-cmd --add-service=http --add-service=https --permanent
sudo firewall-cmd --reload
# Logs do Certbot
tail -n 100 -f /var/log/letsencrypt/letsencrypt.log
# Verificar DNS (substitua pelo seu domínio)
dig +short A exemplo.com || nslookup exemplo.com
# Testar acesso ao desafio HTTP-01 (crie um arquivo e acesse via navegador)
mkdir -p /var/www/html/.well-known/acme-challenge/
echo ok > /var/www/html/.well-known/acme-challenge/teste
curl http://exemplo.com/.well-known/acme-challenge/teste
Próximos passos e segurança contínua
Mantenha o servidor atualizado, desative protocolos inseguros e revise headers de segurança (HSTS, X-Frame-Options, etc.). Se identificar pontos fracos no app, priorize correções.
Para apoio em diagnósticos de risco, veja como corrigir vulnerabilidades em aplicações web.
Perguntas frequentes
Let's Encrypt é confiável para produção?
Sim. É uma autoridade certificadora amplamente reconhecida, emitindo certificados DV. Para a maioria dos sites e APIs públicas, DV é suficiente. Se você precisa de validação organizacional/estendida, busque CAs que ofereçam OV/EV.
Posso emitir certificado wildcard (*.dominio.com)?
Sim, com o desafio DNS-01. Você precisará criar (ou automatizar) registros TXT no DNS do domínio. Muitos provedores de DNS têm APIs para automatizar esse processo com o Certbot.
Preciso abrir a porta 80 para validar?
Para HTTP-01, sim. A validação acessa um token via http://seu-dominio/.well-known/acme-challenge/. Alternativas: usar DNS-01 ou o modo standalone, desde que a porta 80 esteja temporariamente livre para o Certbot.
Como renovar sem downtime?
Use o Certbot com webroot/nginx/apache e configure um deploy-hook para recarregar o serviço (reload), não reiniciar. O reload aplica o novo certificado sem derrubar conexões ativas na maioria dos servidores.
Dá para incluir vários domínios no mesmo certificado?
Sim. Adicione múltiplas opções -d no comando do Certbot (ex.: -d exemplo.com -d www.exemplo.com -d app.exemplo.com). Só inclua domínios que apontem para o mesmo servidor ou use DNS-01.
Posso usar ambiente de testes para evitar limites?
Sim. Use --staging nos comandos do Certbot para emitir certificados de teste, ideais durante implantação e automação. Depois, em produção, remova --staging para emitir certificados válidos.
Precisa de ajuda para um cenário mais complexo?
Ambientes com reverse proxy, balanceadores, containers ou múltiplos domínios podem exigir DNS-01 e automação. Se quiser suporte pontual na configuração, vamos conversar.
Falar sobre sua configuraçãoVeja também
- tutorial: implementar Canary releases com Traefik em Docker Compose usando headers e weight routing para deploys graduais de aplicações PHP
- Tutorial: configurar HAProxy com Let's Encrypt e healthchecks para balanceamento de tráfego entre containers Docker em VPS (passo a passo)
- Tutorial prático: implementar mTLS entre Nginx e microserviços usando smallstep CA em Docker Compose
- Tutorial: configurar cgroup v2 e systemd ResourceControl para limitar CPU, memória e I/O de containers Docker no Debian