NoctisNode
← GuiasSegurança2026-10-2310 min

HTTPS automático no Caddy: como funciona o TLS automático e como resolver falhas

O Caddy obtém e renova certificados TLS via ACME para cada domínio da sua configuração. Entenda HTTP-01, TLS-ALPN-01, wildcards com DNS-01, TLS on-demand e as falhas mais comuns.

Resposta curta: o Caddy ativa HTTPS automaticamente para qualquer endereço de site que seja um nome de domínio público. Ele solicita um certificado via ACME (Let's Encrypt ou ZeroSSL por padrão), prova o controle do domínio pelo desafio HTTP-01 ou TLS-ALPN-01 nas portas 80 e 443, redireciona HTTP para HTTPS e renova o certificado antes que expire, sem nenhuma configuração extra.

Um reverse proxy Caddy é simplesmente o Caddy terminando essa conexão HTTPS e encaminhando a requisição para um app em outra porta, container ou host com a diretiva `reverse_proxy`. Essa combinação — TLS mais proxy em poucas linhas — é o principal motivo pelo qual as pessoas o escolhem.

Reverse proxy com SSL em três linhas

Com o DNS apontando para o servidor e as portas 80 e 443 acessíveis, este Caddyfile é um reverse proxy HTTPS completo para dois hostnames. O Caddy obtém certificados para os dois nomes na inicialização, serve HTTP/1.1, HTTP/2 e HTTP/3 e repassa `X-Forwarded-For`, `X-Forwarded-Proto` e `X-Forwarded-Host` ao backend. A opção `email` é opcional, mas permite que a CA entre em contato sobre certificados expirando ou revogados.

A instalação pelo repositório apt oficial e o básico de systemd estão no guia de reverse proxy com Caddy; para containers, veja Caddy como reverse proxy no Docker. Aplique as alterações com `sudo systemctl reload caddy`.

# /etc/caddy/Caddyfile
{
	email [email protected]
}

example.com, www.example.com {
	reverse_proxy 127.0.0.1:8080
}

Como o TLS automático do Caddy funciona por dentro

Quando o Caddy carrega uma configuração, ele reúne todos os hostnames dos endereços de site e decide quem deve emitir cada certificado. Domínios públicos vão para os emissores ACME públicos; `localhost`, endereços IP e nomes apenas internos recebem certificados da CA local do próprio Caddy (o mesmo que escrever `tls internal`). Certificados, chaves e a conta ACME ficam no diretório de dados do Caddy: `/var/lib/caddy/.local/share/caddy` no pacote apt, `/data` na imagem Docker oficial.

A renovação acontece em segundo plano bem antes do vencimento, e o Caddy faz stapling das respostas OCSP quando a CA oferece suporte. Se a emissão falhar, o Caddy tenta de novo com backoff exponencial e usa o endpoint de staging da CA nas novas tentativas para não queimar os rate limits de produção. Várias instâncias do Caddy que compartilham o mesmo armazenamento se coordenam para que só uma solicite cada certificado.

DesafioO que a CA verificaRequisitosWildcards?
HTTP-01Um token servido em `http://domain/.well-known/acme-challenge/`Porta 80 acessível pela internetNão
TLS-ALPN-01Um certificado especial apresentado num handshake TLSPorta 443 acessível pela internetNão
DNS-01Um registro TXT em `_acme-challenge.domain`Token de API do provedor de DNS e um build do Caddy com o módulo desse provedorSim

Certificados wildcard com DNS-01

Certificados wildcard como `*.example.com` só podem ser emitidos pelo desafio DNS-01. O binário padrão do Caddy não inclui plugins de provedores de DNS, então você gera um build com o xcaddy (ou escolhe o provedor na página oficial de download) e fornece ao Caddy um token de API limitado à edição do DNS daquela zona. O DNS-01 também funciona quando as portas 80 e 443 não estão acessíveis pela internet, por exemplo num servidor apenas interno.

Mantenha o token fora do Caddyfile: coloque-o num arquivo de ambiente usado pela unit do systemd (`sudo systemctl edit caddy` e depois `EnvironmentFile=/etc/caddy/caddy.env` em `[Service]`) e restrinja o arquivo com `chmod 600`.

# Build Caddy with a DNS provider module (example: Cloudflare)
xcaddy build --with github.com/caddy-dns/cloudflare

# Caddyfile: one wildcard certificate for all subdomains
*.example.com {
	tls {
		dns cloudflare {env.CF_API_TOKEN}
	}

	@app host app.example.com
	handle @app {
		reverse_proxy 127.0.0.1:3000
	}

	handle {
		respond "Unknown host" 404
	}
}

TLS on-demand e staging

O TLS on-demand faz o Caddy obter um certificado durante o primeiro handshake TLS para um hostname que ele ainda não conhece. Ele foi pensado para plataformas em que os clientes apontam os próprios domínios para o seu servidor. Configure sempre o endpoint `ask`: o Caddy o chama com `?domain=name` e só prossegue com uma resposta 200. Sem isso, qualquer pessoa poderia apontar nomes aleatórios para o seu IP e fazer você estourar os rate limits.

Enquanto estiver testando, mude para a CA de staging do Let's Encrypt com a opção global `acme_ca`. Os certificados de staging não são confiáveis para os navegadores, mas os limites são muito mais altos, então você pode quebrar e consertar à vontade. Ao terminar, remova a opção e, se quiser, apague os certificados de staging do diretório de dados.

{
	on_demand_tls {
		ask http://127.0.0.1:5555/allowed
	}
}

https:// {
	tls {
		on_demand
	}
	reverse_proxy 127.0.0.1:8080
}

# Global options block for testing
{
	email [email protected]
	# Test against Let's Encrypt staging; remove when everything works
	acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
}

Falhas comuns de TLS no Caddy e como corrigi-las

  1. 01.DNS não apontado: o registro A ou AAAA está faltando, ainda aponta para um servidor antigo ou está em cache. Um registro AAAA desatualizado é uma armadilha clássica, porque a CA prefere IPv6 quando ele existe. Verifique os dois com `dig`.
  2. 02.Porta 80 ou 443 fechada: o firewall do host, um firewall de nuvem ou um roteador bloqueia o tráfego de entrada, e nem o HTTP-01 nem o TLS-ALPN-01 conseguem concluir. Abra 80/tcp e 443/tcp (e 443/udp para HTTP/3).
  3. 03.Porta já em uso: Apache, nginx ou outro container está vinculado à 80 ou à 443, e o Caddy não consegue escutar. Pare o outro serviço ou coloque-o atrás do Caddy.
  4. 04.Proxy de CDN na frente: um proxy no estilo "nuvem laranja" termina o TLS antes do Caddy, o que pode quebrar o TLS-ALPN-01. Use DNS-01 ou deixe o registro como DNS-only durante a emissão.
  5. 05.Rate limits: tentativas fracassadas repetidas ou apagar o diretório de dados fazem você atingir os limites da CA (o Let's Encrypt limita validações fracassadas por hostname por hora e certificados duplicados por semana). Corrija a causa raiz, use staging e mantenha o diretório de dados persistente.
  6. 06.Registro CAA: um registro CAA que só permite outra CA bloqueia a emissão. Permita `letsencrypt.org` e `sectigo.com` (usado pela ZeroSSL) ou remova a restrição.
# Does the name resolve to this server (both IPv4 and IPv6)?
dig +short A example.com
dig +short AAAA example.com
curl -4 -s https://ifconfig.me ; echo

# Are ports 80 and 443 open in the host firewall?
sudo ufw status
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 443/udp

# Is something else already bound to 80/443?
sudo ss -ltnp '( sport = :80 or sport = :443 )'

# What does Caddy say?
sudo journalctl -u caddy --no-pager -n 100

HTTPS também até o backend

A maioria dos backends no mesmo host fala HTTP simples em localhost, e isso está ok. Quando o upstream fica em outra máquina ou exige TLS, use um upstream `https://` e diga ao Caddy qual nome verificar e em qual CA confiar. Evite `tls_insecure_skip_verify` fora de testes rápidos, porque ele remove a proteção contra interceptação entre o proxy e o backend. Para tráfego entre servidores, um túnel WireGuard privado costuma ser mais simples do que gerenciar certificados de backend.

Num VPS NoctisNode com root completo e um endereço IPv4 dedicado, a configuração habitual é: apontar um registro A (sem AAAA, a menos que o servidor tenha IPv6) para o servidor, abrir 80 e 443 e deixar o Caddy cuidar do resto. Se você precisa encaminhar tráfego que não é HTTP, veja proxy TCP e SSH com Caddy.

example.com {
	reverse_proxy https://10.0.0.5:8443 {
		transport http {
			tls_server_name backend.internal
			tls_trust_pool file /etc/caddy/backend-ca.pem
		}
	}
}

Perguntas frequentes

QO que é um reverse proxy Caddy?

AÉ o servidor web Caddy aceitando conexões de clientes, normalmente terminando o HTTPS, e encaminhando as requisições para um ou mais serviços de backend com a diretiva `reverse_proxy`. O Caddy obtém e renova automaticamente os certificados TLS para isso.

QO Caddy renova os certificados automaticamente?

ASim. O Caddy renova os certificados em segundo plano bem antes do vencimento e os recarrega sem reiniciar, desde que o domínio continue resolvendo para o servidor e as portas do desafio continuem acessíveis.

QPor que o Caddy não está conseguindo um certificado?

AAs causas mais comuns são registros DNS apontando para outro lugar (inclusive um registro AAAA desatualizado), portas 80 e 443 bloqueadas, outro programa usando essas portas ou rate limits após falhas repetidas. `journalctl -u caddy` mostra o erro ACME exato.

QO Caddy consegue emitir um certificado wildcard?

ASim, mas só pelo desafio DNS-01, que exige um build do Caddy com o módulo do seu provedor de DNS e um token de API para aquela zona.

QComo desativo o HTTPS automático no Caddy?

AUse um endereço de site `http://` para um único site ou defina a opção global `auto_https off`. Você também pode usar `auto_https disable_redirects` para manter os certificados, mas parar o redirecionamento de HTTP para HTTPS.

HTTPS automático no Caddy: como funciona o TLS automático e como resolver falhas · NoctisNode