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 arrancar
- O Apache já serve o seu site por HTTP simples. O plugin do 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 à sua máquina através da Internet: não funciona num homelab atrás de NAT sem reencaminhamento de portas, nem com nomes
.local. O HTTP-01 pode validar um IP simples, mas o Let's Encrypt só emite certificados para IP através do seu perfilshortlivedopcional (com validade de 160 horas), e o Certbot 2.9.0 instalado pelo apt não consegue pedir perfis ACME nem endereços IP. Por isso, este guia precisa de um nome de domínio.dig +short example.comtem de devolver o endereço do seu VPS. Se alterou o DNS na última hora, aguarde até expirar o TTL do registo antigo antes de emitir o certificado. - Se existir um registo AAAA, tem de estar correto. O Let's Encrypt tenta sempre primeiro IPv6 quando é publicado um registo AAAA. Se essa ligação exceder o tempo limite, tenta novamente através de IPv4, mas nenhum outro erro tem essa segunda oportunidade: um AAAA num endereço que recusa ligações, ou num servidor ativo que não é este, faz a validação falhar mesmo quando
curlfunciona 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 fornecedor; a maioria dos painéis de alojamento tem uma segunda firewall que o sistema operativo nunca vê. 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 processo demora quinze minutos, dez dos quais a ler.
Certbot via Snap ou apt? No 24.04, o apt finalmente é uma opção adequada
O Certbot passou a ser distribuído via snap há anos por um bom motivo: os pacotes das distribuições ficaram desatualizados. O Ubuntu 20.04 incluía o Certbot 0.40 e nunca atualizou essa versão, e o projeto acabou por se cansar de corrigir bugs com cinco anos. No 24.04, esse motivo deixou de existir: o arquivo inclui o Certbot 2.9.0, uma versão lançada em fevereiro de 2024 da linha moderna 2.x, e o unattended-upgrades instala qualquer atualização de segurança que o Ubuntu publique para esse pacote. Entretanto, o upstream avançou para a série 5.x, mas nada neste guia precisa dessa versão. A minha recomendação para este sistema operativo é usar o apt. 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 edita 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 escolha certa em dois casos: quando pretende a versão mais recente do Certbot no próprio dia em que é lançada, ou quando precisa de um plugin DNS distribuído apenas como snap. Vários plugins de 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/certbotIndependentemente da opção escolhida, nunca execute as duas. Duas instalações significam dois agendadores de renovação a competir por /etc/letsencrypt, e o certbot que a sua shell encontra em PATH pode não ser o que gere os seus certificados. A linha apt remove acima nã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 (a Let's Encrypt já não o armazena na sua conta ACME nem envia avisos de expiração, por isso cabe-lhe monitorizar as renovações), a aceitação dos termos da Let's Encrypt e a indicação sobre partilhar o endereço de e-mail com a EFF. Já não existe uma pergunta sobre o redirecionamento: desde o Certbot 1.0, o instalador do Apache redireciona HTTP para HTTPS por predefinição (a própria pergunta foi removida na versão 1.4), que é o comportamento pretendido. Use --no-redirect apenas se precisar realmente de continuar a servir conteúdo por HTTP simples.
O resultado correto é semelhante ao seguinte. Leia a mensagem com atenção:
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 2027-01-09.
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 ativo; escreveu example.com-le-ssl.conf, uma cópia do seu vhost em *:443 com SSLEngine on e os caminhos dos certificados; ativou essa configuração; 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 o equivalente SSL fica ao lado dele, onde pode consultar cada linha adicionada.
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 recrie
Os certificados Let's Encrypt têm atualmente uma 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 dentro de 30 dias. Não adicione um cron job por cima; um segundo agendador não traz qualquer benefício e apenas aumenta o ruído nos logs e a exposição aos limites de frequência. A Let's Encrypt anunciou que, a partir de February 10, 2027, os novos certificados terão, por predefinição, uma validade de 64 dias. A janela de 30 dias continua a funcionar com esses certificados; a renovação ocorrerá por volta do dia 34 em vez do dia 60. Portanto, não é necessário alterar nada neste servidor.
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, pelo que a hora exata é deliberadamente imprevisível (na instalação por snap, o temporizador é snap.certbot.renew.timer). A execução de teste simula uma renovação completa no ambiente de staging da Let's Encrypt, com um desafio real, mas sem emitir um certificado e sem consumir limites de frequência. Um resultado correto termina com:
Congratulations, all simulated renewals succeeded:
/etc/letsencrypt/live/example.com/fullchain.pem (success)Se a execução de teste 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 confirme 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 YE1 ou YE2 (chaves ECDSA), ou YR1 ou YR2 (chaves RSA), e uma validade notAfter aproximadamente 90 dias à frente. Um certificado emitido antes de a Let's Encrypt retirar os seus intermediários mais antigos ainda pode mostrar um CN como R12 ou E7 até à renovação seguinte. Isso não é um erro. No navegador, aparece o cadeado, e ao clicar nele é mostrado o mesmo emissor. Se o curl funcionar e o navegador apresentar um aviso, quase certamente está a consultar uma página em cache ou o nome de host errado, e 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á
O 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 alterar qualquer coisa e termina se o próprio Apache tiver problemas. Os \ns são literais porque o Certbot imprime a representação da exceção. Execute sudo apache2ctl configtest manualmente: o comando indica o ficheiro e a linha. Normalmente, trata-se de um erro de digitação introduzido durante a edição manual, de um SSLCertificateFile que aponta para um caminho que já não existe ou de um módulo referenciado mas não ativado. Corrija o problema até o comando imprimir Syntax OK e 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 mencionada anteriormente, detetada no momento da emissão. O Certbot procurou em todos os vhosts da porta 80 ativados um ServerName/ServerAlias correspondente ao seu -d e não encontrou nenhum. sudo apache2ctl -S mostra como o Apache encaminha efetivamente os pedidos. Adicione a linha ServerName ao vhost correto, recarregue o Apache 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; ou o DNS ainda aponta para um servidor anterior. Um registo AAAA obsoleto, por si só, normalmente não causa este problema, porque, quando a tentativa por IPv6 excede o tempo limite, o Let's Encrypt tenta novamente através de IPv4. Problemas com AAAA tendem a surgir como Connection refused ou Invalid response provenientes do servidor errado. Teste a partir de fora do VPS: curl -I http://example.com executado no seu portátil 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 (5) for "example.com" in the last 1h0m0s, retry after ... UTC: see https://letsencrypt.org/docs/rate-limits/...O Let's Encrypt permite 5 validações falhadas por nome de anfitrião, por conta e por hora, através de um conjunto de créditos que se repõe e recupera aproximadamente uma tentativa a cada 12 minutos. Repetir agressivamente as tentativas contra uma firewall inválida esgota-o rapidamente. Esperar funciona, mas a correção real é comportamental: depois de qualquer falha, faça a depuração com o ambiente de staging até ter sucesso.
sudo certbot certonly --apache --dry-run -d example.com -d www.example.comTenha em atenção o certonly: --dry-run só é aceite pelos subcomandos certonly e renew, e a forma simples certbot --apache --dry-run recusa-se a executar, informando-o de --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 generosos e não emite certificados reais, pelo que pode falhar nesse ambiente durante toda a tarde. Execute novamente o comando real apenas depois de a validação no staging passar. 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.
Depois de o HTTPS estar ativo, lembre-se de que o certificado protege o transporte, não o servidor: a porta 22 continua a receber tentativas de adivinhar palavras-passe durante todo o dia. Combinar isto com Fail2ban no Ubuntu 24.04 é o próximo passo natural para os 30 minutos seguintes.
FAQ
Devo instalar o Certbot com snap ou apt para Apache no Ubuntu 24.04?
Use apt. O Ubuntu 24.04 inclui o Certbot 2.9.0, que é suficientemente atual para tudo neste guia, recebe quaisquer atualizações de segurança publicadas pelo Ubuntu através de unattended-upgrades e não requer snapd. Escolha o snap apenas se precisar imediatamente da versão mais recente ou de um plugin DNS distribuído exclusivamente como snap. Se mudar, execute primeiro apt remove certbot python3-certbot-apache para evitar que coexistam dois agendadores de renovação.
Por que razão o Certbot apresenta "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. O vhost predefinido do Ubuntu inclui ServerName comentado. Execute sudo apache2ctl -S, localize ou crie o vhost que deve assumir esse nome, adicione ServerName example.com, recarregue o Apache e execute novamente o Certbot.
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 seu DNS. Verifique a firewall de rede ao nível do painel do seu fornecedor e também o ufw. Confirme que dig +short example.com devolve este VPS e corrija ou elimine qualquer registo AAAA obsoleto, porque a validação tenta primeiro IPv6 e só recorre a IPv4 depois de ocorrer um timeout. Confirme a correção a partir do exterior 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 real.
O Certbot renova automaticamente os certificados 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 job 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. Isso requer um plugin certbot-dns-* com credenciais de API do seu fornecedor de 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 ficam no servidor.