文档
一个 项目

全局选项

Caddyfile 提供了一种方式来指定全局适用的选项。有些选项作为默认值;有些用于定制 HTTP 服务器并不只应用于某个特定站点;还有一些用于定制 Caddyfile 适配器 的行为。

Caddyfile 的最顶部可以是一个全局选项块。这是一个没有键的块:

{
	...
}

最多只能有一个,并且它必须是 Caddyfile 的第一个块。

可能的选项如下(点击每个选项可跳转到其文档):

{
	# General Options
	debug
	http_port    <port>
	https_port   <port>
	default_bind <hosts...>
	order <dir1> first|last|[before|after <dir2>]
	storage <module_name> {
		<options...>
	}
	storage_clean_interval <duration>
	admin   off|<addr> {
		origins <origins...>
		enforce_origin
	}
	persist_config off
	log [name] {
		output  <writer_module> ...
		format  <encoder_module> ...
		level   <level>
		include <namespaces...>
		exclude <namespaces...>
	}
	grace_period   <duration>
	shutdown_delay <duration>
	metrics {
		per_host
	}

	# TLS Options
	auto_https off|disable_redirects|ignore_loaded_certs|disable_certs
	email <yours>
	default_sni <name>
	fallback_sni <name>
	local_certs
	skip_install_trust
	acme_ca <directory_url>
	acme_ca_root <pem_file>
	acme_eab {
		key_id <key_id>
		mac_key <mac_key>
	}
	acme_dns <provider> ...
	dns <provider> ...
	ech <public_names...> {
		dns <provider> ...
	}
	on_demand_tls {
		ask        <endpoint>
		permission <module>
	}
	key_type ed25519|p256|p384|rsa2048|rsa4096
	cert_issuer <name> ...
	renew_interval <duration>
	cert_lifetime  <duration>
	ocsp_interval  <duration>
	ocsp_stapling off
	preferred_chains [smallest] {
		root_common_name <common_names...>
		any_common_name  <common_names...>
	}

	# Server Options
	servers [<listener_address>] {
		name <name>
		listener_wrappers {
			<listener_wrappers...>
		}
		timeouts {
			read_body   <duration>
			read_header <duration>
			write       <duration>
			idle        <duration>
		}
		keepalive_interval <duration>
		trusted_proxies <module> ...
		client_ip_headers <headers...>
		trace
		max_header_size <size>
		enable_full_duplex
		log_credentials
		protocols [h1|h2|h2c|h3]
		strict_sni_host [on|insecure_off]
	}

	# File Systems
	filesystem <name> <module> {
		<options...>
	}

	# PKI Options
	pki {
		ca [<id>] {
			name                  <name>
			root_cn               <name>
			intermediate_cn       <name>
			intermediate_lifetime <duration>
			root {
				format <format>
				cert   <path>
				key    <path>
			}
			intermediate {
				format <format>
				cert   <path>
				key    <path>
			}
		}
	}

	# Event options
	events {
		on <event> <handler...>
	}
}

常规选项

debug

启用调试模式,会将 默认记录器 的日志级别设置为 DEBUG。这会显示更多有助于故障排查的详细信息(在生产环境下会非常详细)。在请求社区论坛帮助之前,我们建议先启用此项(https://caddy.community)。例如,如果你的 Caddyfile 顶部没有其他全局选项,可以这样:

{
	debug
}
http_port

服务器用于 HTTP 的端口。

仅供内部使用;不会改变客户端的 HTTP 端口。通常用于在内部网络中将 80 端口转发到到达 Caddy 前的另一个端口(例如 8080),以便进行路由。

默认:80

https_port

服务器用于 HTTPS 的端口。

仅供内部使用;不会改变客户端的 HTTPS 端口。通常用于在内部网络中将 443 端口转发到到达 Caddy 前的另一个端口(例如 8443),以便进行路由。

默认:443

default_bind

如果站点中未使用 bind 指令,则为所有站点使用的默认绑定地址。默认:空,表示绑定到所有接口。

{
	default_bind 10.0.0.1
}
order

为 HTTP 处理器指令分配顺序。由于 HTTP 处理器按顺序链式执行,因此需要确保处理器按正确顺序执行。标准指令有预定义的顺序,但如果使用第三方 HTTP 处理器模块,你需要通过此选项或将指令放在 route 中来显式定义顺序。顺序可以是绝对的(firstlast),也可以是相对于另一个指令的(beforeafter)。

例如,要使用 replace-response 插件,你应确保它的指令放在 encode 之后,这样它就可以在响应被编码之前执行替换(因为响应在处理器链中是向上流动的,而不是向下):

{
	order replace after encode
}
storage

配置 Caddy 的存储机制。默认是 file_system。还有许多其他可用的 存储模块 作为插件提供。

例如,要更改文件系统的存储位置:

{
	storage file_system /path/to/custom/location
}

当需要在多个 Caddy 实例之间同步 Caddy 存储以确保它们使用相同的证书和密钥时,通常需要自定义存储模块。有关更多详细信息,请参阅 自动 HTTPS 关于存储的部分

storage_clean_interval

扫描存储单元以移除旧的或过期资源的频率。此类扫描会对存储模块产生大量读取(和列表操作),因此在大型部署中请为此间隔选择更长的时间。接受 持续时间值

在进程首次启动时会始终进行清理。然后,如果上一次清理在少于此间隔一半的时间内完成,则在上一次清理开始后过此持续时间才会启动新的清理(否则将跳过下一次启动)。

默认:24h

{
	storage_clean_interval 7d
}
admin

定制 管理 API 端点。接受占位符。使用 网络地址

默认值:localhost:2019,除非设置了 CADDY_ADMIN 环境变量。

如果设置为 off,则管理端点将被禁用。禁用时,无法进行配置更改,除非停止并重启服务器,因为 caddy reload 命令 使用管理 API 将新配置推送到正在运行的服务器。

如果运行服务器时更改了管理端点地址,请记得在兼容的 命令 中使用 CLI 标志 --address 指定当前的管理端点地址。

还支持以下子选项:

  • origins 配置允许连接到端点的来源列表。

    默认值会智能选择:

    • 如果监听地址是回环地址(例如 localhost 或回环 IP,或 unix 套接字),则允许的来源为 localhost::1127.0.0.1,并与监听地址端口组合(所以 localhost:2019 是一个有效的 origin)。
    • 如果监听地址不是回环地址,则允许的 origin 与监听地址相同。

    如果监听地址主机不是通配接口(通配符包括:空字符串、0.0.0.0[::]),则会执行 Host 头强制验证。实际上,这意味着默认情况下会验证 Host 头是否在 origins 中,因为接口是 localhost。但对于像 :2020 这样的地址(含通配接口),不会执行 Host 头验证。

  • enforce_origin 启用对请求的 Origin 头的强制验证。

    当监听地址是通配接口(因为不会验证 Host),并且管理 API 暴露在公共网络时,这个选项最有用。它启用 CORS 预检检查,并确保 Origin 头与 origins 列表进行验证。只有在你在开发机器上运行 Caddy 并需要从浏览器访问管理 API 时才使用此项。

例如,在所有接口上将管理 API 暴露到不同端口 — ⚠️ 此端口不应公开暴露,否则任何人都能控制你的服务器;如果需要公开访问,考虑启用 origin 验证:

{
	admin :2020
}

要关闭管理 API — ⚠️ 这会导致在不停止并重新启动服务器的情况下无法重载配置:

{
	admin off
}

使用 unix 套接字 为管理 API 提供访问控制(基于文件权限):

{
	admin unix//run/caddy-admin.sock
}

仅允许具有匹配 Origin 头的请求:

{
	admin :2019 {
		origins localhost
		enforce_origin
	}
}
persist_config

控制是否将当前 JSON 配置持久化到 配置目录,以避免通过管理 API 进行的配置更改丢失。目前,仅支持 off 选项。默认情况下,配置会被持久化。

{
	persist_config off
}
log

配置命名记录器。

可以传入名称以指示要定制其行为的特定记录器。如果未指定名称,则修改 default 记录器的行为。你可以阅读更多关于 default 记录器以及 Caddy 中日志如何工作 的解释。

可以通过多次使用 log 来配置多个不同名称的记录器。

这与 log 指令 不同,后者仅配置 HTTP 请求日志(也称为访问日志)。全局选项 log 与该指令共享其配置结构(除了 includeexclude),完整文档可在该指令页面找到。

  • output 配置日志写入位置。

    有关完整文档,请参阅 log 指令

  • format 描述如何编码或格式化日志。

    有关完整文档,请参阅 log 指令

  • level 是要记录的最低条目级别。

    默认:INFO

    可选值:DEBUGINFOWARNERROR,以及很少使用的 PANICFATAL

  • include 指定要包含在此记录器中的日志名称。

    默认情况下,此列表为空(即包含所有日志)。

    例如,要仅包含由管理 API 发出的日志,可以包含 admin.api

  • exclude 指定要从此记录器中排除的日志名称。

    默认情况下,此列表为空(即不排除任何日志)。

    例如,要排除 HTTP 访问日志,可以排除 http.log.access

includeexclude 可接受的记录器名称取决于使用的模块,最简单的发现方式是查看已有日志。

下面是一个示例,将所有 HTTP 访问日志和管理日志以 JSON 格式写到 stdout:

{
	log default {
		output stdout
		format json
		include http.log.access admin.api
	}
}
grace_period

定义关闭 HTTP 服务器(例如在配置更改或 Caddy 停止时)的宽限期。

在宽限期内,不接受新连接,空闲连接会被关闭,活动连接会被尽可能耐心地等待以完成其请求。如果客户端在宽限期内未完成请求,服务器将被强制终止以允许重载完成并释放资源。接受 持续时间值

默认情况下,宽限期是永远的,这意味着连接不会被强制关闭。

{
	grace_period 10s
}
shutdown_delay

定义在 宽限期 之前 的一段 持续时间,在此期间即将被停止的服务器将继续正常运行,除非 {http.shutting_down} 占位符的值变为 true,并且 {http.time_until_shutdown} 给出直到宽限期开始的时间。

如果在配置更改时有任何服务器要被关闭,这会导致延迟,并有效地将更改安排在稍后的时间。它对于向健康检查器通告该服务器即将下线并给予负载均衡器将其移出轮询的时间很有用;例如:

{
	shutdown_delay 30s
}

example.com {
	handle /health-check {
		@goingDown vars {http.shutting_down} true
		respond @goingDown "Bye-bye in {http.time_until_shutdown}" 503
		respond 200
	}
	handle {
		respond "Hello, world!"
	}
}

TLS 选项

auto_https

配置 自动 HTTPS,该功能使 Caddy 能够为你的站点自动管理证书并进行 HTTP 到 HTTPS 的重定向。

有几种模式可供选择:

  • off:禁用证书自动化和 HTTP 到 HTTPS 的重定向。

  • disable_redirects:仅禁用 HTTP 到 HTTPS 的重定向。

  • disable_certs:仅禁用证书自动化。

  • ignore_loaded_certs:即便名称出现在手动加载的证书中也进行证书自动化。当你使用 tls 指令 指定了证书并包含你想要由自动化管理的名称(或通配符)时,此项很有用。

{
	auto_https disable_redirects
}
email

你的电子邮件地址。主要在向 CA 创建 ACME 账户时使用,强烈建议填写以便在证书出现问题时接收通知。

{
	email admin@example.com
}
default_sni

为客户端在 ClientHello 中未使用 SNI 时设置默认的 TLS ServerName。

{
	default_sni example.com
}
fallback_sni

⚠️ 实验性

如果配置,fallback 将在原始 ServerName 与证书缓存中的任何证书都不匹配时成为 ClientHello 中的 TLS ServerName。

此用途相当小众;通常在客户端为 CDN 并透传下游握手的 ServerName,但可接受使用原点主机名的证书时,你会将该原点主机名设置为此项。注意 Caddy 必须为该名称管理证书。

{
	fallback_sni example.com
}
local_certs

使默认情况下所有证书都内部签发,而不是通过像 Let's Encrypt 这样的(公共)ACME CA。这在开发环境中作为快速切换很有用。

{
	local_certs
}
skip_install_trust

跳过将本地 CA 根证书安装到系统信任存储以及 Java 和 Mozilla Firefox 信任存储的尝试。

{
	skip_install_trust
}
acme_ca

指定 ACME CA 的目录 URL。强烈建议在测试或开发时将其设置为 Let's Encrypt 的暂存端点 。默认:ZeroSSL 和 Let's Encrypt 的生产端点。

注意,全局配置的 ACME CA 可能不会适用于所有站点;有关使用默认 ACME 签发者的主机名要求,请参阅文档。

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

指定一个 PEM 文件,该文件包含 ACME CA 端点的受信任根证书(当系统信任存储中没有时)。

{
	acme_ca_root /path/to/ca/root.pem
}
acme_eab

为所有 ACME 事务指定外部账户绑定(External Account Binding)。

例如,使用模拟 ZeroSSL 凭据:

{
	acme_eab {
		key_id GD-VvWydSVFuss_GhBwYQQ
		mac_key MjXU3MH-Z0WQ7piMAnVsCpD1shgMiWx6ggPWiTmydgUaj7dWWWfQfA
	}
}
acme_dns

配置用于所有 ACME 事务的 ACME DNS 挑战 提供商。

需要使用带有你 DNS 提供商插件的自定义构建的 Caddy。

提供商名称之后的令牌将以与在 tls 指令的 acme 签发器 中指定时相同的方式设置提供商。

{
	acme_dns cloudflare {env.CLOUDFLARE_API_TOKEN}
}
dns

配置一个默认的 DNS 提供商,当在相关上下文中没有本地指定其他提供商时使用。例如,如果启用了 ACME DNS 挑战但未配置 DNS 提供商,则将使用此全局默认。它也用于发布加密的 Encrypted ClientHello (ECH) 配置。

你的 Caddy 二进制必须包含指定的 DNS 提供商模块才能使其工作。

示例:使用来自环境变量的凭据:

{
	dns cloudflare {env.CLOUDFLARE_API_TOKEN}
}

(需要 Caddy 2.10 测试版 1 或更高版本。)

ech

通过使用指定的公用域名作为 TLS 握手中明文的服务器名称 (SNI) 来启用 Encrypted ClientHello (ECH)。在符合条件时,ECH 可以帮助在连接过程中在线路上保护你站点的域名。Caddy 将为每个指定的公用名称生成并发布一个 ECH 配置。发布是兼容客户端(例如正确配置的现代浏览器)知道使用 ECH 访问你站点的方式。

为了正确工作,ECH 配置必须以客户端期望的方式发布。大多数浏览器(启用了 DoH 或 DoT)期望 ECH 配置被发布到 HTTPS 类型的 DNS 记录。Caddy 会自动完成这类发布,但你必须使用 dns 子选项或全局的 dns 全局选项 指定一个 DNS 提供商,并且你的 Caddy 二进制必须包含所指定的 DNS 提供商模块。(可在我们的下载页面获取自定义构建。)

隐私提示:

  • 通常建议最大化你的匿名集合(anonymity set)大小。因此,我们通常建议大多数用户仅配置一个公用域名来保护你所有的站点。
  • 你的服务器应对你指定的公用域名具有权威性(即这些域名应指向你的服务器),因为 Caddy 会为它们获取证书。这些证书在某些情况下对于帮助符合规范的客户端可靠且安全地连接并完成 ECH 握手是至关重要的。它们仅用于促成正确的 ECH 握手,而不是用于应用数据(你的站点 —— 除非你定义的站点与公用域名相同)。
  • 每种情况可能不同。如果风险较高,我们建议咨询专家以审查你的威胁模型,因为 ECH 并非一刀切的解决方案。

示例:使用来自环境变量的凭据,将发布到停放在 Cloudflare 的域名服务器:

{
	dns cloudflare {env.CLOUDFLARE_API_TOKEN}
	ech ech.example.net
}

这应使兼容的客户端使用 ech.example.net 加载你所有站点,而不是以明文暴露各个站点名称。

成功发布需要你站点的域名托管在配置的 DNS 提供商处,并且可以使用给定凭据/提供商配置修改相应记录。

(需要 Caddy 2.10 测试版 1 或更高版本。)

on_demand_tls

配置启用位置的 按需 TLS,但仅配置并不启用它(要启用,请在 tls 指令中使用 on_demand 子指令](/caddyfile/directives/tls#syntax))。在生产环境中使用时需要该配置以防止滥用。

  • ask 会导致 Caddy 向给定 URL 发起 HTTP 请求,询问是否允许为某个域名签发证书。

    请求的查询字符串为 ?domain=,其值为域名。

    如果端点返回 2xx 状态码,Caddy 将被授权为该名称获取证书。任何其他状态码都会导致取消签发证书并使 TLS 握手出错。

  • permission 允许使用自定义模块来决定是否应为特定名称签发证书。该模块必须实现 caddytls.OnDemandPermission 接口。包含一个 http permission 模块,这就是 ask 选项使用的模块,并作为向后兼容的快捷方式保留。

  • ⚠️ 以前可用的速率限制选项 intervalburst 不再推荐使用。如果你的配置中仍有它们,请将其移除。

{
	on_demand_tls {
		ask http://localhost:9123/ask
	}
}

https:// {
	tls {
		on_demand
	}
}
key_type

指定为 TLS 证书生成的密钥类型;只有在有特定需求时才更改此项。

可能的值:ed25519p256p384rsa2048rsa4096

{
	key_type ed25519
}
cert_issuer

定义 TLS 证书的签发者(或来源)。

这允许在全局配置签发者,而不是像在站点级别使用 tls 指令的 issuer 子指令 那样逐站点配置。

可重复使用以配置多个要尝试的签发者。它们将按定义的顺序尝试。

{
	cert_issuer acme {
		...
	}
	cert_issuer zerossl {
		...
	}
}
renew_interval

扫描所有已加载的受管理证书的频率,并在到期时触发续期。

默认:10m

{
	renew_interval 30m
}
cert_lifetime

请求 CA 签发证书的有效期。

此值用于计算 ACME 订单的 notAfter 字段;因此系统必须具有合理同步的时钟。注意:并非所有 CA 都支持此项。请查看你的 CA 的 ACME 文档以了解是否允许以及可使用的值。

默认:0(由 CA 选择有效期,通常为 90 天)

⚠️ 这是一个实验性功能。可能更改或移除。

{
	cert_lifetime 30d
}
ocsp_interval

检查 OCSP staple 是否需要更新的频率。

默认:1h

{
	ocsp_interval 2h
}
ocsp_stapling

可以设置为 off 以禁用 OCSP stapling。在由于防火墙导致无法访问响应者的环境中很有用。

{
	ocsp_stapling off
}
preferred_chains

如果你的 CA 提供多个证书链,你可以使用此选项指定 Caddy 应偏好的链。设置以下选项之一:

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

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

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

注意,如果在全局选项中指定 preferred_chains,并且没有任何覆盖的签发者级别配置,则这将影响所有签发者。

{
	preferred_chains smallest
}
{
	preferred_chains {
		root_common_name "ISRG Root X2"
	}
}

服务器选项

定制可能跨多个站点的 HTTP 服务器 的设置,这些设置因此不能在站点块中正确配置。这些选项影响监听器/套接字或 HTTP 层之下的其他设施。

可以为不同的 listener_address 值多次指定 servers,以对不同服务器进行配置。例如,servers :443 只会应用于绑定到监听地址 :443 的服务器。省略监听地址将把选项应用于任何剩余的服务器。

例如,要为端口 :80:443 上的服务器配置不同选项,你可以指定两个 servers 块:

{
	servers :443 {
		listener_wrappers {
			http_redirect
			tls
		}
	}

	servers :80 {
		protocols h1 h2c
	}
}

当使用 servers 时,它只会应用于在你的 Caddyfile 中实际出现的服务器(即由站点块产生的服务器)。请记住,自动 HTTPS 会在运行时创建一个监听端口 80 的服务器(或使用 http_port 选项)用于 HTTP->HTTPS 重定向和解决 ACME HTTP 挑战;这发生在运行时,即在 Caddyfile 适配器应用 servers 之后。换句话说,这意味着除非你显式声明了 http://:80 这样的站点块,否则 servers 不会应用于 :80

name

为该服务器分配自定义名称。通常有助于在日志和指标中通过名称识别服务器。如果未设置,Caddy 会动态使用 srvX 模式定义名称,其中 X0 开始并根据配置中的服务器数量递增。

请记住,只有由配置中的站点块产生的服务器才会应用设置。自动 HTTPS 在运行时会创建一个 :80 服务器(或使用 http_port),因此如果你想重命名它,你至少需要一个空的 http:// 站点块。

例如:

{
	servers :443 {
		name https
	}
	
	servers :80 {
		name http
	}
}

example.com {
}

http:// {
}
listener_wrappers

允许配置 listener wrappers,它们可以修改套接字监听器的行为。它们按给定顺序应用。

tls

tls listener wrapper 是一个无操作的监听器包装器,用以标记 TLS 监听器在监听器包装链中的位置。只有当另一个监听器包装需要放在 TLS 握手之前时才应使用它。

http_redirect

http_redirect 为在 TLS 端口上以 HTTP 请求形式到来的连接提供 HTTP->HTTPS 重定向,方法是在最初的几个字节中检测到它不是 TLS 握手而是 HTTP 请求。当在非标准端口(非 443)上提供 HTTPS 时这最有用,因为浏览器会尝试 HTTP,除非指定了方案。它必须放在 tls listener wrapper 之前。示例:

{
	servers {
		listener_wrappers {
			http_redirect
			tls
		}
	}
}
proxy_protocol

proxy_protocol listener wrapper(在 v2.7.0 之前仅作为插件提供)启用对 PROXY 协议 的解析(由 HAProxy 推广)。由于它在连接开始时解析明文数据,因此必须在 tls listener wrapper 之前使用:

proxy_protocol {
	timeout <duration>
	allow <cidrs...>
	deny <cidrs...>
	fallback_policy <policy>
}
  • timeout 指定等待 PROXY 头的最长时间。默认为 5s

  • allow 是一个可信来源 CIDR 范围列表,用于接收 PROXY 头。Unix 套接字默认被信任,不属于此选项。

  • deny 是一个拒绝接收 PROXY 头的 CIDR 范围列表。

  • fallback_policy 是当 PROXY 头来自既不在 allow 也不在 deny 列表中的地址时要采取的动作。默认回退策略是 ignorefallback_policy 的可接受值为:

    • ignore:使用 PROXY 头中的地址,但接受连接
    • use:使用 PROXY 头中的地址
    • reject:当发送 PROXY 头时拒绝连接
    • require:要求连接发送 PROXY 头,未发送则拒绝
    • skip:接受连接但不要求 PROXY 头

例如,对于需要 tls listener wrapper 的 HTTPS 服务器,接受来自特定 IP 范围的 PROXY 头并拒绝来自另一个范围的 PROXY 头,超时时间为 2 秒:

{
	servers {
		listener_wrappers {
			proxy_protocol {
				timeout 2s
				allow 192.168.86.1/24 192.168.86.1/24
				deny 10.0.0.0/8
				fallback_policy reject
			}
			tls
		}
	}
}
timeouts
  • read_body 是一个 持续时间值,用于设置允许从客户端上传读取的最长时间。将其设置为较短的非零值可以缓解 slowloris 攻击,但也可能影响合法的慢速客户端。默认没有超时。

  • read_header 是一个 持续时间值,用于设置允许读取客户端请求头的最长时间。默认没有超时。

  • write 是一个 持续时间值,用于设置允许向客户端写入的最长时间。请注意,在传输大文件时将此值设置得很小可能会对合法的慢速客户端产生负面影响。默认没有超时。

  • idle 是一个 持续时间值,用于在启用 keep-alives 时等待下一个请求的最大时间。默认值为 5 分钟,以帮助避免资源耗尽。

{
	servers {
		timeouts {
			read_body   10s
			read_header 5s
			write       30s
			idle        10m
		}
	}
}
keepalive_interval

在没有其他数据传输时,为在 TCP 层保持连接存活而发送 TCP keepalive 数据包的间隔。默认值为 15s

{
	servers {
		keepalive_interval 30s
	}
}
trusted_proxies

允许配置应被信任的代理服务器的 IP 范围(CIDR)。默认情况下不信任任何代理。

启用此项会导致来自受信任代理的请求从 HTTP 头(默认是 X-Forwarded-For;参见 client_ip_headers 以配置其他头)中解析出真实客户端 IP。如果受信任,客户端 IP 会被添加到访问日志,可作为 {client_ip} 占位符 使用,并允许使用 client_ip 匹配器。如果请求不是来自受信任代理,则客户端 IP 设置为直接传入连接的远程 IP。默认情况下,头中的 IP 是从左到右解析的。参见 trusted_proxies_strict 可更改此行为。

某些匹配器或处理器可能会使用请求的信任状态来做出决策。例如,如果受信任,reverse_proxy 处理器将代理并增强敏感的 X-Forwarded-* 请求头。

目前,标准分发的 Caddy 仅包含 static IP 源模块,但可以通过插件扩展以维护动态 IP 范围列表。

static

接受一个静态(不变的)受信任 IP 范围(CIDR)列表。

作为简写,private_ranges 可用于匹配所有私有 IPv4 和 IPv6 范围。它等同于指定以下所有范围:192.168.0.0/16 172.16.0.0/12 10.0.0.0/8 127.0.0.1/8 fd00::/8 ::1

语法如下:

trusted_proxies static [private_ranges] <ranges...>

下面是一个完整示例,信任一个示例 IPv4 范围和一个 IPv6 范围:

{
	servers {
		trusted_proxies static 12.34.56.0/24 1200:ab00::/32
	}
}
trusted_proxies_strict

当启用 trusted_proxies 时,头(由 client_ip_headers 配置)中的 IP 默认从左到右解析。第一个未被信任的 IP 地址将成为真实客户端地址。自 v2.8 起,你可以通过启用 trusted_proxies_strict 选择从右到左解析这些头。默认情况下,为了向后兼容,此选项被禁用。

上游代理(如 HAProxy、CloudFlare、AWS ALB、CloudFront 等)通常会将每个新的连接远程地址追加到 X-Forwarded-For 的右侧。建议在与这些代理一起使用时启用 trusted_proxies_strict,因为最左侧的 IP 可能会被客户端伪造。

{
	servers {
		trusted_proxies static private_ranges
		trusted_proxies_strict
	}
}
client_ip_headers

trusted_proxies 配合使用,允许配置用于确定客户端 IP 的头。默认情况下,仅考虑 X-Forwarded-For。可以指定多个头字段,在这种情况下将使用第一个非空的头值。

{
	servers {
		trusted_proxies static private_ranges
		client_ip_headers X-Forwarded-For X-Real-IP
	}
}
metrics

启用 Prometheus 指标收集;在抓取指标之前必须启用。请注意,在非常繁忙的服务器上启用指标会降低性能。(我们的社区正在努力改进此点,欢迎参与!)

{
	metrics
}

你可以添加 per_host 选项以用主机名对指标进行标注。

{
	metrics {
		per_host
	}
}
trace

记录每个被调用的处理器。要求日志在 DEBUG 级别输出(可使用 debug 全局选项 来设置)。

注意:这可能会记录你的 HTTP 处理模块的配置;当配置中包含敏感数据且运行环境不安全时,请不要启用此项。

⚠️ 这是一个实验性功能。可能更改或移除。

{
	servers {
		trace
	}
}
max_header_size

解析客户端 HTTP 请求头的最大大小。如果超出限制,服务器将以 HTTP 状态 431 Request Header Fields Too Large 响应。接受 go-humanize 支持的所有格式(https://github.com/dustin/go-humanize/blob/master/bytes.go)。默认限制为 1MB

{
	servers {
		max_header_size 5MB
	}
}
enable_full_duplex

为 HTTP/1 请求启用全双工通信。仅在使用 Go 1.21 或更高版本构建 Caddy 时生效。

对于 HTTP/1 请求,Go 的 HTTP 服务器默认会在开始写响应之前读取并消费请求体中未读取的部分,阻止处理器在写响应的同时并发地从请求中阅读。启用此选项会禁用此行为,允许处理器在并发写响应的同时继续读取请求。

对于 HTTP/2+ 请求,Go HTTP 服务器始终允许并发读取和响应,因此此选项对其没有影响。

请使用你的 HTTP 客户端进行充分测试,因为某些旧客户端可能不支持 HTTP/1 的全双工,这可能导致其死锁。详见 golang/go#57786

⚠️ 这是一个实验性功能。可能更改或移除。

{
	servers {
		enable_full_duplex
	}
}
log_credentials

默认情况下,包含可能敏感信息的头(CookieSet-CookieAuthorizationProxy-Authorization)的访问日志(通过 log 指令 启用)将被记录为 REDACTED

如果你不希望这些头被遮盖,可以启用 log_credentials 选项。

{
	servers {
		log_credentials
	}
}
protocols

要支持的以空格分隔的 HTTP 协议列表。

默认:h1 h2 h3

接受的值有:

  • h1 表示 HTTP/1.1
  • h2 表示 HTTP/2
  • h2c 表示明文 HTTP/2(H2 over cleartext)
  • h3 表示 HTTP/3

当前,启用 HTTP/2(包括 H2C)必然意味着启用 HTTP/1.1,因为 Go 标准库在使用其 HTTP 服务器时不允许我们禁用 HTTP/1.1。然而,HTTP/1.1 或 HTTP/3 可以独立启用。

注意,H2C(“明文 HTTP/2”)和 HTTP/3 并非由 Go 标准库实现,因此某些功能或特性可能受限。除非绝对必要,否则我们不建议启用 H2C。

{
	servers :80 {
		protocols h1 h2c
	}
}
strict_sni_host

启用此项将要求请求的 Host 头与客户端 TLS ClientHello 发送的 ServerName 值匹配,这是在使用 TLS 客户端认证时的必要安全措施。如果不匹配,服务器将向客户端写入 HTTP 状态 421 Misdirected Request

如果配置了客户端认证,此选项会自动开启。它阻止 TLS 客户端认证绕过(域名伪装),否则可能被滥用:在 TLS 握手期间发送未受保护的 SNI 值,然后在建立连接后在 Host 头中放置受保护的域名。该行为是安全的默认值,但你可以显式用 insecure_off 关闭它;例如在运行代理且希望允许域名前置且访问不基于主机名受限的情况下。

{
	servers {
		strict_sni_host on
	}
}

文件系统

filesystem 全局选项允许声明一个或多个可用于文件 I/O 的文件系统。

这可以让你连接到运行在云端的远程文件系统、具有类文件接口的数据库,甚至读取嵌入在 Caddy 二进制中的文件。

文件系统以名称声明以便识别。这意味着如果需要,你可以连接到多个同类型的文件系统实例。

默认情况下,Caddy 不包含任何文件系统模块,因此你需要使用对应文件系统的插件构建 Caddy。

示例

使用一个虚拟的 custom 文件系统模块,你可以声明两个文件系统:

{
	filesystem foo custom {
		...
	}

	filesystem bar custom {
		...
	}
}

foo.example.com {
	fs foo
	file_server
}

foo.example.com {
	fs bar
	file_server
}

PKI 选项

PKI(公钥基础设施)应用是 Caddy 的 本地 HTTPSACME 服务器 功能的基础。该应用定义了能够签发证书的证书颁发机构(CA)。

默认的 CA ID 为 local。如果在配置 ca 时省略 ID,则假定为 local

name

证书颁发机构面向用户的名称。

默认:Caddy Local Authority

{
	pki {
		ca local {
			name "My Local CA"
		}
	}
}
root_cn

根证书的 CommonName 字段中要使用的名称。

默认:{pki.ca.name} - {time.now.year} ECC Root

{
	pki {
		ca local {
			root_cn "My Local CA - 2024 ECC Root"
		}
	}
}
intermediate_cn

中间证书的 CommonName 字段中要使用的名称。

默认:{pki.ca.name} - ECC Intermediate

{
	pki {
		ca local {
			intermediate_cn "My Local CA - ECC Intermediate"
		}
	}
}
intermediate_lifetime

中间证书的有效期(持续时间)。此值必须小于根证书的生命周期(3600d 或 10 年)。

默认:7d。除非绝对必要,否则不建议更改此值。

{
	pki {
		ca local {
			intermediate_lifetime 30d
		}
	}
}
root

用于作为 CA 根的密钥对(证书和私钥)。如果未指定,将自动生成并管理。

  • format 指定提供证书和私钥的格式。目前仅支持 pem_file,这是默认值,所以该字段可选。
  • cert 指证书。使用 pem_file 格式时,应为 PEM 文件路径。
  • key 指私钥。使用 pem_file 格式时,应为 PEM 文件路径。
intermediate

用于作为 CA 中间证书的密钥对(证书和私钥)。如果未指定,将自动生成并管理。

  • format 指定提供证书和私钥的格式。目前仅支持 pem_file,这是默认值,所以该字段可选。
  • cert 指证书。使用 pem_file 格式时,应为 PEM 文件路径。
  • key 指私钥。使用 pem_file 格式时,应为 PEM 文件路径。
{
	pki {
		ca local {
			root {
				format pem_file
				cert /path/to/root.pem
				key /path/to/root.key
			}
			intermediate {
				format pem_file
				cert /path/to/intermediate.pem
				key /path/to/intermediate.key
			}
		}
	}
}

事件选项

当 Caddy 模块发生有趣的事情(或即将发生)时,会发出事件。

事件通常包含元数据负载。了解事件及其负载的最好方式是查看各模块的文档,但你也可以通过启用 debug 全局选项 并阅读日志来查看事件及其数据负载。

on

将事件处理器绑定到指定名称的事件。指定事件处理器模块的名称,随后跟随其配置。

例如,在获取证书后运行命令(需要第三方插件 https://github.com/mholt/caddy-events-exec),并使用占位符将事件负载的一部分传递给脚本:

{
	events {
		on cert_obtained exec ./my-script.sh {event.data.certificate_path}
	}
}

事件

以下标准事件由 Caddy 发出:

插件也可能发出事件,请查阅它们的文档以获取详细信息。