Caddy Usage

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

Caddyfile Syntax:

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...>]
}

常见配置方式

Caddy Automatic Https

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-01tls-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)