文档
一个 项目

tls

为站点配置 TLS。

Caddy 的默认 TLS 设置是安全的。只有在你有充分理由并理解其后果时才更改这些设置。 此指令最常见的用途是指定 ACME 帐户电子邮件地址、更改 ACME CA 端点,或提供你自己的证书。

兼容性说明:由于 TLS 作为安全协议的敏感性,可能会在新的次要或补丁版本中对 TLS 默认值进行有意调整。旧的或已损坏的 TLS 版本、密码套件、功能等可能随时被移除。如果你的部署对更改极其敏感,则应明确指定必须保持不变的值,并在升级时保持警惕。在几乎所有情况下,我们建议使用默认设置。

语法

tls [internal|<email>] | [<cert_file> <key_file>] {
	protocols <min> [<max>]
	ciphers   <cipher_suites...>
	curves    <groups...>
	alpn      <values...>
	load      <paths...>
	ca        <ca_dir_url>
	ca_root   <pem_file>
	key_type  ed25519|p256|p384|rsa2048|rsa4096
	dns       <provider_name> [<params...>]
	propagation_timeout <duration>
	propagation_delay   <duration>
	dns_ttl             <duration>
	dns_challenge_override_domain <domain>
	resolvers <dns_servers...>
	eab       <key_id> <mac_key>
	on_demand
	reuse_private_keys
	client_auth {
		mode                   [request|require|verify_if_given|require_and_verify]
		trust_pool             <module>
		verifier 			   <module>
	}
	issuer          <issuer_name>  [<params...>]
	get_certificate <manager_name> [<params...>]
	insecure_secrets_log <log_file>
}
  • internal 表示使用 Caddy 的内部、本地信任的 CA 为该站点生成证书。要进一步配置 internal 签发器,请使用 issuer 子指令。

  • <email> 是用于管理站点证书的 ACME 帐户的电子邮件地址。你也可以选择使用 email 全局选项,以一次性为所有站点配置该设置。

  • <cert_file><key_file> 是证书和私钥 PEM 文件的路径。只指定其中一个是无效的。

  • protocols 指定最小和最大协议版本。除非你知道自己在做什么,否则不要更改这些设置。通常无需配置它们,因为 Caddy 始终使用现代默认值。

    默认最小:tls1.2,默认最大:tls1.3

  • ciphers 指定按偏好降序排列的密码套件名称列表。除非你知道自己在做什么,否则不要更改这些设置。请注意,TLS 1.3 的密码套件不可自定义;并且并非所有 TLS 1.2 密码都默认启用。受支持的名称如下(按 Go 标准库的偏好顺序):

    • TLS_AES_128_GCM_SHA256
    • TLS_CHACHA20_POLY1305_SHA256
    • TLS_AES_256_GCM_SHA384
    • TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
    • TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
    • TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
    • TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
    • TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
    • TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
    • TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
    • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
    • TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
    • TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
    • TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
  • curves 指定要支持的椭圆曲线(EC 群)列表。建议不要更改默认值。支持的值有:

    • x25519mlkem768(后量子密码,PQC)
    • x25519
    • secp256r1
    • secp384r1
    • secp521r1
  • alpn 是要在 TLS 握手的 ALPN 扩展(见 ALPN 术语)中通告的值列表。

  • load 指定从中加载包含证书+密钥捆绑的 PEM 文件的文件夹列表。

  • ca 更改 ACME CA 端点。此项通常用于在测试时设置 Let's Encrypt 的 staging 端点,或使用内部 ACME 服务器。(若要为整个 Caddyfile 更改此值,请改用 acme_ca 全局选项。)

  • ca_root 指定一个包含 ACME CA 端点受信任根证书的 PEM 文件(当该证书不在系统信任存储中时使用)。

  • key_type 是在生成 CSR 时使用的密钥类型。仅在你有特定要求时设置此项。

  • dns 启用使用指定提供者插件的 DNS 验证挑战。该插件必须从 caddy-dns 仓库 中插入。每个提供者插件可能在其名称后有自己的语法;请参阅其文档以获取详细信息。对每个 DNS 提供者的支持维护是社区的工作。在我们的维基上了解如何为你的提供者启用 DNS 挑战。

  • propagation_timeout 是一个 持续时间值,用于设置在使用 DNS 挑战时等待 DNS TXT 记录出现的最大时间。设置为 -1 可禁用传播检查。默认 2 分钟。

  • propagation_delay 是一个 持续时间值,用于设置在使用 DNS 挑战时开始 DNS TXT 记录传播检查前等待多久。默认 0(不等待)。

  • dns_ttl 是一个 持续时间值,用于设置用于 DNS 挑战的 TXT 记录的 TTL。很少需要更改。

  • dns_challenge_override_domain 覆盖用于 DNS 挑战的域名。用于将挑战委托到不同域。

    如果你的主域名的 DNS 提供者没有可用的 DNS 插件,你可能会想使用此项。你可以改为在主域上创建一个以 _acme-challenge 为子域的 CNAME 记录,指向你确实有插件支持的次级域。此选项不要求插件提供特别支持。

    当 ACME 签发器尝试为你的主域解决 DNS 挑战时,它们将遵循 CNAME 到你的次级域以查找 TXT 记录。

    注意: 在此处使用 CNAME 记录的完整规范名称作为值 —— _acme-challenge 子域不会被自动追加。

  • resolvers 自定义在执行 DNS 挑战时使用的 DNS 解析器;它们优先于系统解析器或任何默认解析器。如果在此处设置,解析器将传播到所有已配置的证书签发器。

    这通常是 IP 地址列表。例如,使用 Google 公共 DNS

    resolvers 8.8.8.8 8.8.4.4
    
  • eab 为该站点配置 ACME 外部帐户绑定(EAB),使用由你的 CA 提供的 key ID 和 MAC key。

  • on_demand 为站点块地址中给定的主机启用 按需 TLS安全警告: 除非你还配置了用于缓解滥用的 on_demand_tls 全局选项,否则在生产环境中这样做是不安全的。

  • reuse_private_keys 启用在续期证书时重用私钥。默认情况下,为每个新证书创建一个新的密钥以缓解固定(key pinning)并减少密钥泄露的影响。密钥固定违背行业最佳实践。除非你有特定原因,否则不推荐使用此选项;它可能在未来某个版本中被移除。

  • client_auth 启用并配置 TLS 客户端认证:

    • mode 是用于验证客户端的模式。允许的值为:

      模式 描述
      request 向客户端请求证书,但即使没有证书也允许;不进行验证
      require 要求客户端出示证书,但不进行验证
      verify_if_given 向客户端请求证书;即使没有证书也允许,但若有证书则进行验证
      require_and_verify 要求客户端出示经过验证的有效证书

      默认:如果提供了 trust_pool 模块,则为 require_and_verify;否则为 require

    • trust_pool 配置用于验证客户端证书的证书颁发机构(CA)来源。

      用于提供受信任证书池的证书颁发机构以及该段内的配置取决于所配置的 trust pool 模块。Caddy 中可用的标准模块在下文 信任池提供者 中列出。完整的模块列表(包括第三方)可在 trust_pool JSON 文档 中找到。

      可以使用多个 trusted_* 指令来指定多个 CA 或叶证书。未列为叶证书或未由任何指定 CA 签名的客户端证书将根据 mode 被拒绝。

    • verifier 启用自定义客户端证书验证器模块。这些模块可以执行自定义的客户端认证检查,例如确保证书未被撤销。

  • issuer 配置自定义证书签发器,或从某个来源获取证书。

    使用哪个签发器以及此段后续的选项取决于可用的 签发器模块。一些其他子指令(如 cadns)实际上是配置 acme 签发器的快捷方式(该子指令是后添加的),因此同时指定此指令和其中一些其他指令会造成混淆并因此被禁止。

    此子指令可以多次指定以配置多个冗余签发器;如果一个签发器无法签发证书,将尝试下一个。

  • get_certificate 启用在握手时从 管理器模块 获取证书。

  • insecure_secrets_log 启用将 TLS 密钥记录到文件。这也称为 SSLKEYLOGFILE。使用 NSS 密钥日志格式,随后可被 Wireshark 或其他工具解析。⚠️ 安全警告: 这不安全,因为它允许其他程序或工具解密 TLS 连接,从而完全破坏安全性。但该功能对于调试和故障排除可能是有用的。

信任池提供者

以下是可在 trust_pool 子指令中使用的标准信任池提供者:

inline

inline 模块直接在 Caddyfile 中解析以 base64 DER 编码形式列出的受信根证书。trust_der 指令可以重复多次。

trust_pool inline {
	trust_der      <base64_der>
}
  • trust_der 是用于验证客户端证书的以 base64 DER 编码的 CA 证书。

file

file 模块从磁盘上的 PEM 文件读取受信根证书。pem_file 指令可以在同一行接受多个文件路径,并可重复多次。

... file [<pem_file>...] {
	pem_file <pem_file>...
}
  • pem_file 是用于验证客户端证书的 PEM CA 证书文件路径。

pki_root

pki_root 模块从 PKI 应用 中定义的证书颁发机构获取根证书并信任它们。authority 指令可以同时接受多个 authority,并可重复多次。

... pki_root [<ca_name>...] {
	authority <ca_name>...
}
  • authority 是在 PKI 应用中配置的证书颁发机构的名称。

pki_intermediate

pki_intermediate 模块从 PKI 应用 中定义的证书颁发机构获取中间证书并信任它们。authority 指令可以同时接受多个 authority,并可重复多次。

... pki_intermediate [<ca_name>...] {
	authority <ca_name>...
}
  • authority 是在 PKI 应用中配置的证书颁发机构的名称。

storage

storage 模块从 Caddy 的 存储 中提取受信任证书根。authority 指令可以同时接受多个 authority,并可重复多次。

... storage [<storage_keys>...] {
	storage <storage_module>
	keys    <storage_keys>...
}
  • storage 是一个可选的存储模块以供使用。如果未指定,将使用默认存储模块。如果指定,则只能指定一次。

  • keys 是存储证书 PEM 文件的存储键列表。该指令在同一行接受多个值,并且可以多次指定。

http

http 模块从 HTTP 端点获取受信任证书。endpoints 指令可以同时接受多个端点,并可重复多次。

... http [<endpoints...>] {
	endpoints   <endpoints...>
	tls         <tls_config>
}
  • endpoints 是用于获取证书的 HTTP 端点列表。该指令在同一行接受多个值,并且可以多次指定。

  • tls 是连接到 HTTP 端点时使用的可选 TLS 配置。该段的解析在以下部分中定义。

TLS
... {
	ca                    <ca_module>
	insecure_skip_verify
	handshake_timeout     <duration>
	server_name           <name>
	renegotiation         <never|once|freely>
}
  • ca 是一个可选指令,用于定义信任池的提供者。其配置遵循与 trust_pool 相同的行为。如果指定,则只能指定一次。

  • insecure_skip_verify 关闭 TLS 握手验证,使连接不安全并易受中间人攻击。不要在生产环境中使用。 验证是针对系统信任的证书颁发机构或由 ca 指令确定的证书颁发机构进行的。

  • handshake_timeout 是等待 TLS 握手完成的最大 持续时间。默认:无超时。

  • server_name 设置在验证 TLS 握手中接收到的证书时使用的服务器名称。默认情况下,这将使用上游地址的主机部分。

  • renegotiation 设置 TLS 重新协商级别。TLS 重新协商是在第一次握手之后执行后续握手的行为。级别可以是:

    • never(默认) 禁用重新协商。
    • once 允许远端服务器每个连接请求一次重新协商。
    • freely 允许远端服务器反复请求重新协商。

签发器(Issuers)

以下签发器随 tls 指令一并提供:

acme

使用 ACME 协议获取证书。注意 acme 是默认签发器(使用 Let's Encrypt),因此通常不需要显式配置它。

... acme [<directory_url>] {
	dir      <directory_url>
	test_dir <test_directory_url>
	email    <email>
	timeout  <duration>
	disable_http_challenge
	disable_tlsalpn_challenge
	alt_http_port    <port>
	alt_tlsalpn_port <port>
	eab <key_id> <mac_key>
	trusted_roots <pem_files...>
	dns [<provider_name> [<options>]]
	propagation_timeout <duration>
	propagation_delay   <duration>
	dns_ttl             <duration>
	dns_challenge_override_domain <domain>
	resolvers <dns_servers...>
	preferred_chains [smallest] {
		root_common_name <common_names...>
		any_common_name  <common_names...>
	}
}
  • dir 是 ACME CA 的 directory URL。

    默认:https://acme-v02.api.letsencrypt.org/directory

  • test_dir 是一个可选的回退目录,用于在重试挑战时使用;如果所有挑战失败,则在重试期间使用此端点;当 CA 提供有 staging 端点且你希望避免生产端点的速率限制时非常有用。

    默认:https://acme-staging-v02.api.letsencrypt.org/directory

  • email 是 ACME 帐户联系电子邮件地址。

  • timeout 是一个 持续时间值,用于设置 ACME 操作超时前等待的时间。

  • disable_http_challenge 将禁用 HTTP 挑战。

  • disable_tlsalpn_challenge 将禁用 TLS-ALPN 挑战。

  • alt_http_port 是用于提供 HTTP 挑战的备用端口;它必须发生在端口 80 上,因此你必须将数据包转发到此备用端口。

  • alt_tlsalpn_port 是用于提供 TLS-ALPN 挑战的备用端口;它必须发生在端口 443 上,因此你必须将数据包转发到此备用端口。

  • eab 指定某些 ACME CA 可能要求的外部账户绑定(External Account Binding)。

  • trusted_roots 是一个或多个在连接到 ACME CA 服务器时要信任的根证书(以 PEM 文件名形式)。

  • dns 配置 DNS 挑战。此处必须配置一个提供者,除非 dns 全局选项 指定了一个全局适用的 DNS 提供者模块。

  • propagation_timeout 是一个 持续时间值,用于设置在使用 DNS 挑战时等待 DNS TXT 记录出现的最大时间。设置为 -1 可禁用传播检查。默认 2 分钟。

  • propagation_delay 是一个 持续时间值,用于设置在使用 DNS 挑战时开始 DNS TXT 记录传播检查前等待多久。默认 0(不等待)。

  • dns_ttl 是一个 持续时间值,用于设置用于 DNS 挑战的 TXT 记录的 TTL。很少需要更改。

  • dns_challenge_override_domain 覆盖用于 DNS 挑战的域名。用于将挑战委托到不同域。

    如果你的主域名的 DNS 提供者没有可用的 DNS 插件,你可能会想使用此项。你可以改为在主域上创建一个以 _acme-challenge 为子域的 CNAME 记录,指向你确实有插件支持的次级域。此选项不要求插件提供特别支持。

    当 ACME 签发器尝试为你的主域解决 DNS 挑战时,它们将遵循 CNAME 到你的次级域以查找 TXT 记录。

    注意: 在此处使用 CNAME 记录的完整规范名称作为值 —— _acme-challenge 子域不会被自动追加。

  • resolvers 自定义在执行 DNS 挑战时使用的 DNS 解析器;它们优先于系统解析器或任何默认解析器。如果在此处设置,解析器将传播到所有已配置的证书签发器。

    这通常是 IP 地址列表。例如,使用 Google 公共 DNS

    resolvers 8.8.8.8 8.8.4.4
    
  • preferred_chains 指定 Caddy 应偏好的证书链;当 CA 提供多个链时很有用。使用以下选项之一:

    • smallest 告知 Caddy 优先选择字节数最少的链。

    • root_common_name 是一个或多个通用名称的列表;Caddy 将选择第一个其根与至少一个指定通用名称匹配的链。

    • any_common_name 是一个或多个通用名称的列表;Caddy 将选择第一个其颁发者与至少一个指定通用名称匹配的链。

zerossl

使用 ZeroSSL 的专有证书签发 API 获取证书。需要 API 密钥,并且根据你的计划可能还需要付费。请注意,此签发器与 ZeroSSL 的 ACME 端点 是不同的。要使用 ZeroSSL 的 ACME 端点,请使用配置为 ZeroSSL ACME 目录端点的 acme 签发器(如上所述)。

... zerossl <api_key> {
	validity_days <days>
	alt_http_port <port>
	dns <provider_name> ...
	propagation_delay <duration>
	propagation_timeout <duration>
	resolvers <list...>
	dns_ttl <duration>
}
  • validity_days 定义证书的有效期。仅接受某些值;详细信息见 ZeroSSL 文档
  • alt_http_port 是用于完成 ZeroSSL HTTP 验证的端口(若非端口 80)。
  • dns 使用所命名的 DNS 提供者并基于给定配置启用 CNAME 验证方法以自动创建记录。DNS 提供者插件必须从 caddy-dns 仓库中安装。每个提供者插件可能在其名称后有自己的语法;请参考其文档以获取详细说明。对每个 DNS 提供者的支持维护是社区的工作。
  • propagation_delay 是在检查 CNAME 记录传播之前要等待的时间。
  • propagation_timeout 是在放弃之前等待 CNAME 记录传播的最长时间。
  • resolvers 定义在检查 CNAME 记录传播时使用的自定义 DNS 解析器。
  • dns_ttl 配置作为验证过程一部分创建的 CNAME 记录的 TTL。

internal

从内部证书颁发机构获取证书。

... internal {
	ca       <name>
	lifetime <duration>
	sign_with_root
}
  • ca 是要使用的内部 CA 的名称。默认:local。请参阅 PKI 应用全局选项 以配置 local CA,或创建备用 CA。

    默认情况下,根 CA 证书具有 3600d 的有效期(10 年),中间证书具有 7d 的有效期(7 天)。

    Caddy 将尝试将根 CA 证书安装到系统信任存储,但当 Caddy 以非特权用户运行或在 Docker 容器中运行时,这可能会失败。在这种情况下,需要手动安装根 CA 证书,可以使用 caddy trust 命令,或通过 从容器中复制出来

  • lifetime 是一个 持续时间值,用于设置内部签发的叶证书的有效期。默认:12h。除非绝对必要,否则不建议更改此项。它必须短于中间证书的有效期。

  • sign_with_root 强制使用根证书作为签发者而不是中间证书。不推荐使用,只有在设备/客户端无法正确验证证书链(非常罕见)时才应使用。

证书管理器(Certificate Managers)

证书管理器模块与签发器模块不同:使用管理器模块意味着外部工具或服务负责保持证书续订,而使用签发器模块则意味着 Caddy 本身在管理证书。(签发器模块以证书签名请求(CSR)为输入,而证书管理器模块以 TLS ClientHello 为输入。)

以下管理器模块随 tls 指令一起提供:

tailscale

从本地运行的 Tailscale 实例获取证书。必须在你的 Tailscale 帐户中启用 HTTPS(或你的开源 Headscale 服务器);并且 Caddy 进程必须以 root 运行,或者你必须配置 tailscaled 以授予你的 Caddy 用户获取证书的权限

注意:这通常是不必要的!Caddy 会自动为所有 *.ts.net 域使用 Tailscale,无需额外配置。

get_certificate tailscale  # often unnecessary!

http

通过发出 HTTP(S) 请求获取证书。响应必须具有 200 状态码,且主体必须包含一个 PEM 链,包括完整证书(含中间证书)以及私钥。

get_certificate http <url>
  • url 是要发出请求的完整 URL。强烈建议将此 URL 指向本地端点以获得性能方面的优势。URL 将附加以下查询字符串参数:

    • server_name:SNI 值
    • signature_schemes:以逗号分隔的签名算法十六进制 ID 列表
    • cipher_suites:以逗号分隔的密码套件十六进制 ID 列表

示例

使用自定义证书和密钥。证书应具有与站点地址匹配的 SANs

example.com {
	tls cert.pem key.pem
}

对当前站点块中的所有主机使用 本地信任 证书,而不是通过 ACME / Let's Encrypt 获取的公共证书(在开发环境中很有用):

example.com {
	tls internal
}

使用本地信任证书,但通过 按需 管理,而不是在后台管理。这允许你将任意域名指向你的 Caddy 实例并自动为其配置证书。如果你的 Caddy 实例可公开访问,则不应使用此方法,因为攻击者可能利用它耗尽你的服务器资源:

https:// {
	tls internal {
		on_demand
	}
}

使用内部 CA 的自定义选项(不能使用 tls internal 快捷方式):

example.com {
	tls {
		issuer internal {
			ca foo
		}
	}
}

为你的 ACME 帐户指定电子邮件地址(但如果所有站点只使用一个电子邮件,我们建议使用 email 全局选项):

example.com {
	tls your@email.com
}

为在 Cloudflare 上托管的域启用 DNS 挑战,账号凭据存储在环境变量中。这可以启用通配符证书支持(需要 DNS 验证):

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

通过 HTTP 获取证书链,而不是让 Caddy 管理证书。注意,get_certificate 意味着已启用 on_demand,使用模块获取证书而不是触发 ACME 签发:

https:// {
	tls {
		get_certificate http http://localhost:9007/certs
	}
}

启用 TLS 客户端认证并要求客户端出示经所有提供的 CA 验证的有效证书,通过 trust_poolfile 提供者:

example.com {
	tls {
		client_auth {
			trust_pool file ../caddy.ca.cer ../root.ca.cer
		}
	}
}