Certbot wildcard com DNS-01: emitir e renovar
Emita wildcard com Certbot pelo DNS-01: publique o TXT em _acme-challenge, instale o plugin DNS correto e mantenha a renovação automática pela API.
Por que um certificado wildcard precisa de DNS-01
Um certificado wildcard abrange todos os subdomínios de primeiro nível de um domínio: *.example.com corresponde a app.example.com, blog.example.com e qualquer outro nome com um nível. A Let's Encrypt emite certificados wildcard apenas através do desafio DNS-01. Por isso, o Certbot tem de provar o controlo do DNS do domínio publicando um registo TXT em _acme-challenge.example.com. O desafio HTTP-01 não pode ser utilizado, porque servir um ficheiro com um token prova apenas o controlo de um hostname: aquele a partir do qual o servidor de validação obteve o ficheiro. Um wildcard é uma declaração sobre todos os nomes possíveis sob o domínio. O único registo público que representa todo esse namespace é o próprio DNS.
Este requisito determina todo o restante desta página. Para passar o DNS-01, tem de conseguir criar registos TXT na zona do domínio, manualmente ou através da API (application programming interface) do seu fornecedor de DNS. O método manual funciona uma vez e depois falha na renovação, por um motivo concreto explicado abaixo. O método através da API, usando um plugin DNS do Certbot, renova os certificados sem intervenção. É esta a configuração que deve utilizar no final.
Este é o capítulo sobre certificados wildcard dos nossos guias do Certbot. Os certificados comuns para um único hostname, a configuração do servidor web e as regras da porta 80 são abordados em Certbot com nginx no Ubuntu 24.04 e Certbot com Apache no Ubuntu 24.04.
Como funciona o registo TXT _acme-challenge
Quando o Certbot solicita *.example.com, o Let's Encrypt responde com um token aleatório. O Certbot combina esse token com a chave da conta ACME (ambiente de gestão automática de certificados), calcula um hash do resultado com SHA-256 e produz um valor de texto curto. Esse valor tem de aparecer como registo TXT em _acme-challenge.example.com. Em seguida, o Let's Encrypt consulta os servidores de nomes autoritativos do seu domínio a partir da própria infraestrutura. Se o registo que lê corresponder ao valor esperado, fica provado que controla a zona, e o controlo da zona é aceite como controlo de todos os nomes nela incluídos.
Dois detalhes causam a maioria das falhas:
- Solicitar
example.come*.example.comno mesmo certificado significa dois desafios separados, e ambos os registos TXT ficam no mesmo nome,_acme-challenge.example.com. Ambos têm de existir ao mesmo tempo. Adicionar o segundo registo está correto; substituir o primeiro pelo segundo faz o primeiro desafio falhar. - A validação consulta os seus servidores autoritativos, mas os painéis de controlo dos fornecedores podem demorar um minuto ou mais a publicar um novo registo nesses servidores. Verifique externamente antes de permitir que a validação seja executada:
dig +short TXT _acme-challenge.example.com @1.1.1.1Quando esse comando mostrar o valor solicitado pelo Certbot, a validação poderá ser bem-sucedida. Quando não mostrar nada, aguarde e execute-o novamente.
Ver o processo uma vez: modo manual
O modo manual exige que edite o DNS por conta própria. Esta é a melhor forma de compreender o mecanismo antes de o automatizar:
sudo certbot certonly --manual --preferred-challenges dns -d example.com -d '*.example.com'As aspas à volta do wildcard impedem que a shell trate * como um padrão de nomes de ficheiros. O Certbot pausa e apresenta instruções:
Please deploy a DNS TXT record under the name:
_acme-challenge.example.com.
with the following value:
Jx9mQ2wLr8vTn5cKp0aYdG3hB7fZs4eN1oiRuXqMk6ECrie esse registo TXT no painel do seu fornecedor de DNS, confirme que está visível com o comando dig acima e só depois prima Enter. Como esta execução solicita o domínio base e o wildcard, o Certbot apresenta dois pedidos. Mantenha ambos os registos no DNS até a emissão terminar. Em caso de sucesso, são apresentadas as linhas habituais:
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/example.com/fullchain.pemPor que o modo manual não consegue renovar sozinho
Cada renovação é um novo desafio com um novo token, por isso o valor TXT muda todas as vezes. O registo que colou hoje será inútil daqui a 60 dias. O temporizador de renovação executa o Certbot sem intervenção duas vezes por dia, e não há ninguém ao teclado para colar o novo valor. Por isso, um certificado emitido manualmente falha a renovação com este erro exato:
Failed to renew certificate example.com with error: The manual plugin is not
working; there may be problems with your existing configuration.
The error was: PluginError('An authentication script must be provided with
--manual-auth-hook when using the manual plugin non-interactively.')Pode cumprir esse requisito escrevendo scripts --manual-auth-hook que chamem a API do seu fornecedor de DNS, mas, nesse momento, estará a recriar manualmente um plugin de DNS. Use o modo manual para aprender o processo ou para uma emissão pontual real num domínio cujo DNS ainda não consegue automatizar. Defina um lembrete bastante antes do dia 90, porque o Let's Encrypt já não envia emails de expiração. Em todos os outros casos, use um plugin.
A rota do plugin: certbot-dns-cloudflare no Ubuntu 24.04
Um plugin DNS armazena uma credencial de API do seu fornecedor DNS e executa todo o processo dos registos TXT, tanto na emissão como em cada renovação. O Cloudflare é usado como exemplo porque é o plugin de fornecedor de que a maioria dos utilizadores precisa e está disponível nos pacotes do Ubuntu.
Os nossos guias do Certbot recomendam os pacotes apt no Ubuntu 24.04, e essa recomendação também se aplica ao Cloudflare:
sudo apt update
sudo apt install certbot python3-certbot-dns-cloudflareUma nota importante sobre versões. O repositório do 24.04 inclui este plugin na versão 2.0.0, juntamente com o Certbot 2.9.0; apt policy python3-certbot-dns-cloudflare mostra a sua versão. A diferença não causa problemas, e os tokens de API com permissões limitadas funcionam porque a biblioteca python3-cloudflare subjacente no 24.04 está na versão 2.11.1, acima da versão 2.3.1 de que o plugin precisa para suportar tokens. Nas versões mais antigas do Ubuntu, essa biblioteca era demasiado antiga para suportar tokens. É daí que vêm os avisos encontrados online sobre o plugin apt obrigar ao uso da Global API Key. No 24.04, esses avisos já não se aplicam.
No painel do Cloudflare, crie um token de API com permissões limitadas, não a Global API Key: My Profile, depois API Tokens e, por fim, Create Token, com a única permissão Zone / DNS / Edit, limitada à zona para a qual está a emitir o certificado. Guarde-o num ficheiro que apenas o root possa ler:
sudo mkdir -p /root/.secrets
sudo tee /root/.secrets/cloudflare.ini > /dev/null <<'EOF'
dns_cloudflare_api_token = paste_your_scoped_token_here
EOF
sudo chmod 600 /root/.secrets/cloudflare.iniO Certbot verifica o modo do ficheiro e avisa sobre Unsafe permissions on credentials configuration file se este puder ser lido por outros utilizadores. Agora emita o certificado:
sudo certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /root/.secrets/cloudflare.ini \
-d example.com -d '*.example.com'O plugin cria os registos TXT através da API, aguarda um breve período de propagação, permite a execução da validação e elimina os registos novamente. Se os servidores de nomes da sua zona demorarem a detetar as alterações, aumente o tempo de espera com --dns-cloudflare-propagation-seconds 60. O certificado fica disponível em /etc/letsencrypt/live/example.com/, e deve configurar o nginx ou o Apache para usar fullchain.pem e privkey.pem, exatamente como mostrado nos guias base, incluindo o deploy hook.
Se o plugin do seu provedor não estiver no apt
O arquivo 24.04 só inclui plugins para alguns provedores, entre eles Cloudflare, Route 53, DigitalOcean e a interface RFC 2136 genérica. Execute apt search certbot-dns para ver a lista. Se o seu provedor não estiver incluído, este é o único ponto em que a recomendação de priorizar o apt muda: instale o Certbot e o plugin a partir do snap e remova primeiro o Certbot do apt, para que dois temporizadores de renovação nunca disputem /etc/letsencrypt:
sudo apt remove certbot python3-certbot-dns-cloudflare
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo snap set certbot trust-plugin-with-root=ok
sudo snap install certbot-dns-yourproviderUm plugin do snap só se conecta ao Certbot do snap. Ele não pode ampliar o Certbot do apt, por isso as duas instalações não devem coexistir. Se o seu provedor de DNS não oferecer uma API, as opções realistas são transferir o DNS do domínio para um provedor que ofereça uma, ou executar o seu próprio servidor de nomes e apontar o plugin rfc2136 para ele.
Renovação: prove agora, não daqui a 60 dias
O Certbot regista como cada certificado foi emitido em /etc/letsencrypt/renewal/example.com.conf, incluindo authenticator = dns-cloudflare e o caminho das credenciais. Assim, o temporizador padrão, executado duas vezes por dia, renova-o sem intervenção. Teste todo o processo no ambiente de staging:
sudo certbot renew --dry-runUm resultado bem-sucedido significa que a credencial funciona e que a validação é concluída de ponta a ponta. A renovação real daqui a 60 dias seguirá o mesmo caminho. Vale a pena tratar hoje de dois pontos. Primeiro, um certificado renovado no disco não produz qualquer efeito até o servidor Web o recarregar. Por isso, configure o deploy hook descrito nos guias de nginx e Apache. Segundo, proteja o ficheiro de credenciais: qualquer pessoa que consiga lê-lo pode editar a sua zona DNS. Isso é suficiente para redirecionar o seu correio ou concluir desafios DNS-01 próprios. Mantenha-o com o modo 600 em /root, limite o token a uma zona e faça a rotação se suspeitar que alguma credencial foi exposta.
Quando não é necessário um wildcard
Um wildcard é a ferramenta certa para muitos subdomínios ou para subdomínios que não é possível prever. Não deve ser a opção padrão em todos os outros casos.
- Um subdomínio ou alguns subdomínios conhecidos: um certificado SAN (subject alternative name) normal é mais simples.
certbot --nginx -d example.com -d www.example.com -d app.example.comcobre até 100 nomes através de HTTP-01 simples, e nenhuma credencial da API DNS fica no servidor. - Um wildcard corresponde exatamente a um label.
*.example.comnão cobre oexample.comsimples. Por isso, os comandos acima solicitam ambos. Também não cobrea.b.example.com; para isso, seria necessário*.b.example.com. - Uma única chave privada é usada por todos os subdomínios. Se a máquina que a contém for comprometida, todos os nomes abrangidos pelo wildcard serão afetados ao mesmo tempo.
- Se o Traefik terminar o TLS (transport layer security) dos seus contentores, não precisa de incluir o Certbot: o Traefik solicita os próprios certificados wildcard através de DNS-01, usando o mesmo tipo de token do provedor.
O wildcard é realmente útil para subdomínios por cliente ou por aplicação, criados mais rapidamente do que seria conveniente voltar a emitir certificados, e para hosts internos sem a porta pública 80, como serviços acessíveis apenas através de uma VPN WireGuard. O DNS-01 nunca se liga ao host que está a ser certificado. Assim, até uma máquina totalmente privada pode ter um certificado confiado publicamente.
FAQ
O Certbot pode emitir um certificado wildcard com HTTP-01?
Não. O HTTP-01 prova o controlo de um hostname, porque o servidor de validação obtém um ficheiro de token desse nome exato. Um wildcard abrange todos os nomes do domínio, por isso o Let's Encrypt exige o desafio DNS-01, e os autenticadores --nginx, --apache, --webroot e --standalone são todos baseados em HTTP. A única opção é criar um registo TXT em _acme-challenge.example.com, manualmente ou através de um plugin DNS.
Um certificado wildcard abrange o domínio raiz?
Não. O wildcard corresponde exatamente a um label, por isso *.example.com abrange www.example.com, mas não example.com sem subdomínio, nem a.b.example.com. Peça ambos os nomes no mesmo certificado com -d example.com -d '*.example.com'. Isso cria dois desafios, e ambos os registos TXT ficam no mesmo nome _acme-challenge.example.com. Adicione o segundo registo sem eliminar o primeiro.
Porque é que o meu certificado wildcard não é renovado automaticamente?
Porque foi emitido com --manual. Cada renovação requer um valor TXT completamente novo, e o timer não interativo não tem como o inserir. Por isso, a renovação termina com o erro An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively. Emita novamente o certificado com um plugin DNS, como certbot-dns-cloudflare, ou forneça os scripts --manual-auth-hook e --manual-cleanup-hook para editarem o registo através da API do seu fornecedor.
Quanto tempo demora o registo TXT _acme-challenge a aparecer?
Depende do seu fornecedor de DNS: pode demorar desde alguns segundos até vários minutos. A validação consulta os servidores autoritativos da sua zona, por isso verifique com dig +short TXT _acme-challenge.example.com @1.1.1.1 e aguarde até o valor esperado aparecer antes de continuar uma execução manual. Com um plugin, aumente o tempo de espera integrado através da opção de propagação do plugin, por exemplo --dns-cloudflare-propagation-seconds 60, se a validação indicar que o registo não foi encontrado.
Um certificado wildcard é menos seguro do que um certificado normal?
A criptografia é idêntica. As diferenças são operacionais: uma única chave privada abrange todos os subdomínios, por isso uma violação pode afetar uma área maior. Além disso, a credencial da API DNS exigida pela automatização é um segredo sensível armazenado no servidor. Se executar apenas alguns subdomínios conhecidos, um certificado SAN evita ambos os problemas. É precisamente nessa situação que este guia recomenda não utilizar um wildcard.