Como instalar Certbot no Apache Ubuntu 24.04
Instale Certbot via apt no Ubuntu 24.04 para obter certificados Let's Encrypt. Evite erros de emissão causados pela falta do ServerName no vhost do Apache.
O que você está construindo
Um site Apache no Ubuntu 24.04 respondendo via HTTPS com um certificado Let's Encrypt gratuito e confiável pelos navegadores — emitido pelo Certbot e renovado automaticamente por um timer do systemd que você não precisará gerenciar novamente. O comando que executa o trabalho possui apenas uma linha. Qualquer erro ocorre antes dessa linha: um vhost sem ServerName, a porta 80 fechada no firewall do provedor ou o DNS ainda apontando para o servidor antigo. Por isso, este guia foca principalmente nos pré-requisitos e indica a string de erro exata que cada falha apresenta.
Duas notas de escopo. Se o seu servidor web for nginx, o fluxo é o mesmo, mas o plugin e as configurações mudam — use a versão nginx deste guia em vez desta. E se o recurso que você está protegendo for apenas interno — um painel de administração em um endereço privado ou um servidor de staging que ninguém mais acessa — você não precisa de uma autoridade de certificação; um certificado self-signed exige menos infraestrutura e funciona offline.
Pré-requisitos, e as três formas de falha antes do Certbot ser executado
- Apache já servindo seu site via HTTP comum. O plugin do Apache do Certbot edita um site existente; ele não cria um novo. Se você estiver começando de um VPS limpo, instale o LAMP stack on Ubuntu 24.04 primeiro e volte — este guia é o capítulo de TLS que falta.
- Um domínio público com um registro A apontando para o endereço do seu VPS. O desafio HTTP-01 do Let's Encrypt exige que os servidores de validação se conectem ao seu servidor via internet: sem NAT em homelab sem redirecionamento de porta, sem nomes
.local, sem IPs puros.dig +short example.comdeve retornar o endereço do seu VPS; se você alterou o DNS na última hora, aguarde o TTL do registro antigo antes de emitir o certificado. - Se um registro AAAA existir, ele deve estar correto. O Let's Encrypt prioriza IPv6 quando um registro AAAA é publicado. Um AAAA desatualizado causará falha na validação mesmo que o
curldo seu laptop — provavelmente via IPv4 — funcione normalmente. Publique um AAAA correto ou não publique nenhum.
As portas 80 e 443 precisam estar abertas no ufw e no firewall de rede do seu provedor — a maioria dos painéis de hospedagem possui um segundo firewall que o SO não enxerga. O HTTP-01 valida especificamente pela porta 80; você não pode rodar isso apenas na 443.
sudo ufw allow "Apache Full"
sudo ufw statusCom isso configurado, o trabalho todo leva quinze minutos, e dez deles são de leitura.
Snap ou apt Certbot? No 24.04, o apt finalmente está ok
O Certbot mudou para a distribuição snap anos atrás por um bom motivo: pacotes de distro ficam obsoletos. O Ubuntu 20.04 entregou o Certbot 0.40 e nunca atualizou, e o projeto cansou de depurar bugs de cinco anos atrás. No 24.04 esse motivo não existe mais — o repositório entrega o Certbot 2.9.0, uma versão atual, e o unattended-upgrades mantém as correções. Minha recomendação para este OS: use apt. Você evita o daemon snapd, o plugin do Apache é instalado na mesma transação e o timer de renovação integra-se ao systemd da forma padrão do Debian.
sudo apt update
sudo apt install -y certbot python3-certbot-apache
certbot --versionResultado correto: certbot 2.9.0. O pacote python3-certbot-apache é o plugin que lê e edita suas configurações do Apache — sem ele, o certbot --apache falha com The requested apache plugin does not appear to be installed.
O snap ainda é a escolha certa em dois casos: você quer o Certbot mais recente no dia do lançamento, ou você precisa de um plugin de DNS que só é distribuído como snap (vários plugins de provedores certbot-dns-* são). Se seguir esse caminho:
sudo apt remove -y certbot python3-certbot-apache
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbotIndependentemente da sua escolha, nunca execute ambos. Duas instalações significam dois agendadores de renovação disputando o /etc/letsencrypt, e o certbot que seu shell encontrar em PATH pode não ser o que gerencia seus certificados. A linha apt remove acima não é apenas decorativa.
As edições do Certbot no vhost já devem existir — ServerName é essencial
O certbot --apache funciona encontrando o virtual host na porta 80 cujo ServerName ou ServerAlias coincide com cada domínio -d passado. Isso prova o controle do domínio através dele e, em seguida, cria uma versão SSL desse vhost. Sem um ServerName correspondente, não há correspondência — e o 000-default.conf padrão do Ubuntu vem com o ServerName comentado. Essa única linha comentada é o motivo mais comum para a falha do comando principal deste guia.
Portanto, antes de usar o Certbot, configure um vhost baseado em nome para o site. Crie o /etc/apache2/sites-available/example.com.conf:
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com
ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined
</VirtualHost>Habilite-o e confirme se o Apache consegue processá-lo e rotear o nome para ele:
sudo a2ensite example.com.conf
sudo apache2ctl configtest
sudo systemctl reload apache2
sudo apache2ctl -SO configtest deve exibir Syntax OK. Se também exibir AH00558: apache2: Could not reliably determine the server's fully qualified domain name, trata-se de um aviso sobre o ServerName global, não sobre o seu vhost — não causa danos aqui e é silenciado pelo echo "ServerName $(hostname -f)" | sudo tee /etc/apache2/conf-available/servername.conf && sudo a2enconf servername && sudo systemctl reload apache2.
A saída do -S é a verificação importante. Você deve ver uma linha como port 80 namevhost example.com (/etc/apache2/sites-enabled/example.com.conf:1) com alias www.example.com abaixo dela — o Apache reporta o symlink sites-enabled que ele realmente leu, não o arquivo que você editou em sites-available. Se o example.com não estiver listado na porta 80, o Certbot também não o encontrará.
Emita o certificado: certbot --apache
sudo certbot --apache -d example.com -d www.example.comA primeira execução solicita três informações: um endereço de e-mail (usado para sua conta ACME e avisos urgentes da CA; o Let's Encrypt não envia mais avisos de expiração, portanto o monitoramento de renovações é responsabilidade do usuário), a aceitação dos termos do Let's Encrypt e se você deseja compartilhar seu e-mail com a EFF. Não há mais a pergunta sobre redirecionamento: desde o Certbot 2.0, o instalador do Apache redireciona HTTP para HTTPS por padrão, que é o comportamento desejado. Use --no-redirect se você realmente precisar de HTTP puro para continuar servindo conteúdo.
O sucesso é exibido desta forma, e você deve ler a mensagem em vez de apenas passar o olho:
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/example.com/privkey.pem
This certificate expires on 2026-10-14.
Deploying certificate
Successfully deployed certificate for example.com to /etc/apache2/sites-available/example.com-le-ssl.conf
Successfully deployed certificate for www.example.com to /etc/apache2/sites-available/example.com-le-ssl.conf
Congratulations! You have successfully enabled HTTPS on https://example.com and https://www.example.comPor trás dessa mensagem, o Certbot realizou quatro ações: habilitou o módulo ssl do Apache, caso ainda não estivesse habilitado; escreveu o example.com-le-ssl.conf — uma cópia do seu vhost em *:443 com SSLEngine on e os caminhos do certificado — habilitou-o; e adicionou um bloco RewriteRule ao vhost original da porta 80 que redireciona tudo via 301 para HTTPS. Seu arquivo vhost original é editado, não substituído, e o arquivo SSL correspondente é criado ao lado dele para que você possa ler cada linha adicionada.
Onde o certificado realmente reside e por que você nunca deve copiá-lo
Tudo fica em /etc/letsencrypt/live/example.com/: fullchain.pem (o certificado e a cadeia intermediária — o que os servidores devem apontar), privkey.pem (a chave privada, legível apenas pelo root), além de cert.pem e chain.pem para softwares que exigem os arquivos separadamente. Estes são symlinks para /etc/letsencrypt/archive/, e esse redirecionamento é o mecanismo de renovação: a renovação grava novos arquivos em archive/ e atualiza os symlinks. Aponte qualquer outro software para os caminhos em live/ para receber as renovações automaticamente; copie os arquivos para outro local e você terá uma interrupção de serviço em 90 dias.
O outro arquivo importante é o /etc/letsencrypt/renewal/example.com.conf, que registra como este certificado foi emitido — authenticator = apache, installer = apache, os domínios — permitindo que a renovação repita o processo sem intervenção, incluindo o reload do Apache posteriormente.
A renovação já está agendada — verifique-a, não a crie
Certificados Let's Encrypt duram 90 dias por padrão. O pacote apt já instalou a estrutura necessária: um timer do systemd que executa o Certbot duas vezes por dia em horários aleatórios, renovando qualquer certificado que expire em até 30 dias. Não adicione um cron job adicional; um segundo agendador apenas gera ruído nos logs e aumenta o risco de atingir o rate-limit.
systemctl list-timers certbot.timer
sudo certbot renew --dry-runO primeiro comando mostra o timer ativo, com um tempo NEXT dentro das próximas 24 horas — o agendamento é duas vezes ao dia com atraso aleatório, portanto o horário exato é deliberadamente imprevisível (na instalação via snap, o timer é snap.certbot.renew.timer). O dry run realiza um ensaio completo de renovação contra o ambiente de staging do Let's Encrypt — desafio real, sem emissão de certificado e sem custo de rate-limit. O resultado correto termina com:
Congratulations, all simulated renewals succeeded:
/etc/letsencrypt/live/example.com/fullchain.pem (success)Se o dry run falhar, a renovação real em ~60 dias falhará da mesma forma — corrija agora, enquanto o certificado atual ainda tem todo o seu período de validade. O culpado comum é uma regra de firewall adicionada após a emissão que fechou a porta 80 novamente.
Verifique com curl, e o que o cadeado deve exibir
curl -sI http://example.com | head -n 3
curl -I https://example.com
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -issuer -datesO primeiro deve retornar HTTP/1.1 301 Moved Permanently com um header Location: https://example.com/ — este é o redirect instalado pelo Certbot. O segundo deve retornar HTTP/1.1 200 OK sem erros de TLS no curl. O terceiro imprime o emissor — uma linha O = Let's Encrypt com um CN curto como R12 ou E7 — e notAfter aproximadamente 90 dias de validade. Em um browser, você verá o cadeado, e clicar nele mostrará o mesmo emissor. Se o curl funcionar e o browser exibir um aviso, você provavelmente está visualizando uma página em cache ou o hostname incorreto, não um problema de certificado.
Múltiplos sites: um certificado SAN ou um certificado por site
Ambas as opções funcionam; o processo de renovação é o mesmo. Para sites não relacionados no mesmo servidor, execute o comando de emissão uma vez por site — cada um terá seu próprio diretório em live/ e sua própria configuração de renovação. Um problema em um domínio não impede a renovação dos outros. Esta é a minha configuração padrão.
Para um site com vários nomes, utilize um único certificado SAN — um único certificado pode conter até 100 nomes. Você já fez isso acima com example.com e www.example.com. Para adicionar um nome a um certificado existente posteriormente, reemita o certificado informando o nome do certificado e a lista completa de novos nomes:
sudo certbot --apache --cert-name example.com -d example.com -d www.example.com -d blog.example.comO Certbot detecta o conjunto de domínios alterado, solicita a confirmação da expansão e substitui o certificado no local — no mesmo caminho live/, portanto nada mais precisa ser alterado. Note que a lista é uma substituição, não uma adição: omita o www desse comando e o novo certificado removerá o domínio silenciosamente.
Wildcards exigem DNS-01, e geralmente você não precisa de um wildcard
O HTTP-01 não pode emitir *.example.com — colocar um arquivo em um servidor web prova o controle de um hostname, não de um namespace inteiro. Wildcards exigem o desafio DNS-01: o Certbot define um registro TXT em _acme-challenge.example.com, o que na prática exige um plugin certbot-dns-* com credenciais de API do seu provedor de DNS, ou a edição manual de registros TXT em cada renovação com --manual (trabalhoso — não planeje seu fluxo de trabalho assim). O guia completo, desde a mecânica do registro TXT até um plugin para renovação automática, está em certificados wildcard com Certbot via DNS-01. Conselho técnico: se você tem quatro subdomínios conhecidos, um certificado SAN listando todos os quatro é mais simples que um wildcard e não exige chaves de API de DNS armazenadas no servidor.
Modos de falha e as mensagens que você verá
O Certbot recusa a inicialização porque a configuração do Apache está incorreta.
The apache plugin is not working; there may be problems with your existing configuration.
The error was: MisconfigurationError('Error while running apache2ctl configtest.\n\nAction \'configtest\' failed.\nThe Apache error log may have more information.\n\nAH00526: Syntax error on line 12 of /etc/apache2/sites-enabled/example.com.conf')O plugin executa configtest antes de qualquer alteração e aborta se o Apache apresentar erros — as mensagens \n são literais, pois o Certbot imprime o repr da exceção. Execute sudo apache2ctl configtest manualmente: ele indica o arquivo e a linha — geralmente um erro de digitação por edição manual, um SSLCertificateFile apontando para um caminho inexistente ou um módulo referenciado mas não habilitado. Corrija até que apareça Syntax OK e execute o Certbot novamente.
Nenhum vhost corresponde ao domínio.
Unable to find a virtual host listening on port 80 which is currently the only challenge port.Este é o erro de falta de ServerName mencionado anteriormente, detectado no momento da emissão. O Certbot buscou em todos os vhosts habilitados na porta 80 por um ServerName/ServerAlias que correspondesse ao seu -d e não encontrou nada. O comando sudo apache2ctl -S mostra o que o Apache está roteando de fato; adicione a linha ServerName ao vhost correto, recarregue e tente novamente. Um erro similar é a validação atingir o vhost errado — a resposta do desafio retorna Invalid response ... 404 porque outro site interceptou a requisição. O diagnóstico e a ferramenta são os mesmos: apache2ctl -S.
A validação expirou (timeout).
Certbot failed to authenticate some domains (authenticator: apache).
...
Detail: ...: Timeout during connect (likely firewall problem)O Let's Encrypt não conseguiu abrir uma conexão TCP na porta 80 no endereço anunciado pelo seu DNS. Em ordem de probabilidade: o firewall da rede do seu provedor (distinto do ufw, configurado no painel de hospedagem), um ruleset do ufw permitindo apenas 443 ou apenas SSH, o DNS ainda apontando para um servidor anterior, ou o problema de registro AAAA obsoleto — os servidores deles tentaram IPv6, mas o seu responde apenas via IPv4. Teste de fora da VPS: execute curl -I http://example.com do seu laptop para reproduzir o que o validador deles enxerga.
Você atingiu um limite de taxa (rate limit) por excesso de tentativas.
Error creating new order :: too many failed authorizations recently: see https://letsencrypt.org/docs/rate-limits/O Let's Encrypt permite 5 validações falhas por hostname, por conta, por hora — desde a reformulação dos limites de 2025, o sistema funciona como um balde que se enche gradualmente, recuperando aproximadamente uma tentativa a cada 12 minutos — e insistir em tentativas contra um firewall bloqueado esgota o limite rapidamente. Esperar funciona, mas a solução real é comportamental: após qualquer falha, faça o debug usando o ambiente de staging até obter sucesso.
sudo certbot certonly --apache --dry-run -d example.com -d www.example.comObserve o certonly: o --dry-run só é aceito pelos subcomandos certonly e renew, e o comando certbot --apache --dry-run puro recusa a execução, informando --dry-run currently only works with the 'certonly' or 'renew' subcommands. O dry run valida contra o staging, que possui limites generosos e não emite certificados reais, permitindo testes contínuos. Só execute o comando real após o staging passar. Os outros limites — 50 certificados por domínio registrado por semana, 5 duplicatas do mesmo conjunto de nomes por semana — só serão atingidos se um script estiver reemitindo certificados em um loop.
Com o HTTPS ativo, lembre-se que o certificado protege o transporte, não o servidor: a porta 22 continua recebendo tentativas de brute-force de senhas. Combinar isso com Fail2ban no Ubuntu 24.04 é o próximo passo lógico.
FAQ
Devo instalar o Certbot via snap ou apt para Apache no Ubuntu 24.04?
Use apt. O Ubuntu 24.04 possui o Certbot 2.9.0, que é atual o suficiente para este guia, recebe patches de segurança via unattended-upgrades e não requer o snapd. Escolha o snap apenas se precisar da versão mais recente imediatamente ou de um plugin de DNS distribuído exclusivamente como snap — e se mudar de método, execute apt remove certbot python3-certbot-apache primeiro para evitar que dois agendadores de renovação coexistam.
Por que o Certbot exibe "Unable to find a virtual host listening on port 80"?
Porque nenhum vhost habilitado na porta 80 possui um ServerName ou ServerAlias correspondente ao domínio passado com -d — o vhost padrão do Ubuntu vem com o ServerName comentado. Execute sudo apache2ctl -S, localize (ou crie) o vhost que deve responder pelo nome, adicione ServerName example.com, recarregue o Apache e execute o Certbot novamente.
Como corrigir "Timeout during connect (likely firewall problem)"?
O Let's Encrypt não conseguiu alcançar a porta 80 no endereço publicado pelo seu DNS. Verifique o firewall de rede no painel do seu provedor e também o ufw, confirme se dig +short example.com retorna este VPS e delete ou corrija qualquer registro AAAA antigo — a validação prioriza IPv6 quando este existe. Confirme a correção de fora do servidor com curl -I http://example.com e teste com sudo certbot certonly --apache --dry-run -d example.com antes da emissão real.
O Certbot renova certificados automaticamente no Ubuntu 24.04?
Sim. O pacote apt instala o certbot.timer, um timer do systemd que roda duas vezes ao dia e renova qualquer certificado faltando 30 dias para o vencimento, recarregando o Apache em seguida; o snap utiliza o snap.certbot.renew.timer para a mesma função. Verifique com systemctl list-timers certbot.timer e teste com sudo certbot renew --dry-run — não adicione seu próprio cron job adicional.
Como obter um certificado wildcard com Certbot e Apache?
Wildcards exigem o desafio DNS-01: o Certbot deve inserir um registro TXT em _acme-challenge.example.com, o que requer um plugin certbot-dns-* com credenciais de API do seu provedor de DNS (a alternativa --manual exige edição manual de registros TXT em cada renovação). Se você tiver apenas alguns subdomínios conhecidos, um certificado SAN listando-os explicitamente é mais simples e evita manter chaves de API de DNS no servidor.