强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Caddy 从入门到精通 / 05 - TLS 与 HTTPS / TLS & HTTPS

TLS 与 HTTPS / TLS & HTTPS

Caddy 的招牌功能:全自动 HTTPS。默认情况下,只要配置了域名,Caddy 就会自动完成证书申请、配置、续期的全部工作。

Caddy’s flagship feature: fully automatic HTTPS. By default, as long as a domain name is configured, Caddy handles certificate issuance, configuration, and renewal automatically.


🟢 基础 / Basics

自动 HTTPS(零配置)

example.com {
    respond "Secure by default!"
}

仅此而已。Caddy 会:

  1. 自动从 Let’s Encrypt 申请证书
  2. 自动配置 TLS
  3. 自动将 HTTP 重定向到 HTTPS
  4. 自动在证书到期前续期

前提条件:

  • 域名已解析到服务器 IP
  • 服务器 80 和 443 端口开放
  • 防火墙允许入站连接

多域名自动 HTTPS

example.com {
    respond "Site A"
}

blog.example.com {
    respond "Site B"
}

api.example.com {
    respond "Site C"
}

三个域名各自动获取独立证书,支持通配符需手动配置(见进阶部分)。

验证 HTTPS 状态

# 查看证书信息
curl -vI https://example.com 2>&1 | grep -i "ssl\|issuer\|expire"

# 更详细
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -issuer -dates -subject

🟡 进阶 / Intermediate

邮箱配置(证书过期通知)

Let’s Encrypt 在证书即将过期但未续期时会发送通知邮件:

{
    email [email protected]
}

example.com {
    respond "Hello"
}

使用 staging 环境测试

测试阶段建议使用 Let’s Encrypt staging 环境,避免触发速率限制:

{
    acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
}

example.com {
    respond "Testing"
}

⚠️ staging 证书不被浏览器信任,仅用于测试。

通配符证书

通配符证书需要 DNS challenge 验证:

{
    email [email protected]
}

*.example.com {
    tls {
        dns cloudflare {env.CF_API_TOKEN}
    }
    respond "Wildcard!"
}

环境变量设置:

export CF_API_TOKEN="your-cloudflare-api-token"

支持的 DNS 提供商:

提供商模块名
Cloudflaregithub.com/caddy-dns/cloudflare
Route53github.com/caddy-dns/route53
DigitalOceangithub.com/caddy-dns/digitalocean
Aliyungithub.com/caddy-dns/alidns
腾讯云 DNSPodgithub.com/caddy-dns/tencentcloud

通配符证书需要 xcaddy 编译包含对应 DNS 模块:

xcaddy build \
    --with github.com/caddy-dns/cloudflare

使用自签名证书(内部服务)

internal.example.com {
    tls internal
    respond "Internal service"
}

tls internal 使用 Caddy 的内置 CA 签发证书。浏览器会提示不受信任,适合内网服务。

自定义 CA(PKI)

{
    local_certs
    # 或配置自定义 PKI
}

example.com {
    tls {
        issuer internal {
            ca    "MyCompany CA"
            lifetime 365d
        }
    }
    respond "Custom CA"
}

手动指定证书文件

example.com {
    tls /path/to/cert.pem /path/to/key.pem
}

适用于已有证书的场景(如企业内部 CA 签发的证书)。

TLS 协议与密码套件控制

example.com {
    tls {
        protocols tls1.2 tls1.3
        ciphers TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
    }
}

🔴 高级 / Advanced

ACME 账户管理

Caddy 将 ACME 账户密钥和证书存储在 data 目录中:

~/.local/share/caddy/
├── certificates/
│   ├── acme-v02.api.letsencrypt.org-directory/
│   │   ├── example.com/
│   │   │   ├── example.com.crt
│   │   │   └── example.com.key
├── acme/
│   └── acme-v02.api.letsencrypt.org-users/
│       └── [email protected]/
│           ├── [email protected]
│           └── [email protected]
└── ocsp/

OCSP Stapling

Caddy 自动进行 OCSP Stapling,无需配置。当 OCSP 响应无法获取时,Caddy 会缓存上一个有效的响应。

验证 OCSP Stapling:

echo | openssl s_client -connect example.com:443 -status 2>/dev/null | grep -i "OCSP response"

双向 TLS(mTLS / Client Certificate)

example.com {
    tls {
        client_auth {
            mode require_and_verify
            trusted_ca_cert_file /path/to/client-ca.pem
        }
    }
    respond "Authenticated client"
}

客户端必须提供有效证书才能访问。

mTLS 配合验证客户端证书信息:

example.com {
    tls {
        client_auth {
            mode require_and_verify
            trusted_ca_cert_file /path/to/client-ca.pem
        }
    }

    @valid_client {
        header X-Client-Cert-Subject *CN=trusted-client*
    }

    handle @valid_client {
        respond "Welcome, trusted client"
    }

    handle {
        respond "Access denied" 403
    }
}

证书自动续期机制

Caddy 的续期逻辑:

证书签发成功
    │
    ▼
计算续期时间 = (到期时间 - 签发时间) × 2/3
    │
    ▼
例如 90 天证书 → 第 60 天开始续期
    │
    ▼
Caddy 后台 goroutine 定期检查
    │
    ▼
续期成功 → 更新内存证书 → OCSP 更新
    │
    ▼
续期失败 → 重试(指数退避) → 触发邮件通知

Zero-Downtime 证书热替换

当证书续期成功后,Caddy 在内存中完成证书切换,已建立的 TLS 连接不受影响。

配置自定义 ACME 端点

{
    acme_ca https://custom-acme-server.example.com/directory
    email [email protected]
}

example.com {
    respond "Custom ACME"
}

适用于自建 ACME 服务器(如 Step-CA、Boulder)。

DNS-01 Challenge 的多域名配置

{
    email [email protected]
}

*.example.com {
    tls {
        dns cloudflare {env.CF_API_TOKEN}
    }
}

*.example.org {
    tls {
        dns route53 {
            aws_access_key_id {env.AWS_ACCESS_KEY_ID}
            aws_secret_access_key {env.AWS_SECRET_ACCESS_KEY}
            region us-east-1
        }
    }
}

小结 / Summary

层级内容
🟢 基础自动 HTTPS、零配置、多域名
🟡 进阶staging 测试、通配符证书、DNS challenge、自签名、自定义证书
🔴 高级ACME 账户、OCSP Stapling、mTLS、续期机制、自定义 ACME 端点

下一章:路由与匹配 / Routing & Matching