Módulo 7 · 7.3
https com o Let's Encrypt
Módulo 7: Domínio, servidor web e https · Tempo de leitura: 12 minutos
Objetivo de aprendizagem: Depois desta lição, saberá pedir com o certbot um certificado gratuito do Let's Encrypt para o nginx, redirecionar http para https, verificar a renovação automática e resolver os erros mais comuns num pedido.
Conceitos-chave: certificado, autoridade de certificação (CA), ACME, Let's Encrypt, validação de domínio, HTTP-01, DNS-01, TLS-ALPN-01, certbot, renovação, certbot renew --dry-run, período de validade, ARI, rate limits, staging, CAA, redirecionamento para https
Porquê https, e o que um certificado prova
Sem https, tudo o que circula entre o navegador e o servidor passa pela rede sem encriptação: palavras-passe, formulários, cookies. Qualquer pessoa no caminho (uma rede wifi pública, um router comprometido) pode ler ou alterar os dados. Por isso, os navegadores marcam os sites http como "não seguro", e algumas funcionalidades só funcionam através de https. Para um cofre de palavras-passe como o Vaultwarden (lição 9.4), o https é mesmo obrigatório.
O https utiliza TLS, e para isso o seu servidor precisa de um certificado: uma prova, assinada por uma autoridade de certificação (CA) em que os navegadores confiam, de que esta chave pertence a este nome. Um certificado comum prova apenas que quem o pediu controla o nome de domínio (validação de domínio). Não diz nada sobre quem é nem se é de confiança.
O Let's Encrypt é uma CA gratuita que emite apenas certificados validados por domínio, de forma totalmente automática através do protocolo ACME. Um programa no seu servidor (o cliente ACME) pede o certificado, prova que controla o nome, instala-o e renova-o a tempo. Esta lição utiliza o certbot, o cliente da EFF. O Caddy (lição 7.4) tem um cliente ACME incorporado.
Como se prova que controla o nome?
O Let's Encrypt conhece três tipos de desafios (challenges):
| Desafio | Como | Porta | Wildcard (*.example.com) |
|---|---|---|---|
| HTTP-01 | colocar um ficheiro em http://<naam>/.well-known/acme-challenge/ | 80 | não |
| DNS-01 | criar um registo TXT _acme-challenge.<naam> | nenhuma | sim |
| TLS-ALPN-01 | apresentar um certificado especial durante o handshake TLS | 443 | não |
Para um VPS comum com um site, o HTTP-01 é o mais simples. Para isso, é necessário que:
- o nome aponte para o seu servidor com A (e AAAA) (lição 7.1);
- a porta 80 esteja aberta para todo o mundo, mesmo que o seu site use apenas https. O Let's Encrypt valida apenas através da porta 80 e a partir de vários locais na internet; não é possível colocar esses endereços na sua firewall;
- o seu servidor responda da mesma forma por IPv4 e por IPv6. Se o nome tiver um registo AAAA, o Let's Encrypt tenta primeiro por IPv6. Só recorre ao IPv4 se o IPv6 não estabelecer qualquer ligação.
O DNS-01 é necessário para um certificado wildcard, ou quando o servidor não está acessível a partir do exterior. Nesse caso, o cliente ACME tem de conseguir alterar o seu DNS, normalmente através de uma chave de API do seu fornecedor de DNS. Essa chave pode alterar todo o seu DNS: guarde-a com o mesmo cuidado que uma palavra-passe.
Instalar o certbot
Os criadores do certbot recomendam o snap, porque tem sempre a versão mais recente. No Debian e no Ubuntu também pode instalá-lo simplesmente a partir do repositório de pacotes:
anna@web1:~$ sudo apt install certbot python3-certbot-nginxA versão da distribuição é mais antiga, mas recebe atualizações de segurança através do apt (lições 4.1 e 4.2), o que se ajusta ao resto deste curso. Escolha uma das duas, não ambas: duas instalações atrapalham-se mutuamente na renovação.
Pedir um certificado
Com o site da lição 7.2 já a funcionar na porta 80:
anna@web1:~$ sudo certbot --nginx -d example.com -d www.example.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address or hit Enter to skip.
(Enter 'c' to cancel):
...
Requesting a certificate for example.com and www.example.com
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-02-07.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.
Deploying certificate
Successfully deployed certificate for example.com to /etc/nginx/sites-enabled/example.com
Successfully deployed certificate for www.example.com to /etc/nginx/sites-enabled/example.com
Congratulations! You have successfully enabled HTTPS on https://example.com and https://www.example.com(A data e os pormenores são um exemplo.) O plug-in --nginx faz três coisas: prepara temporariamente o desafio, obtém o certificado e ajusta o seu server block com um bloco listen 443 ssl e um redirecionamento de http para https. Se preferir fazer isso pessoalmente, utilize certbot certonly --nginx e acrescente as linhas à sua configuração.
Alguns pontos a ter em atenção:
- Peça de uma só vez todos os nomes que pertencem ao site (
-dpor nome). Cada nome tem de apontar para o servidor; caso contrário, todo o pedido falha. - A chave privada (
privkey.pem) está em/etc/letsencrypt/live/e só pode ser lida pelo root. Não a copie para outros locais e nunca a coloque numa cópia de segurança que outras pessoas possam ler. - O endereço de e-mail é opcional. Desde junho de 2025, o Let's Encrypt já não envia e-mails quando um certificado está prestes a expirar. Por isso, tem de ser o próprio a monitorizar se a renovação é bem-sucedida (lição 8.3).
Redirecionar http para https
Depois do certbot, a sua configuração fica mais ou menos assim (simplificada; o certbot acrescenta comentários # managed by Certbot e por vezes linhas if):
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
root /var/www/example.com;
...
}O primeiro bloco redireciona tudo o que chega por http para o mesmo nome e o mesmo caminho por https, com um redirecionamento permanente (301). O ficheiro do desafio para a renovação continua a funcionar: o Let's Encrypt segue esse redirecionamento. O segundo bloco é o site propriamente dito. Se também quiser redirecionar www para o nome sem prefixo (ou o inverso), faça-o num bloco próprio, para que os visitantes vejam sempre um único nome.
Renovação: automática, e verificada
Atualmente, um certificado do Let's Encrypt é válido durante 90 dias. Esse prazo vai diminuir: o Let's Encrypt anunciou que o perfil predefinido passará a emitir certificados de 64 dias a partir de 10 de fevereiro de 2027 e de 45 dias a partir de 16 de fevereiro de 2028. Renovar manualmente não é, portanto, uma opção; tem de ser automático.
Na instalação, o certbot cria um temporizador do systemd (ou uma linha cron) que verifica duas vezes por dia se algum certificado precisa de ser renovado. Confirme que existe e teste a renovação com um pedido de ensaio:
anna@web1:~$ systemctl list-timers 'certbot*'
NEXT LEFT LAST PASSED UNIT ACTIVATES
Mon 2026-11-09 22:41:00 CET 9h left - - certbot.timer certbot.service
anna@web1:~$ sudo certbot renew --dry-run
...
Congratulations, all simulated renewals succeeded:
/etc/letsencrypt/live/example.com/fullchain.pem (success)Após a renovação, o nginx também tem de carregar o novo certificado. Com o plug-in do nginx, o certbot trata disso sozinho; se utilizar certonly, crie um deploy hook que recarregue o nginx, por exemplo um script executável em /etc/letsencrypt/renewal-hooks/deploy/ com systemctl reload nginx.
Os bons clientes ACME utilizam o ARI (ACME Renewal Information): o próprio Let's Encrypt indica quando um certificado deve ser renovado, por exemplo mais cedo se houver um problema com uma série de certificados. Por isso, mantenha o seu cliente atualizado.
Quando um pedido falha
| Mensagem (abreviada) | Causa | Solução |
|---|---|---|
Timeout during connect (likely firewall problem) | porta 80 fechada, ou o nome aponta para outro endereço | firewall (lição 5.2), A/AAAA (lição 7.1) |
Invalid response from http://.../.well-known/acme-challenge/...: 404 | responde outro servidor ou outro server block, muitas vezes por IPv6 | listen [::]:80, verificar o registo AAAA |
CAA record for example.com prevents issuance | um registo CAA só autoriza outra autoridade de certificação | ajustar o CAA (lição 7.1) |
too many certificates already issued | um rate limit | aguardar; testar com staging |
O Let's Encrypt tem rate limits para evitar abusos. Os mais importantes: no máximo 50 certificados novos por domínio registado a cada 7 dias, no máximo 5 certificados para exatamente o mesmo conjunto de nomes a cada 7 dias, e no máximo 5 validações falhadas por nome por hora. Quem está a fazer experiências e repete o pedido vezes sem conta depressa atinge esses limites. Por isso, teste com o ambiente de staging, que tem limites muito mais largos mas emite certificados em que os navegadores não confiam:
anna@web1:~$ sudo certbot certonly --nginx --staging -d test.example.comSe funcionar aí, peça então o certificado verdadeiro.
No AlmaLinux e no Rocky Linux
Nestes sistemas, o certbot vem do EPEL (dnf install certbot python3-certbot-nginx) ou como snap. O plug-in e os comandos são os mesmos. Lembre-se do firewalld (--add-service=http --add-service=https) e do SELinux se os certificados estiverem num local pouco habitual.
Na prática
Num pacote de alojamento, o painel trata do certificado por si (na WebOké e noutras empresas de alojamento com DirectAdmin, cPanel ou Plesk). Num VPS, é o próprio que o faz, com o certbot, o Caddy ou o cliente ACME que acompanha o seu software. Isto aplica-se a qualquer fornecedor.
Resumo
- Um certificado do Let's Encrypt prova que controla o nome; o certbot pede-o, instala-o e renova-o através do ACME.
- O HTTP-01 precisa da porta 80 aberta, para todos, e da mesma resposta por IPv4 e IPv6; o DNS-01 serve para wildcards.
certbot --nginx -d ... -d ...trata do certificado e do redirecionamento para https; peça todos os nomes de um site de uma só vez.- Os certificados são atualmente válidos durante 90 dias e esse prazo vai diminuir; verifique o temporizador e
certbot renew --dry-run, e monitorize pessoalmente a data de expiração. - Teste com
--stagingpara evitar os rate limits; tenha atenção ao CAA.
Questionário
Exercício
Exercício Z7.3: https com um certificado válido. Peça um certificado para o seu site (com o certbot ou o Caddy), redirecione http para https e teste a renovação com certbot renew --dry-run (no Caddy: verifique nos registos se o certificado foi obtido). Indique o nome do seu site. O programa estabelece uma ligação TLS à porta 443 e verifica se o certificado é válido, se foi assinado por uma autoridade de certificação de confiança e se abrange o seu nome; em seguida, pede http://<naam>/ para ver se redireciona para https. Além disso, indica quando o seu certificado expira e como está organizada a renovação no seu caso.
Para saber mais
- Ativar, renovar e resolver problemas do certificado SSL
- Curso gratuito de DNS 5.2: CAA: quem pode emitir certificados?
- Let's Encrypt, Challenge Types: https://letsencrypt.org/docs/challenge-types/
- Let's Encrypt, Rate Limits: https://letsencrypt.org/docs/rate-limits/
- Let's Encrypt, Decreasing Certificate Lifetimes to 45 Days: https://letsencrypt.org/2025/12/02/from-90-to-45
- Instruções do Certbot (nginx): https://certbot.eff.org/instructions?ws=nginx&os=snap
