Caddy DNS #
Plugin caddy-dns memungkinkan Caddy mendapatkan sertifikat TLS wildcard melalui DNS-01 ACME challenge. Berbeda dari HTTP-01 challenge (yang memerlukan akses publik ke port 80), DNS-01 challenge dilakukan sepenuhnya melalui DNS record — sehingga cocok untuk server internal, server di belakang firewall, atau kebutuhan wildcard certificate.
Mengapa DNS Challenge? #
HTTP-01 Challenge (default Caddy):
+ Simple, tidak perlu konfigurasi tambahan
+ Works out of the box
- Butuh port 80 bisa diakses dari internet
- Tidak bisa digunakan untuk internal servers
- Tidak support wildcard certificate (*.example.com)
DNS-01 Challenge (via caddy-dns):
+ Support wildcard certificate (*.example.com)
+ Bekerja untuk server internal / di belakang firewall
+ Tidak butuh port 80 terbuka ke internet
- Butuh API access ke DNS provider
- Propagasi DNS butuh waktu (30 detik - beberapa menit)
- Perlu mengelola API credentials dengan aman
Provider yang Didukung #
Provider Module
──────────────────────────────────────────────────────────────────
Cloudflare github.com/caddy-dns/cloudflare
AWS Route53 github.com/caddy-dns/route53
Google Cloud DNS github.com/caddy-dns/googleclouddns
Azure DNS github.com/caddy-dns/azure
DigitalOcean github.com/caddy-dns/digitalocean
Namecheap github.com/caddy-dns/namecheap
Gandi github.com/caddy-dns/gandi
Hetzner github.com/caddy-dns/hetzner
Porkbun github.com/caddy-dns/porkbun
Vultr github.com/caddy-dns/vultr
DNSimple github.com/caddy-dns/dnsimple
GoDaddy github.com/caddy-dns/godaddy
dan puluhan lainnya... https://github.com/caddy-dns
Instalasi: Cloudflare (Paling Umum) #
xcaddy build \
--with github.com/caddy-dns/cloudflare
# Buat Cloudflare API Token (bukan API Key global!)
# Di Cloudflare Dashboard:
# My Profile → API Tokens → Create Token
# Template: "Edit zone DNS"
# Zone Resources: Include - Specific zone - example.com
# (Beri akses hanya ke zone yang diperlukan, bukan semua)
# Simpan token sebagai environment variable
export CF_API_TOKEN="your-cloudflare-api-token-here"
Konfigurasi Wildcard Certificate — Cloudflare #
{
# Konfigurasi global TLS untuk menggunakan DNS challenge
email [email protected]
}
# Wildcard certificate untuk semua subdomain
*.example.com example.com {
tls {
dns cloudflare {env.CF_API_TOKEN}
}
# Routing berdasarkan subdomain
@app host app.example.com
@api host api.example.com
@admin host admin.example.com
handle @app {
reverse_proxy app-backend:3000
}
handle @api {
reverse_proxy api-backend:8080
}
handle @admin {
basicauth { ... }
reverse_proxy admin-backend:9000
}
# Default handler
handle {
root * /var/www/html
file_server
}
}
Konfigurasi Route53 — AWS #
xcaddy build \
--with github.com/caddy-dns/route53
{
email [email protected]
}
*.example.com example.com {
tls {
dns route53 {
# Opsi 1: Gunakan IAM role (direkomendasikan di AWS)
# Tidak perlu konfigurasi credentials eksplisit
# Caddy akan menggunakan instance role otomatis
# Opsi 2: Access key eksplisit
access_key_id {env.AWS_ACCESS_KEY_ID}
secret_access_key {env.AWS_SECRET_ACCESS_KEY}
region {env.AWS_REGION}
# Opsi 3: Profile dari ~/.aws/credentials
# profile my-profile
}
}
reverse_proxy backend:3000
}
// IAM Policy minimum untuk Route53 DNS challenge
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"route53:GetChange",
"route53:ChangeResourceRecordSets",
"route53:ListResourceRecordSets"
],
"Resource": [
"arn:aws:route53:::hostedzone/YOUR_HOSTED_ZONE_ID",
"arn:aws:route53:::change/*"
]
},
{
"Effect": "Allow",
"Action": "route53:ListHostedZonesByName",
"Resource": "*"
}
]
}
Internal Server dengan DNS Challenge #
Skenario paling umum penggunaan DNS challenge: server yang tidak bisa diakses dari internet:
{
email [email protected]
# Gunakan CA internal untuk sertifikat internal
# (Atau Let's Encrypt jika domain public tapi server internal)
}
# Server internal — tidak perlu port 80 terbuka ke internet
internal.company.com {
tls {
dns cloudflare {env.CF_API_TOKEN}
}
# Hanya izinkan akses dari jaringan internal
@external not remote_ip 10.0.0.0/8 192.168.0.0/16
respond @external 403
reverse_proxy internal-app:8080
}
DNS Challenge untuk Multi-Domain #
{
email [email protected]
}
# Wildcard untuk domain utama
*.example.com {
tls {
dns cloudflare {env.CF_API_TOKEN}
}
reverse_proxy backend:3000
}
# Wildcard untuk domain lain (multi-tenant)
*.client-a.com *.client-b.com {
tls {
dns cloudflare {env.CF_API_TOKEN}
}
# Map ke backend berdasarkan domain
reverse_proxy backend:3000
}
Keamanan API Key #
# JANGAN simpan API key langsung di Caddyfile!
# Gunakan environment variables
# /etc/caddy/caddy.env (mode 600, owned by caddy user)
cat > /etc/caddy/caddy.env << 'EOF'
CF_API_TOKEN=your-cloudflare-token
AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key
EOF
chmod 600 /etc/caddy/caddy.env
chown caddy:caddy /etc/caddy/caddy.env
# Tambahkan ke systemd service
sudo systemctl edit caddy
# /etc/systemd/system/caddy.service.d/override.conf
[Service]
EnvironmentFile=/etc/caddy/caddy.env
sudo systemctl daemon-reload
sudo systemctl restart caddy
# Verifikasi environment tersedia
sudo systemctl show caddy --property=Environment
Troubleshooting DNS Challenge #
# 1. Cek apakah Caddy berhasil membuat TXT record
# Setelah inisiasi, Caddy harusnya buat record:
# _acme-challenge.example.com TXT "..."
dig TXT _acme-challenge.example.com
# 2. Cek log Caddy untuk error DNS challenge
sudo journalctl -u caddy -n 50 | grep -i "dns\|acme\|tls"
# 3. Debug mode untuk TLS
# Di global options:
# { debug }
# Lalu perhatikan log untuk "dns-01" challenge
# 4. Error umum:
# "permission denied" → API token tidak punya permission yang cukup
# "zone not found" → Domain tidak di account Cloudflare tersebut
# "propagation timeout" → DNS lambat propagasi, tambah delay:
{
email [email protected]
}
*.example.com {
tls {
dns cloudflare {env.CF_API_TOKEN}
# Tunggu lebih lama untuk propagasi DNS
# (default biasanya cukup, tapi beberapa DNS provider lambat)
resolvers 1.1.1.1 8.8.8.8
}
}
Ringkasan #
- Plugin
caddy-dnstersedia untuk hampir semua DNS provider populer — install hanya provider yang kamu gunakan.- DNS-01 challenge adalah satu-satunya cara mendapatkan wildcard certificate (
*.example.com) — tidak bisa dilakukan dengan HTTP-01.- Simpan API credentials di environment variables atau file terpisah (mode 600) — jangan pernah hardcode di Caddyfile yang masuk ke version control.
- Gunakan API token dengan permission minimal — hanya izinkan akses ke zone yang diperlukan, bukan seluruh akun DNS.
- Untuk server internal yang tidak bisa diakses internet, DNS-01 adalah satu-satunya pilihan untuk mendapatkan sertifikat dari public CA seperti Let’s Encrypt.
- Jika DNS challenge gagal, cek propagasi TXT record dengan
dig TXT _acme-challenge.example.com— record harus muncul sebelum Let’s Encrypt memverifikasi.
← Sebelumnya: Plugin Populer Berikutnya: Buat Plugin →
DNS Challenge dengan ZeroSSL #
ZeroSSL adalah alternatif Let’s Encrypt yang juga mendukung wildcard certificate via DNS challenge:
{
email [email protected]
# ZeroSSL perlu EAB credentials
# Dapatkan dari: https://app.zerossl.com/developer
}
*.example.com example.com {
tls {
ca https://acme.zerossl.com/v2/DV90
# External Account Binding credentials
eab_key_id {env.ZEROSSL_KEY_ID}
eab_mac_key {env.ZEROSSL_MAC_KEY}
# DNS challenge
dns cloudflare {env.CF_API_TOKEN}
}
reverse_proxy backend:3000
}
Menggunakan Dua Provider Sekaligus (Fallback) #
{
email [email protected]
}
*.example.com example.com {
tls {
# Caddy otomatis fallback ke issuer kedua jika pertama gagal
issuer acme {
ca https://acme-v02.api.letsencrypt.org/directory
dns cloudflare {env.CF_API_TOKEN}
}
issuer acme {
ca https://acme.zerossl.com/v2/DV90
eab_key_id {env.ZEROSSL_KEY_ID}
eab_mac_key {env.ZEROSSL_MAC_KEY}
dns cloudflare {env.CF_API_TOKEN}
}
}
reverse_proxy backend:3000
}
Konfigurasi ini memberikan redundansi — jika Let’s Encrypt tidak tersedia, Caddy otomatis mencoba ZeroSSL. Kedua provider menawarkan sertifikat gratis untuk domain publik.