Instalar Certbot no Apache do Ubuntu 24.04
Emita um certificado Let's Encrypt no Apache com uma linha. No Ubuntu 24.04, o apt instala o Certbot 2.9.0 sem snap. Evite o erro de ServerName ausente.
O que você está a configurar
Um site Apache no Ubuntu 24.04 que responde por HTTPS com um certificado Let's Encrypt gratuito e reconhecido pelos navegadores, emitido pelo Certbot e renovado automaticamente por um temporizador systemd que você não precisa de voltar a acompanhar. O comando que faz o trabalho é uma única linha. Tudo o que pode correr mal acontece antes dessa linha: um vhost sem ServerName, a porta 80 fechada na firewall do fornecedor ou o DNS ainda a apontar para o servidor antigo. Por isso, este guia dedica a maior parte do conteúdo aos pré-requisitos e indica a mensagem de erro exata apresentada por cada falha.
Há duas notas sobre o âmbito. Se o seu servidor Web for nginx, o fluxo é semelhante, mas o plugin e as configurações são diferentes; use antes a versão deste guia para nginx. Se o serviço que pretende proteger for apenas interno, como um painel de administração num endereço privado ou um servidor de staging que mais ninguém acede, não precisa de uma autoridade de certificação; um certificado autoassinado exige menos configuração e funciona offline.
Pré-requisitos e as três formas de isto falhar antes de o Certbot sequer ser executado
- O Apache já deve servir o seu site por HTTP simples. O plugin Apache do Certbot edita um site existente; não cria um. Se está a começar com um VPS vazio, configure primeiro a stack LAMP no Ubuntu 24.04 e depois volte aqui. Este guia é o capítulo de TLS que lhe falta.
- Um domínio público com um registo A para o endereço do seu VPS. O desafio HTTP-01 do Let's Encrypt significa que os servidores de validação se ligam ao seu servidor através da Internet: não funciona num homelab atrás de NAT sem reencaminhamento de portas, nem com nomes
.local, nem com IPs isolados.dig +short example.comtem de devolver o endereço do seu VPS. Se alterou o DNS na última hora, aguarde o TTL do registo anterior antes de emitir o certificado. - Se existir um registo AAAA, tem de estar correto. O Let's Encrypt prefere IPv6 quando é publicado um registo AAAA. Por isso, um AAAA desatualizado faz a validação falhar, mesmo que
curlfuncione corretamente a partir do seu portátil, provavelmente através de IPv4. Publique um AAAA correto ou não publique nenhum.
As portas 80 e 443 têm de estar abertas no ufw e na firewall de rede do seu provedor. A maioria dos painéis de alojamento tem uma segunda firewall que o sistema operativo não consegue ver. O HTTP-01 valida especificamente através da porta 80; não pode executar este procedimento apenas com a porta 443.
sudo ufw allow "Apache Full"
sudo ufw statusCom estes requisitos cumpridos, todo o trabalho demora quinze minutos, dos quais dez são passados a ler.
Certbot via Snap ou apt? No 24.04, o apt finalmente é uma opção adequada
O Certbot passou para a distribuição via snap há vários anos por um bom motivo: os pacotes das distribuições ficaram desatualizados. O Ubuntu 20.04 incluía o Certbot 0.40 e nunca o atualizou, e o projeto acabou por se cansar de corrigir problemas com cinco anos. No 24.04, esse motivo deixou de existir: o repositório inclui o Certbot 2.9.0, uma versão atual, e o unattended-upgrades mantém-no atualizado com correções. A minha recomendação para este sistema operativo é usar o apt. Assim, não precisa do daemon snapd, o plugin do Apache é instalado na mesma transação e o temporizador de renovação integra-se no systemd da forma habitual no 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 altera as configurações do Apache. Sem ele, certbot --apache falha com The requested apache plugin does not appear to be installed.
O snap continua a ser a opção correta em dois casos: se quiser a versão mais recente do Certbot no próprio dia em que é lançada ou se precisar de um plugin DNS distribuído apenas como snap. Vários plugins dos fornecedores certbot-dns-* são distribuídos dessa forma. Se escolher essa opção:
sudo apt remove -y certbot python3-certbot-apache
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbotSeja qual for a sua escolha, nunca execute as duas opções. Duas instalações significam dois agendadores de renovação a competir por /etc/letsencrypt, e o certbot encontrado pela sua shell em PATH pode não ser o que gere os seus certificados. A linha apt remove acima não é uma decoração opcional.
Os vhosts que o Certbot edita já têm de existir; ServerName é o elemento essencial
certbot --apache funciona procurando o virtual host da porta 80 cujo ServerName ou ServerAlias corresponde a cada domínio -d fornecido, comprovando o controlo do domínio através dele e, em seguida, escrevendo uma réplica SSL desse vhost. Sem um ServerName correspondente, não há correspondência. Além disso, o 000-default.conf predefinido do Ubuntu inclui ServerName comentado. Essa única linha comentada é o motivo mais comum para o grande comando deste guia falhar.
Antes de executar o Certbot, configure o site com um vhost baseado corretamente no nome. Crie /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>Ative-o e confirme que o Apache analisa o ficheiro e encaminha o nome para esse vhost:
sudo a2ensite example.com.conf
sudo apache2ctl configtest
sudo systemctl reload apache2
sudo apache2ctl -Sconfigtest tem de apresentar Syntax OK. Se também apresentar AH00558: apache2: Could not reliably determine the server's fully qualified domain name, isso é um aviso sobre o ServerName global, não sobre o seu vhost. É inofensivo neste caso e pode ser silenciado com echo "ServerName $(hostname -f)" | sudo tee /etc/apache2/conf-available/servername.conf && sudo a2enconf servername && sudo systemctl reload apache2.
O resultado de -S é a verificação relevante. Procure 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 indica o link simbólico sites-enabled que leu efetivamente, e não o ficheiro que editou em sites-available. Se example.com não estiver listado na porta 80, o Certbot também não o encontrará.
Emitir o certificado: certbot --apache
sudo certbot --apache -d example.com -d www.example.comNa primeira execução, são solicitados três dados: um endereço de e-mail (usado na sua conta ACME e para avisos urgentes da CA; o Let's Encrypt já não envia avisos de expiração, por isso cabe-lhe monitorizar as renovações), a aceitação dos termos do Let's Encrypt e a autorização para partilhar o seu e-mail com a EFF. Já não é apresentada uma pergunta sobre o redirecionamento: desde o Certbot 2.0, o instalador do Apache redireciona HTTP para HTTPS por predefinição, que é o comportamento pretendido. Passe --no-redirect se realmente precisar de continuar a servir conteúdo por HTTP sem encriptação.
Um resultado bem-sucedido é semelhante a este. Leia-o com atenção em vez de apenas o consultar rapidamente:
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 executou quatro ações: ativou o módulo ssl do Apache, caso ainda não estivesse ativado; criou example.com-le-ssl.conf, uma cópia do seu vhost em *:443 com SSLEngine on e os caminhos dos certificados; ativou esse vhost; e adicionou um bloco RewriteRule ao vhost original da porta 80, que redireciona tudo para HTTPS com o código 301. O ficheiro do vhost original é editado, não substituído, e a cópia SSL fica ao lado dele, permitindo consultar todas as linhas adicionadas.
Onde o certificado está efetivamente e por que nunca deve copiá-lo
Tudo fica em /etc/letsencrypt/live/example.com/: fullchain.pem (o certificado e a cadeia intermediária, para onde os servidores devem apontar), privkey.pem (a chave privada, legível apenas por root), além de cert.pem e chain.pem para software que precisa dos componentes separadamente. Estes ficheiros são links simbólicos para /etc/letsencrypt/archive/. Essa indireção é o mecanismo de renovação: a renovação grava novos ficheiros em archive/ e atualiza os links simbólicos. Aponte qualquer outro software para os caminhos live/. Assim, ele utiliza automaticamente os certificados renovados. Se copiar os ficheiros para outro local, estará a criar uma indisponibilidade para daqui a 90 dias.
O outro ficheiro importante é /etc/letsencrypt/renewal/example.com.conf. Ele regista como este certificado foi emitido, authenticator = apache, installer = apache e os domínios. Assim, a renovação pode repetir o processo sem intervenção, incluindo o recarregamento do Apache.
A renovação já está agendada; verifique-a, não a crie
Os certificados Let's Encrypt têm validade de 90 dias por definição, e o pacote apt já instalou a infraestrutura necessária: um temporizador systemd que executa o Certbot duas vezes por dia, em horários aleatórios, e renova qualquer certificado que expire nos 30 dias seguintes. Não adicione um cron por cima. Um segundo agendador não traz qualquer benefício e apenas aumenta o ruído nos logs e a exposição a limites de taxa.
systemctl list-timers certbot.timer
sudo certbot renew --dry-runO primeiro comando mostra o temporizador ativo, com um horário NEXT algures nas próximas 24 horas. O agendamento ocorre duas vezes por dia, com um atraso aleatório, por isso o horário exato é deliberadamente imprevisível. Na instalação por snap, o temporizador é snap.certbot.renew.timer. O teste a seco executa uma simulação completa da renovação no ambiente de staging do Let's Encrypt, com um desafio real, mas sem emitir um certificado e sem consumir limites de taxa. Um resultado correto termina com:
Congratulations, all simulated renewals succeeded:
/etc/letsencrypt/live/example.com/fullchain.pem (success)Se o teste a seco falhar, a renovação real daqui a ~60 dias falhará da mesma forma. Corrija o problema agora, enquanto o certificado atual ainda tem toda a validade pela frente. A causa mais comum é uma regra de firewall adicionada depois da emissão que voltou a bloquear a porta 80.
Verifique com curl e veja o que o cadeado deve indicar
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 comando deve devolver HTTP/1.1 301 Moved Permanently com um cabeçalho Location: https://example.com/. Esse é o redirecionamento instalado pelo Certbot. O segundo deve devolver HTTP/1.1 200 OK sem qualquer aviso de TLS do curl. O terceiro mostra o emissor, uma linha O = Let's Encrypt com um CN curto, como R12 ou E7, e notAfter aproximadamente 90 dias no futuro. Num navegador, verá o cadeado. Ao clicar nele, verá o mesmo emissor. Se o curl funcionar e o navegador mostrar um aviso, quase certamente está a consultar uma página em cache ou o hostname errado, não existe um problema com o certificado.
Vários sites: um certificado SAN ou um certificado por site
Ambas as opções funcionam e são renovadas da mesma forma. Para sites sem relação entre si no mesmo servidor, execute o comando de emissão uma vez por site. Cada site terá o seu próprio diretório em live/ e a sua própria configuração de renovação. Um problema num domínio nunca impede a renovação dos outros. Esta é a minha opção padrão.
Para um site com vários nomes, coloque-os num único certificado SAN. Um único certificado pode incluir até 100 nomes. Já fez isso acima com example.com e www.example.com. Para adicionar posteriormente um nome a um certificado existente, emita-o novamente, indicando o nome do certificado e a lista completa de nomes:
sudo certbot --apache --cert-name example.com -d example.com -d www.example.com -d blog.example.comO Certbot deteta a alteração do conjunto de domínios, pede a confirmação da expansão e substitui o certificado no mesmo local, em live/. Não é necessário alterar mais nada. A lista substitui a anterior; não é acrescentada a ela. Se omitir www desse comando, o novo certificado irá removê-lo silenciosamente.
Os curingas exigem DNS-01 e, normalmente, não precisa de um curinga
HTTP-01 não pode emitir *.example.com. Colocar um ficheiro num servidor Web prova o controlo de um nome de domínio, não de todo um espaço de nomes. Os curingas exigem o desafio DNS-01: o Certbot define um registo TXT em _acme-challenge.example.com. Na prática, isto significa um plugin certbot-dns-* com credenciais de API do seu fornecedor de DNS, ou editar manualmente os registos TXT em cada renovação com --manual (uma tarefa penosa; não planeie com base nela). O passo a passo completo, desde o funcionamento dos registos TXT até um plugin que renova sem intervenção, está em certificados curinga com Certbot através de DNS-01. Conselho direto: se tiver quatro subdomínios conhecidos, um certificado SAN que liste os quatro é mais simples do que um curinga e não exige chaves de API de DNS no servidor.
Modos de falha e as mensagens que verá
Certbot recusa-se a iniciar porque a configuração do Apache está inválida.
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 fazer qualquer alteração e termina se o próprio Apache tiver problemas. Os \n são literais porque o Certbot imprime a representação da exceção. Execute sudo apache2ctl configtest manualmente. O comando identifica o ficheiro e a linha. Normalmente, trata-se de um erro de digitação introduzido numa edição manual, de um SSLCertificateFile que aponta para um caminho inexistente ou de um módulo referenciado mas não ativado. Corrija o problema até o comando imprimir Syntax OK. Em seguida, execute novamente o Certbot.
Nenhum vhost corresponde ao domínio.
Unable to find a virtual host listening on port 80 which is currently the only challenge port.Esta é a falha de ServerName em falta mencionada anteriormente, detetada no momento da emissão. O Certbot procurou um ServerName/ServerAlias correspondente ao seu -d em todos os vhosts da porta 80 ativados e não encontrou nenhum. sudo apache2ctl -S mostra como o Apache encaminha efetivamente os pedidos. Adicione a linha ServerName ao vhost correto, recarregue a configuração e tente novamente. Um caso semelhante ocorre quando a validação chega ao vhost errado: a resposta ao desafio devolve Invalid response ... 404 porque outro site recebeu o pedido. O diagnóstico é o mesmo e a ferramenta também: apache2ctl -S.
A validação excede o tempo limite.
Certbot failed to authenticate some domains (authenticator: apache).
...
Detail: ...: Timeout during connect (likely firewall problem)O Let's Encrypt não conseguiu abrir uma ligação TCP à porta 80 no endereço anunciado pelo seu DNS. Por ordem de probabilidade: a firewall de rede do seu fornecedor, separada do ufw e configurada no painel de alojamento; um conjunto de regras do ufw que permite apenas a porta 443 ou apenas SSH; o DNS ainda a apontar para um servidor anterior; ou o problema de AAAA obsoleto, em que os servidores do Let's Encrypt tentam IPv6 mas o seu servidor só responde em IPv4. Teste a partir do exterior do VPS: curl -I http://example.com executado no seu computador reproduz o que o validador do Let's Encrypt vê.
As novas tentativas fizeram-no atingir um limite de utilização.
Error creating new order :: too many failed authorizations recently: see https://letsencrypt.org/docs/rate-limits/O Let's Encrypt permite 5 validações falhadas por nome de host, por conta e por hora. Desde a reformulação dos limites em 2025, trata-se de um conjunto de tokens que é reposto gradualmente, recuperando aproximadamente uma nova tentativa a cada 12 minutos. Repetir tentativas insistentemente contra uma firewall com problemas esgota-o rapidamente. Esperar resolve temporariamente, mas a correção real é comportamental: depois de qualquer falha, faça a depuração com o ambiente de staging até a validação ser bem-sucedida.
sudo certbot certonly --apache --dry-run -d example.com -d www.example.comObserve o certonly: --dry-run só é aceite pelos subcomandos certonly e renew, e a forma simples certbot --apache --dry-run recusa-se a executar, indicando --dry-run currently only works with the 'certonly' or 'renew' subcommands. A execução de teste valida contra o staging, que tem os seus próprios limites mais permissivos e não emite certificados reais. Assim, pode falhar nesse ambiente durante toda a tarde. Execute novamente o comando real apenas depois de a validação no staging ser bem-sucedida. Os outros limites — 50 certificados por domínio registado por semana e 5 duplicados do mesmo conjunto de nomes por semana — só serão atingidos se um script estiver a emitir certificados repetidamente num ciclo.
Quando o HTTPS estiver ativo, lembre-se de que o certificado protege o transporte, não o servidor. A porta 22 continua a receber tentativas de palavra-passe durante todo o dia. Associar esta configuração ao Fail2ban no Ubuntu 24.04 é o próximo passo natural, com uma duração aproximada de 30 minutos.
FAQ
Devo instalar o Certbot com snap ou apt para o Apache no Ubuntu 24.04?
Use apt. O Ubuntu 24.04 disponibiliza o Certbot 2.9.0, que é suficientemente atual para tudo o que é descrito neste guia, recebe atualizações de segurança através de unattended-upgrades e não requer snapd. Escolha snap apenas se precisar imediatamente da versão mais recente ou de um plugin DNS distribuído exclusivamente como snap. Se mudar, execute apt remove certbot python3-certbot-apache primeiro para que nunca coexistam dois agendadores de renovação.
Por que o Certbot mostra "Unable to find a virtual host listening on port 80"?
Porque não existe nenhum vhost da porta 80 ativado com um ServerName ou ServerAlias correspondente ao domínio indicado com -d. No Ubuntu, o vhost predefinido é distribuído com ServerName comentado. Execute sudo apache2ctl -S, localize ou crie o vhost que deve ser responsável pelo nome, adicione ServerName example.com, recarregue o Apache e execute o Certbot novamente.
Como corrijo "Timeout during connect (likely firewall problem)"?
O Let's Encrypt não conseguiu alcançar a porta 80 no endereço publicado pelo DNS. Verifique a firewall de rede no painel do fornecedor e também o ufw. Confirme que dig +short example.com devolve este VPS e elimine ou corrija qualquer registo AAAA obsoleto. A validação dá preferência ao IPv6 quando existe um registo desse tipo. Confirme a correção a partir de fora do servidor com curl -I http://example.com e faça um ensaio com sudo certbot certonly --apache --dry-run -d example.com antes da emissão efetiva.
O Certbot renova certificados automaticamente no Ubuntu 24.04?
Sim. O pacote apt instala certbot.timer, um temporizador systemd que é executado duas vezes por dia e renova qualquer certificado que expire nos 30 dias seguintes. Depois, recarrega o Apache. O snap usa snap.certbot.renew.timer para a mesma tarefa. Verifique com systemctl list-timers certbot.timer e faça um ensaio com sudo certbot renew --dry-run. Não adicione um cron próprio.
Como obtenho um certificado wildcard com o Certbot e o Apache?
Os certificados wildcard requerem o desafio DNS-01. O Certbot tem de criar um registo TXT em _acme-challenge.example.com. Para isso, é necessário um plugin certbot-dns-* com credenciais de API do fornecedor DNS. A alternativa --manual requer a edição manual dos registos TXT em cada renovação. Se tiver apenas alguns subdomínios conhecidos, é mais simples usar um certificado SAN que os liste explicitamente. Assim, as chaves da API DNS não precisam de ficar no servidor.