Caddy Usage
2 minute read
Build your own caddy images
Dockerfile:
FROM caddy:builder AS builder
RUN xcaddy build \
--with github.com/caddy-dns/alidns
FROM caddy
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
Caddy TLS Settings
tls [internal|<email>] | [<cert_file> <key_file>] {
protocols <min> [<max>]
ciphers <cipher_suites...>
curves <curves...>
alpn <values...>
load <paths...>
ca <ca_dir_url>
ca_root <pem_file>
key_type ed25519|p256|p384|rsa2048|rsa4096
dns <provider_name> [<params...>]
resolvers <dns_servers...>
eab <key_id> <mac_key>
on_demand
client_auth {
mode [request|require|verify_if_given|require_and_verify]
trusted_ca_cert <base64_der>
trusted_ca_cert_file <filename>
trusted_leaf_cert <base64_der>
trusted_leaf_cert_file <filename>
}
issuer <issuer_name> [<params...>]
}
常见配置方式
1. 使用内置的 CA 颁发自签证书
可能需要根据提示输入主机密码来将根证书安装到本机的信任库中
2. 直接指定证书位置
tls {$SSL_CERT_PATH} {$SSL_KEY_PATH}
3. 使用 letsencrypt 或 zerossl 来获得公共认可的 TLS 证书并自动续期
免费版本的 letsencrypt, zerossl 证书有效期仅有 90 天, caddy 会在到期之前自动的更新证书. 根据 ACME 协议 有以下三种常见方式来验证域名
- HTTP-01
- TLS-ALPN-01
- DNS-01
详细说明见 Challenge Types
值得注意的是 ACME 协议和 letsencrypt, zerossl 只使用标准的 http, https, dns 端口(即 80, 443, 53) 来验证
域名. 对于家庭网络公有IP的80, 443
端口可能被运营商默认屏蔽, 因此无法在家庭网络中正常的使用http-01
和tls-alpn-01
方式验证域名
对于 DNS-01
Chanllege, Caddy 提供了一系列的模块来支持 DNS 验证, 比如 route53
, alidns
, cloudflare
等,
详见Caddy Dns Modules
Caddyfile Examples
Caddy work with Vaultwarden(Use DNS-01
Chanllege)
docker-compose.yaml
version: '3'
services:
caddy:
image: caddy
container_name: caddy
build: .
restart: always
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- /share/Container/caddy/data:/data
- /share/Container/caddy/config:/config
network_mode: host
environment:
- ACME_AGREE=true
- DOMAIN_VWARDEN=https://YOUR_DOMAIN_HERE
- LOG_FILE=/data/access.log
- EMAIL=YOUR_EMAIL
- SERVER_VWARDEN=127.0.0.1
- ZEROSSL_API_KEY=
- ALIYUN_ACCESS_KEY_ID=
- ALIYUN_ACCESS_KEY_SECRET=
Caddyfile
{$DOMAIN_VWARDEN}:443 {
log {
level INFO
output file {$LOG_FILE} {
roll_size 10MB
roll_keep 10
}
}
# Uncomment this if you want to get a cert via ACME (Let's Encrypt or ZeroSSL).
# Use http-01 or tls-alpn-01 chanllege
# tls {$EMAIL}
# Use dns-01 chanllege
tls {
issuer zerossl {$ZEROSSL_API_KEY} {
dns alidns {
access_key_id {$ALIYUN_ACCESS_KEY_ID}
access_key_secret {$ALIYUN_ACCESS_KEY_SECRET}
}
}
}
# Or uncomment this if you're providing your own cert.
# tls {$SSL_CERT_PATH} {$SSL_KEY_PATH}
encode zstd gzip
# Uncomment to improve security (WARNING: only use if you understand the implications!)
header {
Strict-Transport-Security "max-age=31536000;"
X-XSS-Protection "1; mode=block"
X-Frame-Options "DENY"
X-Robots-Tag "none"
-Server
}
# Uncomment to allow access to the admin interface only from local networks
@insecureadmin {
not remote_ip 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8
path /admin*
}
redir @insecureadmin /
# The negotiation endpoint is also proxied to Rocket
reverse_proxy /notifications/hub/negotiate vaultwarden:80
# Notifications redirected to the websockets server
reverse_proxy /notifications/hub {$SERVER_VWARDEN}:3012
# Proxy everything else to Rocket
reverse_proxy {$SERVER_VWARDEN}:8012 {
header_up X-Real-IP {remote_host}
}
}
Last modified February 14, 2022: add some docs (88132bf)