Como instalar Let's Encrypt no Apache Ubuntu: guia HTTPS gratuito
Aprenda a instalar Let's Encrypt no Apache Ubuntu com Certbot, configurar HTTPS gratuito, renovação automática e redirecionamento 301 em produção.
HTTPS deixou de ser opcional. Navegadores marcam sites HTTP como “Não seguro”, APIs externas recusam webhooks sem TLS, e SEO penaliza domínios sem certificado. Let’s Encrypt resolve isso de graça — certificados X.509 válidos, reconhecidos por todos os navegadores modernos, emitidos por uma autoridade certificadora pública.
Este tutorial cobre a instalação do Let’s Encrypt num servidor Apache rodando Ubuntu 22.04 ou 24.04, usando o cliente oficial Certbot. O foco é configuração de produção: emissão, redirecionamento 301 de HTTP pra HTTPS, renovação automática e validação real do certificado. Tempo estimado de execução: 15 a 20 minutos, assumindo que o DNS já está apontando pro servidor.
A persona-alvo é sysadmin ou desenvolvedor que já tem um Apache configurado servindo um site funcional em HTTP e precisa adicionar TLS. Se você ainda está provisionando o servidor do zero, instale Apache primeiro (sudo apt install apache2) e volte aqui depois que curl http://seu-dominio retornar HTML.
Pré-requisitos
Antes de começar, confirme que o servidor está com os pré-requisitos corretos. A validação HTTP-01 do Let’s Encrypt precisa alcançar o servidor pela porta 80, então qualquer bloqueio de firewall ou DNS desalinhado faz a emissão falhar logo no primeiro certbot run.
Ubuntu 22.04 LTS ou 24.04 LTS com acesso sudo. Apache 2.4+ já instalado e servindo o site em HTTP. Domínio público (ex: exemplo.com) com registro A apontando pro IP do servidor. Portas 80 e 443 abertas no firewall e em qualquer security group do provedor. Email válido pra notificações de expiração.
Certbot 2.x python3-certbot-apache 80 (HTTP-01) 90 dias Verifique o DNS antes de continuar. Rode dig +short seu-dominio.com.br e confirme que o IP retornado é o do servidor. Se não estiver, a propagação ainda pode estar acontecendo (TTL típico de 1 a 24 horas) — espere antes de tentar emitir.
Instalando o Certbot e o plugin Apache
O Certbot está disponível como pacote APT no Ubuntu, mas a versão dos repositórios oficiais costuma ficar atrás. Pra produção, o método recomendado pelo próprio projeto é o snap, que mantém o cliente atualizado automaticamente. Esta seção cobre a instalação via snap, que é a mais robusta.
Atualize o índice de pacotes e remova qualquer versão antiga do Certbot que tenha vindo do APT:
sudo apt update
sudo apt remove certbot python3-certbot-apache -ySe você nunca instalou antes, o remove simplesmente não faz nada — é seguro rodar.
Instale o snap core (já vem por padrão no Ubuntu 22.04+, mas garante a versão mais nova):
sudo snap install core
sudo snap refresh coreInstale o Certbot via snap e crie o symlink pra que o binário fique disponível no PATH:
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbotO modo --classic é necessário porque o Certbot precisa escrever em diretórios fora do sandbox snap (/etc/letsencrypt, /etc/apache2, /var/log/letsencrypt).
Confirme a instalação:
certbot --versionA saída deve ser algo como certbot 2.11.0. Se aparecer “command not found”, verifique se /snap/bin está no PATH ou refaça o symlink.
Verificando a configuração do Apache
O plugin --apache do Certbot lê os arquivos de VirtualHost em /etc/apache2/sites-enabled/ pra descobrir quais domínios estão servidos e qual vhost editar. Pra que o plugin funcione, cada vhost precisa ter a diretiva ServerName (e opcionalmente ServerAlias) configurada corretamente.
Liste os vhosts ativos:
sudo apachectl -SProcure por entradas com port 80 namevhost listando seu domínio. Se o servidor responder com *:80 is a NameVirtualHost mas o ServerName estiver vazio, edite o vhost antes de continuar.
Abra o vhost do seu site (geralmente /etc/apache2/sites-available/seu-dominio.conf ou 000-default.conf) e confirme que tem ServerName:
<VirtualHost *:80>
ServerName exemplo.com.br
ServerAlias www.exemplo.com.br
DocumentRoot /var/www/exemplo
</VirtualHost>Se editou, recarregue o Apache:
sudo systemctl reload apache2O Ubuntu vem com UFW desabilitado por padrão, mas se você ativou, libere HTTPS antes da emissão:
sudo ufw allow 'Apache Full'
sudo ufw statusA regra Apache Full libera 80 e 443. Se só liberar Apache (sem Full), a porta 443 fica bloqueada e o site nem carrega depois da configuração.
Emitindo o certificado
Com o Certbot instalado e o Apache configurado, a emissão é um único comando. O plugin --apache detecta os domínios, conversa com o Let’s Encrypt via HTTP-01, recebe o certificado, edita os VirtualHosts pra incluir as diretivas SSL e (opcionalmente) configura o redirect 301.
Execute o Certbot em modo interativo:
sudo certbot --apacheVocê será perguntado:
- Email pra notificações (recovery + expiração próxima)
- Aceite dos Termos de Serviço (
Apra aceitar) - Opt-in pra newsletter da EFF (
Nse preferir não receber) - Quais domínios certificar (selecione todos se quiser HTTPS em todos)
- Se quer redirecionar HTTP pra HTTPS automaticamente (escolha
2pra forçar redirect — recomendado)
Se tudo deu certo, a saída termina com algo parecido com:
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/exemplo.com.br/fullchain.pem
Key is saved at: /etc/letsencrypt/live/exemplo.com.br/privkey.pem
This certificate expires on 2026-08-27.O Certbot também cria um novo arquivo de vhost com sufixo -le-ssl.conf em /etc/apache2/sites-available/ contendo o bloco <VirtualHost *:443> com as diretivas SSL.
Let’s Encrypt limita 5 emissões falhas por hora pelo mesmo IP e 50 certificados por domínio registrado por semana. Se você está testando, use o flag --staging (sudo certbot --apache --staging) — emite contra o ambiente de teste, certificado não é confiável pelos navegadores mas não consome o rate limit de produção.
Configurando renovação automática
A instalação via snap já vem com renovação automática configurada via systemd timer. Você não precisa editar crontab nem criar scripts — o snap mantém o timer rodando duas vezes por dia, e o Certbot só faz a chamada real à API quando o certificado está a menos de 30 dias do vencimento.
Verifique se o timer está ativo:
sudo systemctl status snap.certbot.renew.timerA saída deve mostrar Active: active (waiting) e a próxima execução agendada.
Faça um dry-run da renovação pra confirmar que tudo está funcionando:
sudo certbot renew --dry-runO dry-run simula uma renovação contra o ambiente de staging do Let’s Encrypt — não consome rate limit, não substitui o certificado real. Se a saída terminar com Congratulations, all simulated renewals succeeded, está tudo certo.
Se você usa Apache atrás de um proxy reverso (HAProxy, por exemplo) que mantém o certificado em outro caminho, adicione um deploy hook em /etc/letsencrypt/renewal-hooks/deploy/:
#!/bin/bash
cp /etc/letsencrypt/live/exemplo.com.br/fullchain.pem /etc/haproxy/cert.pem
systemctl reload haproxyMarque como executável (chmod +x). O Certbot executa todos os scripts desse diretório após cada renovação bem-sucedida.
Verificando o certificado em produção
Depois da emissão, valide o certificado pelo lado de fora — não basta o Certbot dizer que deu certo, você precisa confirmar que o navegador vê o site como seguro e que a cadeia de certificação está completa.
Rode no terminal local (não no servidor):
curl -I https://exemplo.com.br
A resposta deve começar com HTTP/2 200 ou HTTP/1.1 200 OK. Se aparecer erro de certificado, algo está errado com a cadeia.
Pra inspecionar o certificado em detalhe:
echo | openssl s_client -connect exemplo.com.br:443 -servername exemplo.com.br 2>/dev/null | openssl x509 -noout -dates -issuer -subject
A saída mostra issuer (Let's Encrypt), subject (seu domínio) e datas de validade. Confirme que a data notAfter está ~90 dias à frente.
Pra teste completo de configuração SSL/TLS, use o SSL Labs em https://www.ssllabs.com/ssltest/analyze.html?d=exemplo.com.br. Uma configuração padrão do Certbot 2.x geralmente tira nota A.
Resolução de problemas comuns
Erro “Failed authorization procedure”
Significa que o Let’s Encrypt não conseguiu acessar http://seu-dominio/.well-known/acme-challenge/.... Causas comuns: porta 80 bloqueada no firewall, DNS apontando pra IP errado, ou Apache não escutando em 0.0.0.0:80. Verifique nessa ordem:
sudo ufw status
sudo ss -tlnp | grep :80
dig +short seu-dominio.com.br
Erro “Could not find a usable ‘apache2ctl’ binary”
O Certbot procura apache2ctl no PATH. Em alguns sistemas customizados, o binário está em /usr/sbin/ mas o PATH do snap não inclui. Crie symlink:
sudo ln -s /usr/sbin/apache2ctl /usr/local/bin/apache2ctl
Redirect loop após instalação
Geralmente é Apache atrás de um proxy reverso (CloudFront, Cloudflare) que termina TLS antes do servidor. O Apache recebe HTTP, redireciona pra HTTPS, o proxy envia HTTP de novo, loop. Solução: configure HTTPS=on via header confiável no vhost ou desabilite o redirect do Apache (deixe o proxy lidar).
Próximos passos
Com HTTPS funcionando, vale endurecer a configuração TLS:
- Ajuste
SSLProtocolpra desabilitar TLS 1.0 e 1.1 no vhost SSL (SSLProtocol -all +TLSv1.2 +TLSv1.3) - Adicione header HSTS após validar que tudo está funcionando bem:
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" - Configure OCSP stapling com
SSLUseStapling onpra reduzir latência da validação - Considere mover pra HTTP/2 (
Protocols h2 http/1.1) — exigemod_http2habilitado
Se você está colocando isso em produção e quer infraestrutura sem se preocupar com firewall, kernel updates ou tuning de Apache, uma VPS Hostini vem com Ubuntu LTS, snap instalado e portas 80/443 já liberadas — basta apontar o DNS e rodar certbot --apache.
Perguntas frequentes
Quanto tempo dura o certificado Let's Encrypt e como funciona a renovação?
Certificados Let's Encrypt têm validade de 90 dias. O Certbot instala um timer systemd (`certbot.timer`) que executa `certbot renew` duas vezes por dia. A renovação só faz a chamada à API quando o certificado está a menos de 30 dias de expirar, então rodar com frequência não consome rate limit.
Posso usar Let's Encrypt em domínio sem DNS público apontando pra ele?
Não pra validação HTTP-01 (que o Certbot usa por padrão com `--apache`). O Let's Encrypt precisa alcançar `http://seu-dominio/.well-known/acme-challenge/...` durante a emissão. Pra domínios internos, use o desafio DNS-01 com plugin `certbot-dns-*` apropriado pro seu provedor.
Como instalo certificado wildcard (*.exemplo.com) com Apache?
Wildcards exigem desafio DNS-01, então o plugin `--apache` não serve. Use `certbot certonly --manual --preferred-challenges=dns -d '*.exemplo.com' -d exemplo.com` ou um plugin DNS específico (`certbot-dns-cloudflare`, etc) e configure manualmente o `SSLCertificateFile` e `SSLCertificateKeyFile` nos VirtualHosts.
Por que o Certbot falha com 'Connection refused' durante a validação?
Geralmente é firewall bloqueando porta 80, Apache não escutando em 0.0.0.0:80, ou DNS não resolvendo pro IP do servidor. Verifique `sudo ufw status`, `sudo ss -tlnp | grep :80` e `dig +short SEU-DOMINIO` antes de tentar novamente.
Como forçar HTTPS sem quebrar o ACME challenge da renovação?
O Certbot adiciona automaticamente uma exceção `RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge/` no redirect quando você escolhe `2 - Redirect` durante `certbot --apache`. Se você editar o vhost manualmente, mantenha essa exceção — sem ela, a renovação HTTP-01 falha.
Qual a diferença entre `certbot --apache` e `certbot certonly --webroot`?
`--apache` usa o plugin que edita os vhosts automaticamente, instala o certificado e configura redirect. `certonly --webroot` só emite o certificado num diretório, deixando você configurar o Apache manualmente — útil quando você tem template de configuração customizado ou gerencia muitos sites via Ansible.