tls
为网站配置TLS。
**Caddy的默认TLS设置是安全的。只有在你有充分的理由并了解其影响的情况下才能改变这些设置。**这个指令最常见的用途是指定一个ACME账户的电子邮件地址、改变ACME CA端点,或者提供你自己的证书。
兼容性说明:由于其作为安全协议的敏感性质,在新的次要版本或补丁版本中可能会对TLS默认值进行有意的调整。旧的或坏的TLS版本、密码、功能等可能在任何时候被删除。如果你的部署对变化非常敏感,你应该明确指定那些必须保持不变的值,并对升级保持警惕。在几乎所有情况下,我们建议使用默认设置。
语法
tls [internal|force_automate|<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> renewal_window_ratio <ratio> force_automate }
-
internal意味着使用Caddy内部的、本地信任的CA来为这个网站制作证书。要进一步配置
internal发行者,请使用issuer子指令。 -
force_automate强制Caddy为站点自动管理证书,即使已经有其他托管证书适用。
-
**<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_SHA256TLS_CHACHA20_POLY1305_SHA256TLS_AES_256_GCM_SHA384TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHATLS_ECDHE_RSA_WITH_AES_128_CBC_SHATLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHATLS_ECDHE_RSA_WITH_AES_256_CBC_SHATLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
-
curves 指定要支持的EC组列表。建议不要修改默认值。支持的值是:
x25519mlkem768(PQC)x25519secp256r1secp384r1secp521r1
-
alpn 是在TLS握手的ALPN扩展
中公布的值列表。
-
load 指定一个文件夹列表,从该文件夹中加载证书+密钥捆绑的PEM文件。
-
ca 改变ACME CA端点。这最常用于测试时设置Let's Encrypt暂存端点
,或内部ACME服务器。(要为整个Caddyfile改变这个值,请使用
acme_ca全局选项代替。) -
ca_root 指定一个PEM文件,其中包含ACME CA端点的可信根证书,如果不在系统信任存储中。
-
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 Public DNS
:
resolvers 8.8.8.8 8.8.4.4
-
eab 为这个站点配置ACME外部账户绑定(EAB),使用你的CA提供的密钥ID和MAC密钥。
-
on_demand 为网站块地址中给出的主机名启用按需TLS。**安全警告:**在生产中这样做是不安全的,除非你也配置了
on_demand_tls全局选项以减少滥用。 -
reuse_private_keys 启用证书续期时复用私钥。默认情况下,每张新证书都会创建新密钥,以缓解固定密钥并降低密钥泄露影响范围。密钥固定违背行业最佳实践。除非你有明确理由,否则不建议使用此选项;它将来可能被移除。
-
client_auth 启用并配置TLS客户端认证:
- mode 是验证客户端的模式。允许的值是:
模式 说明 request 要求客户提供证书,但即使没有证书也允许;不对其进行验证。 require 要求客户出示证书,但不进行验证。 verify_if_given 要求客户提供证书,即使没有也允许,但如果有则验证。 require_and_verify 要求客户出示经过验证的有效证书。
默认值:如果提供
trust_pool模块则为require_and_verify;否则为require。- trust_pool 配置证书颁发机构(CA)的来源,用于提供验证客户端证书的证书池。
提供受信证书池的证书颁发机构及其配置取决于所配置的信任池模块。Caddy中可用的标准模块列在下方。完整模块列表(包括第三方模块)见
trust_poolJSON文档。- verifier 启用自定义客户端证书验证器模块。这些模块可以执行自定义客户端认证检查,例如确保证书未被吊销。
- mode 是验证客户端的模式。允许的值是:
-
issuer 配置一个自定义的证书颁发者,或一个获得证书的来源。使用哪一个签发者以及这一段后面的选项取决于可用的签发者模块(标准签发者见下文;插件可以添加其他的)。其他一些子指令,如
ca和dns实际上是配置acme签发者的快捷方式(这个子指令是后来添加的),所以指定这个指令和其他一些指令是混乱的,因此禁止使用。这个子指令可以被多次指定,以配置多个冗余的签发者;如果一个签发失败,将尝试下一个签发者。 -
get_certificate 可以在握手时从一个管理模块获取证书。
-
insecure_secrets_log 启用将TLS密钥记录到文件。这也称为
SSLKEYLOGFILE,使用NSS密钥日志格式,可由Wireshark或其他工具解析。⚠️**安全警告:**这是不安全的,因为它允许其他程序或工具解密TLS连接,从而完全破坏安全性。不过,此能力可用于调试和排查问题。 -
renewal_window_ratio 是0到1之间的比率,用于决定证书剩余多少生命周期时Caddy开始尝试续期。例如,如果证书生命周期为90天,而此比率为
0.3333(默认值),则Caddy会在证书剩余30天或更少时持续尝试续期。也可以通过renewal_window_ratio全局选项设置。你通常很少需要修改它,但如果CA签发时间很长,稍晚续期可能有用。
请记住,这只是一个建议,因为ACME签发者可能实现ARI扩展。ARI会指定ACME客户端(这里是Caddy)应尝试续期的窗口,而该窗口可能与此比率不一致。
-
force_automate与在行内指定相同(见上文)。
信任池提供者
以下是可以在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指令可以同时接受多个机构,也可以重复多次。
... pki_root [<ca_name>...] { authority <ca_name>... }
- authority 是PKI应用中配置的证书颁发机构名称。
pki_intermediate
pki_intermediate模块从PKI应用中定义的证书颁发机构获取并信任 中间 证书。authority指令可以同时接受多个机构,也可以重复多次。
... pki_intermediate [<ca_name>...] { authority <ca_name>... }
- authority 是PKI应用中配置的证书颁发机构名称。
storage
storage模块从Caddy存储中提取受信证书根。keys指令可以同时接受多个存储键,也可以重复多次。
... 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允许远程服务器反复请求重新协商。
验证器
如果配置了trust_pool,客户端证书验证器模块会在验证证书由受信证书颁发机构签发之后执行。标准Caddy当前提供的验证器是leaf。
Leaf
leaf验证器检查客户端证书是否属于一组定义好的允许证书。证书集合通过加载器模块加载。
加载器
标准Caddy发行版捆绑4个加载器,其中3个可在Caddyfile中使用。
File
file加载器从指定PEM文件中加载证书集合。
... file <pem_files...>
Folder
folder加载器会递归遍历指定目录,查找要作为已接受客户端证书加载的PEM文件。
... folder <folders...>
PEM
pem加载器接受以内联方式写在Caddyfile中的PEM格式证书。
... pem <pem_strings...>
发行人
以下签发者随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...> } profile <name> }
-
dir 是ACME CA目录的URL。
默认值:
https://acme-v02.api.letsencrypt.org/directory -
test_dir 是一个可选的后备目录,在重试挑战时使用;如果所有挑战失败,在重试时将使用该端点;如果CA有暂存端点且你想避免其生产端点的速率限制,则非常有用。
默认值:
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可能需要它。
-
trusted_roots 是一个或多个根证书(作为PEM文件名),当连接到ACME CA服务器时要信任。
-
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 Public DNS
:
resolvers 8.8.8.8 8.8.4.4
-
preferred_chains 指定Caddy应该优先使用哪些证书链;如果你的CA提供多个证书链,这会很有用。使用以下选项之一:
-
smallest 将告诉Caddy倾向于使用字节数最少的链。
-
root_common_name 是一个或多个通用名称的列表;Caddy将选择第一个根部与指定通用名称中至少一个相匹配的链。
-
any_common_name 是一个或多个通用名称的列表;Caddy将选择第一个具有与指定通用名称中至少一个相匹配的发行者的链。
-
-
profile是订购证书时要应用的ACME配置文件名称。如果指定了它,所有配置的(无论隐式还是显式)CA都必须支持该配置文件。可用配置文件请参考你的CA文档;某些CA可能不支持配置文件。实验性:ACME配置文件规范仍处于草案状态,因此此功能可能发生变化或被移除。
zerossl
使用ZeroSSL专有证书签发API获取证书。需要API密钥,并且根据你的套餐可能需要付费。请注意,这与ZeroSSL的ACME端点不同。若要使用ZeroSSL的ACME端点,请使用上面描述的acme签发者,并配置ZeroSSL的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应用全局选项来配置localCA,或创建其他CA。默认情况下,根CA证书生命周期为
3600d(10年),中间证书生命周期为7d(7天)。Caddy会尝试将根CA证书安装到系统信任存储,但当Caddy以非特权用户运行或在Docker容器中运行时可能失败。在这种情况下,需要手动安装根CA证书,可以使用
caddy trust命令,或从容器中复制出来。 -
lifetime 是一个持续时间值,设置内部签发的叶子证书有效期。默认值:
12h。除非绝对必要,否则不建议修改。它必须短于中间证书生命周期。 -
sign_with_root 强制由根证书而不是中间证书签发。不建议这样做,只应在设备/客户端不能正确验证证书链时使用(非常罕见)。
证书管理器
证书管理器模块与签发者模块不同:使用管理器模块意味着外部工具或服务负责保持证书续期,而签发者模块意味着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会附加以下查询字符串参数:
server_name:SNI值signature_schemes:签名算法十六进制ID的逗号分隔列表cipher_suites:密码套件十六进制ID的逗号分隔列表local_ip:客户端发起请求时连接到的IP地址
示例
使用自定义证书和密钥。证书应具有与站点地址匹配的SAN:
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客户端认证,并要求客户端提供有效证书,通过trust_pool的file提供者对所有提供的CA进行验证:
example.com { tls { client_auth { trust_pool file ../caddy.ca.cer ../root.ca.cer } } }