ITADN

版本发布 8

v2.11.1
? · 2026-02-23

Our community is pleased to announce Caddy 2.11! Of note are new features, numerous bug fixes including several security patches, and various QoL ("quality-of-life") enhancements. There are no code changes from v2.11.0 other than to a CI job. Due to a recent external change that broke our release process, the first release of 2.11 is v2.11.1. ## Special Sponsor Shoutout Extra big thanks to our major sponsors: - [ZeroSSL](https://zerossl.com) - [Stripe](https://stripe.com) - [Railway](https://railway.com/?utm_medium=sponsor&utm_source=oss&utm_campaign=caddy) They, along with dozens of smaller sponsors, make this project and new releases possible, together with our maintainer team. Thank you all! ## Notable changes - Encrypted ClientHello (ECH) keys are rotated automatically. - Time-rolling options for logs. - `SIGUSR1` can now reload configuration if it was initially loaded from a file on the command line and did not get changed via the API. - Reverse proxy now automatically rewrites the Host header to the address of the upstream when the upstream is HTTPS (#7454) - `log_append` can now log request and response bodies, useful for debugging. - Our project now implements and requires Assistance Disclosures (for AI/LLMs) on issues, PRs, comments, replies, reviews, etc. - Many, many other minor improvements and bug fixes. Thank you to everyone who was involved this release! ### :warning: Security patches - fastcgi: `CVE-2026-27590` by @dunglas and @AbdrrahimDahmani - Unicode case-folding length expansion causes incorrect split_path index (SCRIPT_NAME/PATH_INFO confusion) in FastCGI transport. - admin: `CVE-2026-27589` by @1seal - Cross-origin requests attempted with `no-cors` mode could cause some API requests to succeed; such requests are now blocked. (In order for this to be practically exploitable, a web browser executing a malicious web page must be running locally to a production Caddy process.) - caddyhttp: `CVE-2026-27588` by Asim Viladi Oglu Manizada - The Host matcher becomes case-sensitive for large host lists (>100), enabling host-based route/auth bypass. - caddyhttp: `CVE-2026-27587` by Asim Viladi Oglu Manizada - The Path matcher skips case normalization for escape sequences, enabling path-based route/auth bypass. - caddytls: `CVE-2026-27586` by @moscowchill - TLS client authentication silently fails open when CA certificate file is missing or malformed. - caddyhttp: `CVE-2026-27585` by @parrot409 - Improper sanitization of glob characters in file matcher may lead to bypassing security protections. ## What's Changed * caddyhttp: add replacer placeholders for escaped values by @Qusic in https://github.com/caddyserver/caddy/pull/7181 * AI assistance disclosure by @mholt in https://github.com/caddyserver/caddy/pull/7212 * caddyfile: Prevent trailing space on line before env variable - Fixes #6881 by @arpansaha13 in https://github.com/caddyserver/caddy/pull/7215 * add: encode header Content-Type graphql-response by @aro-lew in https://github.com/caddyserver/caddy/pull/7214 * caddyhttp: Removing redundant middleware next copy by @maxcelant in https://github.com/caddyserver/caddy/pull/7217 * build(deps): bump the all-updates group with 17 updates by @dependabot[bot] in https://github.com/caddyserver/caddy/pull/7236 * build(deps): bump the actions-deps group with 5 updates by @dependabot[bot] in https://github.com/caddyserver/caddy/pull/7237 * encode: fix response corruption when handle_errors is used by @Siomachkin in https://github.com/caddyserver/caddy/pull/7235 * Fix PKI creation when auto_https is disabled (#7211) by @Siomachkin in https://github.com/caddyserver/caddy/pull/7238 * logging: Buffer the logs before config is loaded by @francislavoie in https://github.com/caddyserver/caddy/pull/7245 * fileserver: set Content-Length for precompressed files by @WeidiDeng in https://github.com/caddyserver/caddy/pull/7251 * refactor: use WaitGroup.Go to simplify code by @mickychang9 in https://github.com/caddyserver/caddy/pull/7253 * caddyfile: Allow `block` to do nothing if nothing passed to `import` by @BeeJay28 in https://github.com/caddyserver/caddy/pull/7206 * logging: Adjustments to BufferedLog to keep logs in the correct order by @francislavoie in https://github.com/caddyserver/caddy/pull/7257 * caddyhttp: Prevent commas in header values from being split in CLI commands by @gilbsgilbs in https://github.com/caddyserver/caddy/pull/7268 * update quic-go to v0.54.1 by @marten-seemann in https://github.com/caddyserver/caddy/pull/7273 * chore: ugh, lint fix... by @mohammed90 in https://github.com/caddyserver/caddy/pull/7275 * caddypki: check intermediate lifetime to actual root cert lifetime by @u5surf in https://github.com/caddyserver/caddy/pull/7272 * refactor: omit unnecessary reassignment by @asttool in https://github.com/caddyserver/caddy/pull/7276 * core: use reflect.TypeFor to check for encoding/json.RawMessage by @WeidiDeng in https://github.com/caddyserver/caddy/pull/7274 * core: Reloading with `SIGUSR1` if config never changed via admin by @francislavoie in https://github.com/caddyserver/caddy/pull/7258 * build(deps): bump the actions-deps group with 8 updates by @dependabot[bot] in https://github.com/caddyserver/caddy/pull/7284 * httpcaddyfile: Add missing DNS challenge check for `acme_dns` by @rightaditya in https://github.com/caddyserver/caddy/pull/7270 * httpcaddyfile: Map default_bind to BindHost in globalACMEDefaults by @Monviech in https://github.com/caddyserver/caddy/pull/7278 * Argon2id Support for Basic Auth by @GreyXor in https://github.com/caddyserver/caddy/pull/7186 * update quic-go to v0.55.0 by @marten-seemann in https://github.com/caddyserver/caddy/pull/7288 * reverse_proxy: use http1 for outbound tls requests with placeholder t… by @WeidiDeng in https://github.com/caddyserver/caddy/pull/7296 * caddyhttp: Add server options `keepalive_idle` and `keepalive_count` by @joshuamcbeth in https://github.com/caddyserver/caddy/pull/7298 * chore: fix some comments by @wyrapeseed in https://github.com/caddyserver/caddy/pull/7303 * logging: Switch from `lumberjack` to `timberjack`, add time-rolling options by @aeris in https://github.com/caddyserver/caddy/pull/7244 * reverseproxy: Use http1.1 upgrade for websocket for extended connect of http2 and http3. by @tonyb486 in https://github.com/caddyserver/caddy/pull/7305 * caddyhttp: Add `trusted_proxies_unix` for trusting unix socket `X-Forwarded-*` headers by @cseufert in https://github.com/caddyserver/caddy/pull/7265 * caddyhttp: wrap accepted connection to suppress tls.ConnectionState by @WeidiDeng in https://github.com/caddyserver/caddy/pull/7247 * logging: fix multiple regexp filters on same field (fixes #7049) by @s2010 in https://github.com/caddyserver/caddy/pull/7061 * intercept: use already buffered response if possible when intercepting by @WeidiDeng in https://github.com/caddyserver/caddy/pull/7028 * listeners: Add support for named socket activation by @Siomachkin in https://github.com/caddyserver/caddy/pull/7243 * reverseproxy: do not disable keepalive if proxy protocol is used by @WeidiDeng in https://github.com/caddyserver/caddy/pull/7300 * metrics: resolve per-host inifinite cardinality by @mohammed90 in https://github.com/caddyserver/caddy/pull/7306 * reverseproxy: use http.Protocols to handle h2c requests by @WeidiDeng in https://github.com/caddyserver/caddy/pull/6990 * refactor: use reflect.TypeFor by @wyrapeseed in https://github.com/caddyserver/caddy/pull/7313 * build(deps): bump the all-updates group across 1 directory with 2 updates by @dependabot[bot] in https://github.com/caddyserver/caddy/pull/7307 * build(deps): bump github.com/slackhq/nebula from 1.9.5 to 1.9.7 by @dependabot[bot] in https://github.com/caddyserver/caddy/pull/7315 * feat: switch to autoexport for OpenTelemetry span exporter by @PKeidel in https://github.com/caddyserver/caddy/pull/7317 * reverse_proxy: set default values for keepalive if only some of them are set by @WeidiDeng in https://github.com/caddyserver/caddy/pull/7318 * fix quote within quotes formatted incorrectly by fmt by @keystroke3 in https://github.com/caddyserver/caddy/pull/7045 * caddytls: correct documentation of `LeafFolderLoader` by @mohammed90 in https://github.com/caddyserver/caddy/pull/7327 * fix golangci-lint error G602 in caddyhttp by @cdenicola in https://github.com/caddyserver/caddy/pull/7334 * feat: allow customizing the Server header by @dunglas in https://github.com/caddyserver/caddy/pull/7338 * update quic-go to v0.56.0, enable qlog for HTTP/3 by @marten-seemann in https://github.com/caddyserver/caddy/pull/7345 * build(deps): bump the all-updates group with 4 updates by @dependabot[bot] in https://github.com/caddyserver/caddy/pull/7333 * feat: custom slog handlers for modules (log contextual data) by @dunglas in https://github.com/caddyserver/caddy/pull/7346 * ci: implement new release flow by @mohammed90 in https://github.com/caddyserver/caddy/pull/7341 * reverse_proxy: use interfaces to modify the behaviors of the transports by @WeidiDeng in https://github.com/caddyserver/caddy/pull/7353 * build(deps): bump golang.org/x/crypto from 0.43.0 to 0.45.0 by @dependabot[bot] in https://github.com/caddyserver/caddy/pull/7355 * update quic-go to v0.57.0 by @marten-seemann in https://github.com/caddyserver/caddy/pull/7359 * refactor: replace HasSuffix+TrimSuffix with CutSuffix by @ledigang in https://github.com/caddyserver/caddy/pull/7357 * Fix retries for requests with bodies by @chebyrash in https://github.com/caddyserver/caddy/pull/7360 * build(deps): bump the all-updates group with 3 updates by @dependabot[bot] in https://github.com/caddyserver/caddy/pull/7376 * ci: escape backticks in changelogs embedded in JS by @mohammed90 in https://github.com/caddyserver/caddy/pull/7382 * build(deps): bump github.com/smallstep/certificates from 0.28.4 to 0.29.0 by @dependabot[bot] in https://github.com/caddyserver/caddy/pull/7381 * caddypki: Add support for multiple intermediates in signing chain by @hslatman in https://github.com/caddyserver/caddy/pull/7057 * caddyhttp: Fix logging on wildcard sites when SkipUnmappedHosts is true by @francislavoie in https://github.com/caddyserver/caddy/pull/7372 * multiplexing: Introduce packet conn wrappers by @vnxme in https://github.com/caddyserver/caddy/pull/7180 * docs: add maybe template function documentation by @steffenbusch in https://github.com/caddyserver/caddy/pull/7388 * caddyhttp: create a placeholder for and log ech status by @WeidiDeng in https://github.com/caddyserver/caddy/pull/7328 * caddytls: fix preferred chains options by appending values instead of replacing by @okrc in https://github.com/caddyserver/caddy/pull/7387 * feat: mark Assert* functions as test helpers by @dunglas in https://github.com/caddyserver/caddy/pull/7380 * caddytls: ECH key rotation by @mholt in https://github.com/caddyserver/caddy/pull/7356 * caddytls: panic when using tls.ca_pool.source.http -> tls.ca by @Zenexer in https://github.com/caddyserver/caddy/pull/7393 * notify: implement windows service status and error notifications by @FreyreCorona in https://github.com/caddyserver/caddy/pull/7389 * caddyhttp: `{http.request.body_base64}` placeholder by @francislavoie in https://github.com/caddyserver/caddy/pull/7367 * chore: update tscert package to latest (aea342f6) by @willnorris in https://github.com/caddyserver/caddy/pull/7397 * logging: `log_append` Early option, Supports `{http.response.body}` by @francislavoie in https://github.com/caddyserver/caddy/pull/7368 * update quic-go to v0.58.0 by @marten-seemann in https://github.com/caddyserver/caddy/pull/7404 * cmd: add --json flag to list-modules by @pauloappbr in https://github.com/caddyserver/caddy/pull/7409 * Add span attributes to tracing module by @felix-hilden in https://github.com/caddyserver/caddy/pull/7269 * readme: fix fence by @mohammed90 in https://github.com/caddyserver/caddy/pull/7416 * build(deps): bump the all-updates group across 1 directory with 12 updates by @dependabot[bot] in https://github.com/caddyserver/caddy/pull/7421 * reverseproxy: make error chan bigger when reverse proxying websocket by @WeidiDeng in https://github.com/caddyserver/caddy/pull/7419 * headers: Make ApplyTo nil-safe by @tpaulus in https://github.com/caddyserver/caddy/pull/7426 * chore: Dumb `prealloc` lint fix by @francislavoie in https://github.com/caddyserver/caddy/pull/7430 * update quic-go to v0.59.0 by @marten-seemann in https://github.com/caddyserver/caddy/pull/7431 * reverseproxy: Avoid returning error if remote address is not an IP by @pauloappbr in https://github.com/caddyserver/caddy/pull/7429 * caddyfile: Fix indentation of multiline strings in fmt (#7425) by @pauloappbr in https://github.com/caddyserver/caddy/pull/7433 * core: Embed `time/tzdata` by @francislavoie in https://github.com/caddyserver/caddy/pull/7432 * caddyfile: add `observe_catchall_hosts` option by @mohammed90 in https://github.com/caddyserver/caddy/pull/7434 * core: Show JSON error offsets where possible by @francislavoie in https://github.com/caddyserver/caddy/pull/7437 * autohttps: deterministic logic and strict bind checking on Linux by @pauloappbr in https://github.com/caddyserver/caddy/pull/7435 * reverseproxy: Set `Host` to `{upstream_hostport}` automatically if TLS by @francislavoie in https://github.com/caddyserver/caddy/pull/7454 * reverseproxy: fix X-Forwarded-* headers for Unix socket requests by @XYenon in https://github.com/caddyserver/caddy/pull/7463 * chore: use math/rand/v2 instead of math/rand by @WeidiDeng in https://github.com/caddyserver/caddy/pull/7413 * chore: bump Go to v1.26 by @francislavoie in https://github.com/caddyserver/caddy/pull/7466 * acmeserver: warn when policy rules unset by @1seal in https://github.com/caddyserver/caddy/pull/7469 * caddytls: Return errors instead of nil in client auth provisioning by @moscowchill in https://github.com/caddyserver/caddy/pull/7464 * fix(deps): update nebula v1.10.3 to resolve cve by @omercnet in https://github.com/caddyserver/caddy/pull/7471 * caddyfile: Add renewal_window_ratio global option by @mehrdadbn9 in https://github.com/caddyserver/caddy/pull/7473 * httpcaddyfile: Override global `dns` with `acme_dns` (fix #7294) by @rightaditya in https://github.com/caddyserver/caddy/pull/7458 * pki: add per-CA configurable `maintenance_interval` and `renewal_window_ratio` by @Amirhf1 in https://github.com/caddyserver/caddy/pull/7479 * chore: Bump zerossl dependency to 0.1.5 by @francislavoie in https://github.com/caddyserver/caddy/pull/7489 * chore: Remove obsolete comment in `ech.go` by @francislavoie in https://github.com/caddyserver/caddy/pull/7487 * caddyhttp: Option to disable 0-RTT by @francislavoie in https://github.com/caddyserver/caddy/pull/7485 * dep: upgrade cel-go by @mohammed90 in https://github.com/caddyserver/caddy/pull/7478 * build(deps): bump the all-updates group across 1 directory with 12 updates by @dependabot[bot] in https://github.com/caddyserver/caddy/pull/7490 * refactor: use strings.Builder to improve performance by @zjumathcode in https://github.com/caddyserver/caddy/pull/7364 * chore: fix some comments to improve readability by @wangjingcun in https://github.com/caddyserver/caddy/pull/7395 * caddytls: Enable debug logging for DNSManager by @francislavoie in https://github.com/caddyserver/caddy/pull/7491 * caddytest: make TestReverseProxyHealthCheck deterministic with poll instead of sleep by @Amirhf1 in https://github.com/caddyserver/caddy/pull/7474 * admin: Fix tests locally, properly isolate storage by @francislavoie in https://github.com/caddyserver/caddy/pull/7486 * chore: Add nolints to work around haywire linters by @mholt in https://github.com/caddyserver/caddy/pull/7493 * build(deps): bump filippo.io/edwards25519 from 1.1.0 to 1.1.1 by @dependabot[bot] in https://github.com/caddyserver/caddy/pull/7497 * chore: Disable windows/arm build target (Go 1.26 disabled) by @francislavoie in https://github.com/caddyserver/caddy/pull/7503 ## New Contributors * @Qusic made their first contribution in https://github.com/caddyserver/caddy/pull/7181 * @arpansaha13 made their first contribution in https://github.com/caddyserver/caddy/pull/7215 * @aro-lew made their first contribution in https://github.com/caddyserver/caddy/pull/7214 * @maxcelant made their first contribution in https://github.com/caddyserver/caddy/pull/7217 * @Siomachkin made their first contribution in https://github.com/caddyserver/caddy/pull/7235 * @mickychang9 made their first contribution in https://github.com/caddyserver/caddy/pull/7253 * @asttool made their first contribution in https://github.com/caddyserver/caddy/pull/7276 * @rightaditya made their first contribution in https://github.com/caddyserver/caddy/pull/7270 * @Monviech made their first contribution in https://github.com/caddyserver/caddy/pull/7278 * @wyrapeseed made their first contribution in https://github.com/caddyserver/caddy/pull/7303 * @aeris made their first contribution in https://github.com/caddyserver/caddy/pull/7244 * @tonyb486 made their first contribution in https://github.com/caddyserver/caddy/pull/7305 * @cseufert made their first contribution in https://github.com/caddyserver/caddy/pull/7265 * @s2010 made their first contribution in https://github.com/caddyserver/caddy/pull/7061 * @PKeidel made their first contribution in https://github.com/caddyserver/caddy/pull/7317 * @cdenicola made their first contribution in https://github.com/caddyserver/caddy/pull/7334 * @ledigang made their first contribution in https://github.com/caddyserver/caddy/pull/7357 * @chebyrash made their first contribution in https://github.com/caddyserver/caddy/pull/7360 * @okrc made their first contribution in https://github.com/caddyserver/caddy/pull/7387 * @Zenexer made their first contribution in https://github.com/caddyserver/caddy/pull/7393 * @FreyreCorona made their first contribution in https://github.com/caddyserver/caddy/pull/7389 * @pauloappbr made their first contribution in https://github.com/caddyserver/caddy/pull/7409 * @felix-hilden made their first contribution in https://github.com/caddyserver/caddy/pull/7269 * @tpaulus made their first contribution in https://github.com/caddyserver/caddy/pull/7426 * @1seal made their first contribution in https://github.com/caddyserver/caddy/pull/7469 * @moscowchill made their first contribution in https://github.com/caddyserver/caddy/pull/7464 * @omercnet made their first contribution in https://github.com/caddyserver/caddy/pull/7471 * @mehrdadbn9 made their first contribution in https://github.com/caddyserver/caddy/pull/7473 * @Amirhf1 made their first contribution in https://github.com/caddyserver/caddy/pull/7479 * @zjumathcode made their first contribution in https://github.com/caddyserver/caddy/pull/7364 * @wangjingcun made their first contribution in https://github.com/caddyserver/caddy/pull/7395 **Full Changelog**: https://github.com/caddyserver/caddy/compare/v2.10.2...v2.11.1

v2.11.0-beta.1预发布
? · 2025-12-04

Welcome to the beta version of 2.11. This is the first release made by our [new, automated release process](https://github.com/caddyserver/caddy/pull/7383) developed by @Mohammed90 that was carried out and approved entirely by our maintainer team (together with @francislavoie) without intervention from @mholt, the original Caddy author. This represents a significant step forward in [project autonomy and growth](https://caddy.community/t/next-steps-for-the-caddy-project-maintainership/33076), ensuring that the project's stability and longevity is not reliant upon a single person. This first beta release was primarily to test our new workflow, so there's still a couple things left to do before the stable release. Featured here are numerous, mostly minor, bug fixes and enhancements, mostly affecting edge cases or niche corners of the software; for example, proxying H2C or HTTP/3, obscure Caddyfile scenarios, and named socket activation. Some notable changes: - SIGUSR1 can be used to reload configuration only if it was loaded from a file using the CLI, and not changed by the API since then. - We replaced "lumberjack", our logging library, with a fork "timberjack" that supports the oft-requested time-rolling ability. - Caddy can now bind listeners with named socket activation. Before the final release, we expect ECH key rotation to be enabled as well as a few other patches/features Thank you to our sponsors and contributors for all that you do! ## Changelog * 5473eb95d8e94505b8c06955bd200f37179c54a2 encode: fix response corruption when handle_errors is used (#7235) * 13a4ec7597f8e9ebe105b0ee89102ba521f21173 basicauth: Implement argon2id (#7186) * 6d90c7707dac3026c1b28fba615b1962d2cd45e1 build(deps): bump github.com/slackhq/nebula from 1.9.5 to 1.9.7 (#7315) * eead249382ac14c29d82ec75f30df7638e879567 build(deps): bump golang.org/x/crypto from 0.43.0 to 0.45.0 (#7355) * 2d0f3f887bc1f70c52fc183ebcc6225f7f91c041 build(deps): bump the actions-deps group with 5 updates (#7237) * afbdcec08bbd7471b9b5e5ed209881dfcc51bd6c build(deps): bump the actions-deps group with 8 updates (#7284) * cd1c203777e89a64c8426c049727c58fbebc1276 build(deps): bump the all-updates group across 1 directory with 2 updates (#7307) * 39357d3e5cb6124e8af651460cc8ab6975c637b8 build(deps): bump the all-updates group with 17 updates (#7236) * 786d5378771d068440b7ddd8c310851bb7b9afe0 build(deps): bump the all-updates group with 3 updates (#7376) * 07d2aaf22ef8225575b9557640806bc895067905 build(deps): bump the all-updates group with 4 updates (#7333) * 0ba8786b35eaec5ec53f8562bec9587e6b1e6a8b caddyfile: Allow `block` to do nothing if nothing passed to `import` (#7206) * 92c8bc73228aad9eb0b396fdb687c024124d8dbd caddyfile: fix nested quotes formatted incorrectly by fmt (#7045) * 6d73d85c1fd3d20acaaadc0fb69e3f562d92f685 caddyfile: prevent adding trailing space on line before env variable (#7215) * d7185fd002a2c57d20a98d3e94442da7b259b3ad caddyhttp: Add `trusted_proxies_unix` for trusting unix socket `X-Forwarded-*` headers (#7265) * de6b78009b840eb395c33b8d65c5d32746df38b6 caddyhttp: Add server options `keepalive_idle` and `keepalive_count` (#7298) * e0a8f9541d155b7385b78d2b8bbe2fad53bb6295 caddyhttp: Normalize (lowercase) {label.N} placeholders * 5e2953670ed7eecbc34146b5d12cca7dd85ac580 caddyhttp: add replacer placeholders for escaped values (#7181) * 8285eba8426e3c75ed81d6a8c5cd6ec685430d47 caddyhttp: allow customizing the Server header (#7338) * bc0e1841305b2cc82aeaf9953e527d9819a88c83 caddyhttp: omit unnecessary reassignment (#7276) * 3553cfb6adb2954a53d559c1841c8072b9921e61 caddyhttp: remove redundant middleware next copy (#7217) * 1ce2a13ad10eab5693b425056c571621f5d860e9 caddyhttp: wrap accepted connection to suppress tls.ConnectionState (#7247) * d9cc24f3df663e1bab58dc08ac12bf818c9f6852 caddypki: Disable internal auto-CA when auto_https is disabled (fix #7211) (#7238) * 1e82f9652ec561cc0c84bec501976045aa01a310 caddypki: check intermediate lifetime to actual root cert lifetime (#7272) * 38848f7f2525777edd0241ad3118f070e045d771 caddytls: Allow disabling distributed solving (except http-01) * ddec1838b39a1b61432db4e78f2e752f27c3c769 caddytls: correct documentation of `LeafFolderLoader` (#7327) * f5c3094050566d8d4fcf9f3ecf7d26f9c3241c65 cmd: prevent commas in header values from being split (#7268) * 65e0ddc22137bbbaa68c842ae0b98d0548504545 core: Reloading with `SIGUSR1` if config never changed via admin (#7258) * b3f2db233b5a71df6680b43d025bdb62ee2a999c core: custom slog handlers for modules (log contextual data) (#7346) * b2ab419922e0dabc2956611531f73a6169ecc46f core: use reflect.TypeFor to check for encoding/json.RawMessage (#7274) * 806fef85bedfc3fe178560afe6212c8ae90d3ebe encode: add graphql-response header to list (#7214) * 2cb426776c091febccc6b9a6669f1c5a745648a4 encode: modernize, replace HasSuffix+TrimSuffix with CutSuffix (#7357) * b462615439bf354dd1cb6780fb564b6a6c4a352c fileserver: set Content-Length for precompressed files (#7251) * 0c8798fce36b0915ff39288bff7eddfad2a1673f go.mod: update quic-go to v0.54.1 (#7273) * 3c003deec67ed1ca0127f4b303c64760a9a7b19d httpcaddyfile: Add missing DNS challenge check for `acme_dns` (#7270) * 2f1d270968e050105e3f6814b1ef7e7660ed41ba httpcaddyfile: Map default_bind to BindHost in globalACMEDefaults (#7278) * a7885aabec375db38ac6c221c7c709dc83122535 intercept: use already buffered response if possible when intercepting (#7028) * 156ce99d3a46be8cefe8502b2c30b757e4deb79f listeners: Add support for named socket activation (#7243) * 39ace450deb23a8ebb4f41ff4d8cfe2800d68118 logging: Adjustments to BufferedLog to keep logs in the correct order (#7257) * 012b4b3d40dae32502503c9d6bc6333acb135cb3 logging: Buffer the logs before config is loaded (#7245) * 10ac7da037828c5179ad7d04309fc8912f2fe0d5 logging: Switch from `lumberjack` to `timberjack`, add time-rolling options (#7244) * f5f25d845a814a600102614cc8836af5ebe1487b logging: fix multiple regexp filters on same field (fixes #7049) (#7061) * 595aab8bc0d98c510c044a2a6b8e7053aaf4e8fb metrics: resolve per-host inifinite cardinality (#7306) * 57587ed18e3908931b4f7bfd73078c47082fb742 refactor: use reflect.TypeFor (#7313) * 2ec28bca43e5269511f8d9c1656244dd84acdad9 reverse_proxy: use http1 for outbound tls requests with placeholder that are likely websockets (#7296) * a6da1acdc86199a7f99fa2347d5f91cd59ff90d8 reverse_proxy: use interfaces to modify the behaviors of the transports (#7353) * 67a9e0657e60df8c78510065e8977d86ee17d01c reverseproxy: Fix retries for requests with bodies (#7360) * 7fb39ec1e56751c82950fa8a35a189ea39dfa005 reverseproxy: Use http1.1 upgrade for websocket for extended connect of http2 and http3 (#7305) * 8aca108d2c9d9e9ff3a39ff00684ea58df1338f6 reverseproxy: do not disable keepalive if proxy protocol is used (#7300) * abe0acabb61b0151f58c7b750d3963dbbffe7270 reverseproxy: set default values for keepalive if only some of them are set (#7318) * 1e21b660c42485cb47287b595900446093d3df2b reverseproxy: use http.Protocols to handle h2c requests (#6990) * b54e870b26a23a98d81967c80d9e875f3a9e3c1d tracing: switch to autoexport for OpenTelemetry span exporter (#7317) ## What's Changed * caddyhttp: add replacer placeholders for escaped values by @Qusic in https://github.com/caddyserver/caddy/pull/7181 * AI assistance disclosure by @mholt in https://github.com/caddyserver/caddy/pull/7212 * caddyfile: Prevent trailing space on line before env variable - Fixes #6881 by @arpansaha13 in https://github.com/caddyserver/caddy/pull/7215 * add: encode header Content-Type graphql-response by @aro-lew in https://github.com/caddyserver/caddy/pull/7214 * caddyhttp: Removing redundant middleware next copy by @maxcelant in https://github.com/caddyserver/caddy/pull/7217 * build(deps): bump the all-updates group with 17 updates by @dependabot[bot] in https://github.com/caddyserver/caddy/pull/7236 * build(deps): bump the actions-deps group with 5 updates by @dependabot[bot] in https://github.com/caddyserver/caddy/pull/7237 * encode: fix response corruption when handle_errors is used by @Siomachkin in https://github.com/caddyserver/caddy/pull/7235 * Fix PKI creation when auto_https is disabled (#7211) by @Siomachkin in https://github.com/caddyserver/caddy/pull/7238 * logging: Buffer the logs before config is loaded by @francislavoie in https://github.com/caddyserver/caddy/pull/7245 * fileserver: set Content-Length for precompressed files by @WeidiDeng in https://github.com/caddyserver/caddy/pull/7251 * refactor: use WaitGroup.Go to simplify code by @mickychang9 in https://github.com/caddyserver/caddy/pull/7253 * caddyfile: Allow `block` to do nothing if nothing passed to `import` by @BeeJay28 in https://github.com/caddyserver/caddy/pull/7206 * logging: Adjustments to BufferedLog to keep logs in the correct order by @francislavoie in https://github.com/caddyserver/caddy/pull/7257 * caddyhttp: Prevent commas in header values from being split in CLI commands by @gilbsgilbs in https://github.com/caddyserver/caddy/pull/7268 * update quic-go to v0.54.1 by @marten-seemann in https://github.com/caddyserver/caddy/pull/7273 * chore: ugh, lint fix... by @mohammed90 in https://github.com/caddyserver/caddy/pull/7275 * caddypki: check intermediate lifetime to actual root cert lifetime by @u5surf in https://github.com/caddyserver/caddy/pull/7272 * refactor: omit unnecessary reassignment by @asttool in https://github.com/caddyserver/caddy/pull/7276 * core: use reflect.TypeFor to check for encoding/json.RawMessage by @WeidiDeng in https://github.com/caddyserver/caddy/pull/7274 * core: Reloading with `SIGUSR1` if config never changed via admin by @francislavoie in https://github.com/caddyserver/caddy/pull/7258 * build(deps): bump the actions-deps group with 8 updates by @dependabot[bot] in https://github.com/caddyserver/caddy/pull/7284 * httpcaddyfile: Add missing DNS challenge check for `acme_dns` by @rightaditya in https://github.com/caddyserver/caddy/pull/7270 * httpcaddyfile: Map default_bind to BindHost in globalACMEDefaults by @Monviech in https://github.com/caddyserver/caddy/pull/7278 * Argon2id Support for Basic Auth by @GreyXor in https://github.com/caddyserver/caddy/pull/7186 * update quic-go to v0.55.0 by @marten-seemann in https://github.com/caddyserver/caddy/pull/7288 * reverse_proxy: use http1 for outbound tls requests with placeholder t… by @WeidiDeng in https://github.com/caddyserver/caddy/pull/7296 * caddyhttp: Add server options `keepalive_idle` and `keepalive_count` by @joshuamcbeth in https://github.com/caddyserver/caddy/pull/7298 * chore: fix some comments by @wyrapeseed in https://github.com/caddyserver/caddy/pull/7303 * logging: Switch from `lumberjack` to `timberjack`, add time-rolling options by @aeris in https://github.com/caddyserver/caddy/pull/7244 * reverseproxy: Use http1.1 upgrade for websocket for extended connect of http2 and http3. by @tonyb486 in https://github.com/caddyserver/caddy/pull/7305 * caddyhttp: Add `trusted_proxies_unix` for trusting unix socket `X-Forwarded-*` headers by @cseufert in https://github.com/caddyserver/caddy/pull/7265 * caddyhttp: wrap accepted connection to suppress tls.ConnectionState by @WeidiDeng in https://github.com/caddyserver/caddy/pull/7247 * logging: fix multiple regexp filters on same field (fixes #7049) by @s2010 in https://github.com/caddyserver/caddy/pull/7061 * intercept: use already buffered response if possible when intercepting by @WeidiDeng in https://github.com/caddyserver/caddy/pull/7028 * listeners: Add support for named socket activation by @Siomachkin in https://github.com/caddyserver/caddy/pull/7243 * reverseproxy: do not disable keepalive if proxy protocol is used by @WeidiDeng in https://github.com/caddyserver/caddy/pull/7300 * metrics: resolve per-host inifinite cardinality by @mohammed90 in https://github.com/caddyserver/caddy/pull/7306 * reverseproxy: use http.Protocols to handle h2c requests by @WeidiDeng in https://github.com/caddyserver/caddy/pull/6990 * refactor: use reflect.TypeFor by @wyrapeseed in https://github.com/caddyserver/caddy/pull/7313 * build(deps): bump the all-updates group across 1 directory with 2 updates by @dependabot[bot] in https://github.com/caddyserver/caddy/pull/7307 * build(deps): bump github.com/slackhq/nebula from 1.9.5 to 1.9.7 by @dependabot[bot] in https://github.com/caddyserver/caddy/pull/7315 * feat: switch to autoexport for OpenTelemetry span exporter by @PKeidel in https://github.com/caddyserver/caddy/pull/7317 * reverse_proxy: set default values for keepalive if only some of them are set by @WeidiDeng in https://github.com/caddyserver/caddy/pull/7318 * fix quote within quotes formatted incorrectly by fmt by @keystroke3 in https://github.com/caddyserver/caddy/pull/7045 * caddytls: correct documentation of `LeafFolderLoader` by @mohammed90 in https://github.com/caddyserver/caddy/pull/7327 * fix golangci-lint error G602 in caddyhttp by @cdenicola in https://github.com/caddyserver/caddy/pull/7334 * feat: allow customizing the Server header by @dunglas in https://github.com/caddyserver/caddy/pull/7338 * update quic-go to v0.56.0, enable qlog for HTTP/3 by @marten-seemann in https://github.com/caddyserver/caddy/pull/7345 * build(deps): bump the all-updates group with 4 updates by @dependabot[bot] in https://github.com/caddyserver/caddy/pull/7333 * feat: custom slog handlers for modules (log contextual data) by @dunglas in https://github.com/caddyserver/caddy/pull/7346 * ci: implement new release flow by @mohammed90 in https://github.com/caddyserver/caddy/pull/7341 * reverse_proxy: use interfaces to modify the behaviors of the transports by @WeidiDeng in https://github.com/caddyserver/caddy/pull/7353 * build(deps): bump golang.org/x/crypto from 0.43.0 to 0.45.0 by @dependabot[bot] in https://github.com/caddyserver/caddy/pull/7355 * update quic-go to v0.57.0 by @marten-seemann in https://github.com/caddyserver/caddy/pull/7359 * refactor: replace HasSuffix+TrimSuffix with CutSuffix by @ledigang in https://github.com/caddyserver/caddy/pull/7357 * Fix retries for requests with bodies by @chebyrash in https://github.com/caddyserver/caddy/pull/7360 * build(deps): bump the all-updates group with 3 updates by @dependabot[bot] in https://github.com/caddyserver/caddy/pull/7376 * ci: escape backticks in changelogs embedded in JS by @mohammed90 in https://github.com/caddyserver/caddy/pull/7382 ## New Contributors * @Qusic made their first contribution in https://github.com/caddyserver/caddy/pull/7181 * @arpansaha13 made their first contribution in https://github.com/caddyserver/caddy/pull/7215 * @aro-lew made their first contribution in https://github.com/caddyserver/caddy/pull/7214 * @maxcelant made their first contribution in https://github.com/caddyserver/caddy/pull/7217 * @Siomachkin made their first contribution in https://github.com/caddyserver/caddy/pull/7235 * @mickychang9 made their first contribution in https://github.com/caddyserver/caddy/pull/7253 * @asttool made their first contribution in https://github.com/caddyserver/caddy/pull/7276 * @rightaditya made their first contribution in https://github.com/caddyserver/caddy/pull/7270 * @Monviech made their first contribution in https://github.com/caddyserver/caddy/pull/7278 * @wyrapeseed made their first contribution in https://github.com/caddyserver/caddy/pull/7303 * @aeris made their first contribution in https://github.com/caddyserver/caddy/pull/7244 * @tonyb486 made their first contribution in https://github.com/caddyserver/caddy/pull/7305 * @cseufert made their first contribution in https://github.com/caddyserver/caddy/pull/7265 * @s2010 made their first contribution in https://github.com/caddyserver/caddy/pull/7061 * @PKeidel made their first contribution in https://github.com/caddyserver/caddy/pull/7317 * @cdenicola made their first contribution in https://github.com/caddyserver/caddy/pull/7334 * @ledigang made their first contribution in https://github.com/caddyserver/caddy/pull/7357 * @chebyrash made their first contribution in https://github.com/caddyserver/caddy/pull/7360 **Full Changelog**: https://github.com/caddyserver/caddy/compare/v2.10.2...v2.11.0-beta.1

v2.10.0
? · 2025-04-18

Caddy 2.10 is here! Aside from bug fixes, this release features: - **Encrypted ClientHello (ECH):** This new technology encrypts the last plaintext portion of a TLS connection: the ClientHello, which includes the domain name being connected to. The [draft spec](https://www.ietf.org/archive/id/draft-ietf-tls-esni-24.html) for ECH is almost finalized, so we can now support this privacy feature for TLS. This is a powerful but nuanced capability; we highly recommend reading [the ECH documentation](https://caddyserver.com/docs/automatic-https#encrypted-clienthello-ech) on our website. - **Post-quantum (PQC) key exchange:** Caddy now supports the standardized `x25519mlkem768` cryptographic group by default. - **ACME profiles:** ACME profiles are an experimental draft that allow you to choose properties of your certificates with more flexibility than traditional CSR methods. For example, [Let's Encrypt will issue 6-day certificates](https://letsencrypt.org/2025/01/16/6-day-and-ip-certs/) under a certain profile. Caddy may eventually use that profile by default. - **Via header:** The reverse proxy now sets a Via header instead of a duplicate Server header. - **Global DNS provider:** You can now specify a default "global" DNS module to use instead of having to configure it locally in every part of your config that requires a DNS provider (for example, ACME DNS challenges, and ECH). This is the `dns` global option in the Caddyfile, or in JSON config, it's the `dns` parameter in the `tls` app configuration. - **Wildcards used by default:** Previously, Caddy would obtain individual certificates for every domain in your config literally; now wildcards, if present, will be utilized for subdomains, rather than obtaining individual certificates. This change was motivated by the novel possibility for subdomain privacy afforded by ECH. It can be overridden with `tls force_automate` in the Caddyfile. The experimental `auto_https prefer_wildcard` option has been removed. - **libdns 1.0 APIs:** Many of you use [DNS provider modules](https://github.com/caddy-dns) to solve ACME DNS challenges or to enable dynamic DNS. They implement interfaces defined by [libdns](https://github.com/libdns/libdns) to get, set, append, and delete DNS records. After 5 years of production experience, including lessons learned with ECH, libdns APIs have been updated and 1.0 beta has been tagged. DNS provider packages will need to update their code to be compatible, which will help ensure stability and well-defined semantics for the future. Several packages have already updated or are in the process of updating (cloudflare, rfc2136, and desec to name a few). - **Global `dns` config:** Now that several components of Caddy configuration may affect DNS records (ACME challenges, ECH publication, etc.), there is a new `dns` global option that can be used to specify your DNS provider config in a single place. This prevents repetition of credentials for servers where all the domains are managed by a single DNS provider. **Thank you to the many contributors who have helped to make this possible!** :tada: :partying_face: :champagne: :warning: While have traditionally supported the last 2 minor Go versions to accommodate some distribution / package manager policies, we now only support the latest minor Go version. The privacy and security benefits added in new Go versions (such as post-quantum cryptography) are worth making available to everyone as soon as possible, rather than holding back the entire user base or maintaining multiple code compilation configurations. ## Encrypted ClientHello (ECH) details (This is a brief overview. We recommend reading [the full documentation](https://caddyserver.com/docs/automatic-https#encrypted-clienthello-ech).) Typically, server names (domain names, or "SNI") are sent in the plaintext ClientHello when establishing TLS connections. With ECH, the true server name is encrypted (and wrapped) by an "outer" ClientHello which has a generic SNI of your choosing. With many sites on the same server sharing the same outer SNI, both clients and the server have more privacy related to domain names. Caddy implements fully automated ECH, meaning that it generates (and [soon](https://github.com/golang/go/issues/71920), rotates), publishes, and serves ECH configurations simply by specifying a DNS provider, and the outer/public domain name to use. **Fully automated ECH requires a DNS module built into your Caddy binary.** In order for a client, such as a browser, to know it can use ECH, and what parameters to use, the server's ECH configuration must be published. This config includes the public name, cryptographic parameters, and a public key for encrypting the inner ClientHello. By convention, browsers read the standardized HTTPS-type DNS record containing a `ech` SvcParamKey. Caddy sets this DNS record for all domains being protected, but it needs that DNS provider module plugged in and configured in order to do this. If you are already using the DNS ACME challenge, you should already have a DNS provider plugged in. If you prefer to build Caddy from source with [a DNS module](https://github.com/caddy-dns), it's easy with [xcaddy](https://github.com/caddyserver/xcaddy), for example: `$ xcaddy build --with github.com/caddy-dns/cloudflare` The minimum config needed to enable ClientHello is also the _recommended_ config, as it maximizes privacy benefits in most situations. You just need the `ech` global option and a DNS provider specified. Here's an example using Cloudflare as the nameserver: **Caddyfile:** ```caddy { debug # not required; recommended while testing dns cloudflare {env.CLOUDFLARE_API_KEY} ech ech.example.net } example.com { respond "Hello there!" } ``` This protects all your sites (`example.com` in this case) behind the public name of `ech.example.net`. (As another example, Cloudflare uses `cloudflare-ech.com` for all the sites it serves. We recommend choosing a single public domain and use it to protect all your sites.) **The outer/public name you choose should point to your server.** Caddy will obtain a certificate for this name in order to facilitate safe, reliable connections for clients when needed. Without a certificate, clients may be forced to connect insecurely, or fail to connect at all, in some cases, which not only leaves them vulnerable, but also risks exposing the names of your server's sites. Caddy then uses the specified DNS provider to publish the ECH config(s) for your various site names. It creates (or augments) HTTPS-type records for the domains of your sites (not your ECH public name). Note that DNS provider modules are independently-maintained, and may not have been tested for compatibility with HTTPS-type records. Please contact your module's maintainers if you experience issues. If you have more advanced configuration needs, you can use the JSON configuration (more details coming soon; for now, see #6862 or look at the source code; or use `caddy adapt` to convert a Caddyfile to JSON). ### Testing and verifying Encrypted ClientHello First make sure Caddy runs successfully with ECH enabled (and a DNS module) in the config. You should see logs that it is generating an ECH config and publishing it to your domain name(s). You will need to use a client that supports ECH. Some custom builds of `curl` do, and Firefox and modern Chrome-based browsers do as well, but you need to enable DNS-over-HTTPS or DNS-over-TLS first (since, obviously, querying DNS in plaintext for a protected domain name will expose the domain and defeat the purpose of ECH). If reusing an existing domain name, clear your DNS cache. Firefox has a way of doing this for its cache at `about:networking#dns`. Once you have a suitable client, use [Wireshark](https://www.wireshark.org/) to capture network packets as you load your site. You should see _only_ the outer/public name as SNI (ServerName Indicator) values in the packet capture. If at any time you see the true site name, ECH is not working properly -- it could be a client or server issue. Before filing a bug, please try to pinpoint it as a server issue first. But definitely report server bugs! Thank you! (Note that ECH is not automatically published for CNAME'd domains, and the domain must already have a record in the zone.) ## Commits ### Beta 1: * 96c5c554c1241430ac9ddea6f4b68948adcc961b admin: fix index validation for PUT requests (#6824) * 3644ee31cae8e20493d7ccd0c55b0a9c21f20693 build(deps): bump github.com/cloudflare/circl from 1.3.3 to 1.3.7 (#6876) * eacd7720e99f51b6d2dd340849897c0ff812b8c8 build(deps): bump github.com/go-jose/go-jose/v3 from 3.0.3 to 3.0.4 (#6871) * 9996d6a70ba76a94dfc90548f25fbac0ce9da497 build(deps): bump github.com/golang/glog from 1.2.2 to 1.2.4 (#6814) * 11151586165946453275b66ef33794d41a5e047b caddyhttp: ResponseRecorder sets stream regardless of 1xx * 8861eae22350d9e8f94653db951faf85a50a82da caddytest: Support configuration defaults override (#6850) * d7764dfdbbee04d2f63aa1b05150737dfddc0bcf caddytls: Encrypted ClientHello (ECH) (#6862) * a807fe065959baa8ee2ad95156183c0850c2b584 caddytls: Enhance ECH documentation * bc3d497739444a5ce550696b7b0da36e6e3bc777 caddytls: Fix broken refactor * 7b8f3505e33139de0d542566478e98b361bb84bf caddytls: Fix sni_regexp matcher to obtain layer4 contexts (#6804) * 2c4295ee48f494bc8dda5fa09b37612d520c8b3b caddytls: Initial support for ACME profiles * d7872c3bfa673ce9584d00f01a725b93fa7bedf1 caddytls: Refactor sni matcher (#6812) * 172136a0a0f6aa47be4eab3727fa2482d7af6617 caddytls: Support post-quantum key exchange mechanism X25519MLKEM768 * 066d770409917b409d0bdc14cb5ba33d3e4cb33e cmd: automatically set GOMEMLIMIT (#6809) * 1f35a8a4029a338e89998acafa95e1e931a46a27 fastcgi: improve parsePHPFastCGI docs (#6779) * 22563a70eb7b590fcb698680a3ec6d76c0968748 file_server: use the UTC timezone for modified time (#6830) * cfc3af67492eba22686fd13a2b2201c66cd737f3 fix: update broken link to Ardan Labs (#6800) * 99073eaa33af62bff51c31305e3437c57d936284 go.mod: Upgrade CertMagic to v0.21.7 * 1641e76fd742408c85363e4826451ba9ef22bc99 go.mod: Upgrade dependencies * 0d7c63920daecec510202c42816c883fd2dbe047 go.mod: remove glog dependency (#6838) * 932dac157a3c4693b80576477498bb86208b9b30 logging: Always set fields func; fix #6829 * 9e0e5a4b4c2babda81c58f28fe61adfa91d04524 logging: Fix crash if logging error is not HandlerError (#6777) * 904a0fa368b7eacac3c7156ce4a1f6ced8f61f34 reverse_proxy: re-add healthy upstreams metric (#6806) * e7da3b267bcec986aaca960dd22ef834d3b9d4a6 reverseproxy: Via header (#6275) * 9283770f68f570f47ca20aa9c6f9de8cc50063ba reverseproxy: ignore duplicate collector registration error (#6820) ### Beta 2: * f4432a306ac59feee1fc45c8efefad3619e37629 caddyfile: add error handling for unrecognized subdirective/options in various modules (#6884) * 84364ffcd06e35a93c9bb08ed80617bde72d4f74 caddypki: Remove lifetime check at Caddyfile parse (fix #6878) * adbe7f87e6bda96a1dddd94ecedefe3219a5304d caddytls: Only make DNS solver if not already set (fix #6880) * d57ab215a2f198a465ea33abe4588bb5696e7abd caddytls: Pointer receiver (fix #6885) * 4ebcfed9c942c59f473f12f8108e1d0fa92e0855 caddytls: Reorder provisioning steps (fix #6877) * a686f7c346fe011ad153a3bd4ac3e31e6758bcce cmd: Only set memory/CPU limits on run (fix #6879) * 19876208c79a476a46beec2430e554d4161ab426 cmd: Promote undo maxProcs func to caller * 220cd1c2bcecc07bcf6a0141069538c1b1109907 reverseproxy: more comments about buffering and add new tests (#6778) ### Beta 3: * b3e692ed09f8ba15b741621c4b16d8bfee38f8a1 caddyfile: Fix formatting for backquote wrapped braces (#6903) * 55c89ccf2a39dcfd7286fcaed54787821ff9a1aa caddytls: Convert AP subjects to punycode * 1f8dab572ca9681464fdadc65bfb5f250fc496c3 caddytls: Don't publish ECH configs if other records don't exist * 782a3c7ac60c82311fe9fb8889dd843dfe26c0bc caddytls: Don't publish HTTPS record for CNAME'd domain (fix #6922) * 49f9af9a4ab2a28fa5c445630017f5284a5afa48 caddytls: Fix TrustedCACerts backwards compatibility (#6889) * e276994174983dbb190d4bb9acaab157ef14373b caddytls: Initialize permission module earlier (fix #6901) * 39262f86632401ae4915600b042ef5a28141d3d5 caddytls: Minor fixes for ECH * 173573035c7484bb4aad4498a90bf5a1cf1bb5be core: add modular `network_proxy` support (#6399) * 86c620fb4e7bfad5888832c491147af53fd5390a go.mod: Minor dependency upgrades * af2d33afbb52389cda139a6a0fd8a9d65f558676 headers: Allow nil HeaderOps (fix #6893) * dccf3d8982d1b428e840d43f71fa5c3becf6ea8f requestbody: Add set option to replace request body (#5795) * 2ac09fdb2046957597e17096adf6335a6d589a2f requestbody: Fix ContentLength calculation after body replacement (#6896) ### v2.10.0: * f297bc0a04dcab6c2585b47f3672d045c4f6b54b admin: Remove host checking for UDS (close #6832) * 0b2802faa47faa378181a3de5b0d1dcc769a715d build(deps): bump golang.org/x/net from 0.37.0 to 0.38.0 (#6960) * 5be77d07ab730e6035ec7a47fb0fe161785af35c caddyauth: Set authentication provider error in placeholder (#6932) * b06a9496d130cb06466156d53138a9691342e5a2 caddyhttp: Document side effect of HTTP/3 early data (close #6936) * 35c8c2d92d26208642cea0d1549c77a00124e154 caddytls: Add remote_ip to HTTP cert manager (close #6952) * fb22a26b1a08a2fa3b2526d1852467904ee140f6 caddytls: Allow missing ECH meta file * 1bfa111552eff8b30bc1a5f76516426f29c66a88 caddytls: Prefer managed wildcard certs over individual subdomain certs (#6959) * ea77a9ab67d8c04f513adaf0a1c648c738e25922 caddytls: Temporarily treat "" and "@" as equivalent for DNS publication * 5a6b2f8d1d4633622b551357f3cc9d27ec669d02 events: Refactor; move Event into core, so core can emit events (#6930) * 137711ae3e2d9aa48d7c48dba5ca176af628f073 go.mod: Upgrade acmez and certmagic * 9becf61a9f5bafb88a15823ce80c1325d3a30a4f go.mod: Upgrade to libdns 1.0 beta APIs (requires upgraded DNS providers) * 6c38ae7381b3338b173c59706673d11783091dee reverseproxy: Add valid Upstream to DialInfo in active health checks (#6949) ## What's Changed * docs: improve parsePHPFastCGI docs by @dunglas in https://github.com/caddyserver/caddy/pull/6779 * Fixes crash if logging error is not HandlerError by @kkroo in https://github.com/caddyserver/caddy/pull/6777 * chore: update quic-go to v0.49.0 by @marten-seemann in https://github.com/caddyserver/caddy/pull/6803 * chore: don't use deprecated `archives.format_overrides.format` by @mohammed90 in https://github.com/caddyserver/caddy/pull/6807 * caddytls: Fix sni_regexp matcher to obtain layer4 contexts by @vnxme in https://github.com/caddyserver/caddy/pull/6804 * feat: automatically set GOMEMLIMIT by @dunglas in https://github.com/caddyserver/caddy/pull/6809 * caddytls: Refactor sni matcher by @vnxme in https://github.com/caddyserver/caddy/pull/6812 * reverse_proxy: re-add healthy upstreams metric by @mohammed90 in https://github.com/caddyserver/caddy/pull/6806 * fix: update broken link to Ardan Labs by @sbruens in https://github.com/caddyserver/caddy/pull/6800 * build(deps): bump github.com/golang/glog from 1.2.2 to 1.2.4 by @dependabot in https://github.com/caddyserver/caddy/pull/6814 * reverseproxy: ignore duplicate collector registration error by @mohammed90 in https://github.com/caddyserver/caddy/pull/6820 * fix: fix index validation for PUT requests by @debug-ing in https://github.com/caddyserver/caddy/pull/6824 * file_server: use the UTC timezone for modified time by @WeidiDeng in https://github.com/caddyserver/caddy/pull/6830 * feat/tests: tests for error handling & metrics in admin endpoints by @gdhameeja in https://github.com/caddyserver/caddy/pull/6805 * chore: upgrade Go version to 1.24 by @mohammed90 in https://github.com/caddyserver/caddy/pull/6839 * remove glog dependency by @Ns2Kracy in https://github.com/caddyserver/caddy/pull/6838 * update quic-go to v0.50.0 by @marten-seemann in https://github.com/caddyserver/caddy/pull/6854 * Support Caddy Test Configuration Defaults Override. by @baruchyahalom in https://github.com/caddyserver/caddy/pull/6850 * chore: upgrade cobra by @mohammed90 in https://github.com/caddyserver/caddy/pull/6868 * build(deps): bump github.com/go-jose/go-jose/v3 from 3.0.3 to 3.0.4 by @dependabot in https://github.com/caddyserver/caddy/pull/6871 * caddytls: Encrypted ClientHello (ECH) by @mholt in https://github.com/caddyserver/caddy/pull/6862 * build(deps): bump github.com/cloudflare/circl from 1.3.3 to 1.3.7 by @dependabot in https://github.com/caddyserver/caddy/pull/6876 * docs: replaced the name and twitter link by @sashaphmn in https://github.com/caddyserver/caddy/pull/6874 * ci: allow using the toolchain Go "toolchain" by @dunglas in https://github.com/caddyserver/caddy/pull/6846 * chore: more comments about reverse_proxy buffering and add new tests by @WeidiDeng in https://github.com/caddyserver/caddy/pull/6778 * Add error handling for unrecognized subdirective/options by @steffenbusch in https://github.com/caddyserver/caddy/pull/6884 * Fix TrustedCACerts backwards compatibility by @jjiang-stripe in https://github.com/caddyserver/caddy/pull/6889 * requestbody: Add `replace` for optional body replacement by @AdrienPensart in https://github.com/caddyserver/caddy/pull/5795 * requestbody: Fix ContentLength calculation after body replacement by @steffenbusch in https://github.com/caddyserver/caddy/pull/6896 * Fix caddy fmt breaks backquote wrapped braces in template by @keystroke3 in https://github.com/caddyserver/caddy/pull/6903 * update quic-go to v0.50.1 by @marten-seemann in https://github.com/caddyserver/caddy/pull/6918 * core: add modular `network_proxy` support by @mohammed90 in https://github.com/caddyserver/caddy/pull/6399 * events: Refactor; move Event into core, so core can emit events by @mholt in https://github.com/caddyserver/caddy/pull/6930 * chore: fix comment by @riyueguang in https://github.com/caddyserver/caddy/pull/6950 * bug: Fix the incorrect parameter order by @cuishuang in https://github.com/caddyserver/caddy/pull/6951 * Add a valid Upstream to the DialInfo when doing active health checks by @jbro in https://github.com/caddyserver/caddy/pull/6949 * caddyauth: Set authentication provider error in placeholder by @steffenbusch in https://github.com/caddyserver/caddy/pull/6932 * build(deps): bump golang.org/x/net from 0.37.0 to 0.38.0 by @dependabot in https://github.com/caddyserver/caddy/pull/6960 * caddytls: Prefer managed wildcard certs over individual subdomain certs by @mholt in https://github.com/caddyserver/caddy/pull/6959 ## New Contributors * @sbruens made their first contribution in https://github.com/caddyserver/caddy/pull/6800 * @debug-ing made their first contribution in https://github.com/caddyserver/caddy/pull/6824 * @Ns2Kracy made their first contribution in https://github.com/caddyserver/caddy/pull/6838 * @baruchyahalom made their first contribution in https://github.com/caddyserver/caddy/pull/6850 * @sashaphmn made their first contribution in https://github.com/caddyserver/caddy/pull/6874 * @AdrienPensart made their first contribution in https://github.com/caddyserver/caddy/pull/5795 * @keystroke3 made their first contribution in https://github.com/caddyserver/caddy/pull/6903 * @riyueguang made their first contribution in https://github.com/caddyserver/caddy/pull/6950 **Full Changelog**: https://github.com/caddyserver/caddy/compare/v2.9.1...v2.10.0

v2.10.0-beta.4预发布
? · 2025-03-25

Welcome to the pre-release versions for Caddy 2.10! We hope you will try these betas in your production environments after verifying them in testing/staging, and offer your feedback so the stable release will be better. We're excited for 2.10, as it will bring many improvements, new features, and fixes to your web server. Expect several beta versions as we work through a backlog of issues and pull requests. Aside from many bug fixes, this beta already features: - **Encrypted ClientHello (ECH):** The [draft spec](https://www.ietf.org/archive/id/draft-ietf-tls-esni-23.html) for ECH is almost finalized, so we can now support this privacy feature for TLS. This is a powerful but nuanced capability; see below (and docs on the website) for details. - **Post-quantum (PQC) key exchange:** Caddy now supports the standardized `x25519mlkem768` cryptographic group by default. - **ACME profiles:** ACME profiles are an experimental draft that allow you to choose properties of your certificates with more flexibility than traditional CSR methods. For example, [Let's Encrypt will issue 6-day certificates](https://letsencrypt.org/2025/01/16/6-day-and-ip-certs/) under a certain profile. Caddy may eventually use that profile by default. - **Via header:** The reverse proxy now sets a Via header instead of a duplicate Server header. - **Global DNS provider:** You can now specify a default "global" DNS module to use instead of having to configure it locally in every part of your config that requires a DNS provider (for example, ACME DNS challenges, and ECH). This is the `dns` global option in the Caddyfile, or in JSON config, it's the `dns` parameter in the `tls` app configuration. :warning: While have traditionally supported the last 2 minor Go versions to accommodate some distribution / package manager policies, we now only support the latest minor Go version. The privacy and security benefits added in new Go versions (such as post-quantum cryptography) are worth making available to everyone as soon as possible, rather than holding back the entire user base or maintaining multiple code compilation configurations. ## Encrypted ClientHello (ECH) details Typically, server names (domain names, or "SNI") are sent in the plaintext ClientHello when establishing TLS connections. With ECH, the true server name is encrypted (and wrapped) by an "outer" ClientHello which has a generic SNI of your choosing. With many sites on the same server sharing the same outer SNI, both clients and the server have more privacy relative to domain names. Caddy implements fully automated ECH, meaning that it generates (and [soon](https://github.com/golang/go/issues/71920), rotates), publishes, and serves ECH configurations simply by specifying a DNS provider, and the outer/public domain name to use. **Fully automated ECH requires a DNS module built into your Caddy binary.** In order for a client, such as a browser, to know it can use ECH, and what parameters to use, the server's ECH configuration must be published. This config includes the public name, cryptographic parameters, and a public key for encrypting the inner ClientHello. By convention, browsers read the standardized HTTPS-type DNS record containing a `ech` SvcParamKey. Caddy sets this DNS record for all domains being protected, but it needs that DNS provider module plugged in and configured in order to do this. If you are already using the DNS ACME challenge, you should already have a DNS provider plugged in. If you prefer to build Caddy from source with [a DNS module](https://github.com/caddy-dns), it's easy with [xcaddy](https://github.com/caddyserver/xcaddy), for example: `$ xcaddy build --with github.com/caddy-dns/cloudflare` The minimum config needed to enable ClientHello is also the _recommended_ config, as it maximizes privacy benefits in most situations. You just need the `ech` global option and a DNS provider specified. Here's an example using Cloudflare as the nameserver: **Caddyfile:** ```caddy { debug # not required; recommended while testing dns cloudflare {env.CLOUDFLARE_API_KEY} ech ech.example.net } example.com { respond "Hello there!" } ``` This protects all your sites (`example.com` in this case) behind the public name of `ech.example.net`. (As another example, Cloudflare uses `cloudflare-ech.com` for all the sites it serves. We recommend choosing a single public domain and use it to protect all your sites.) **The outer/public name you choose should point to your server.** Caddy will obtain a certificate for this name in order to facilitate safe, reliable connections for clients when needed. Without a certificate, clients may be forced to connect insecurely, or fail to connect at all, in some cases, which not only leaves them vulnerable, but also risks exposing the names of your server's sites. Caddy then uses the specified DNS provider to publish the ECH config(s) for your various site names. It creates (or augments) HTTPS-type records for the domains of your sites (not your ECH public name). Note that DNS provider modules are independently-maintained, and may not have been tested for compatibility with HTTPS-type records. Please contact your module's maintainers if you experience issues. If you have more advanced configuration needs, you can use the JSON configuration (more details coming soon; for now, see #6862 or look at the source code; or use `caddy adapt` to convert a Caddyfile to JSON). ### Testing and verifying Encrypted ClientHello First make sure Caddy runs successfully with ECH enabled (and a DNS module) in the config. You should see logs that it is generating an ECH config and publishing it to your domain name(s). You will need to use a client that supports ECH. Some custom builds of `curl` do, and Firefox and modern Chrome-based browsers do as well, but you need to enable DNS-over-HTTPS or DNS-over-TLS first (since, obviously, querying DNS in plaintext for a protected domain name will expose the domain and defeat the purpose of ECH). If reusing an existing domain name, clear your DNS cache. Firefox has a way of doing this for its cache at `about:networking#dns`. Once you have a suitable client, use [Wireshark](https://www.wireshark.org/) to capture network packets as you load your site. You should see _only_ the outer/public name as SNI (ServerName Indicator) values in the packet capture. If at any time you see the true site name, ECH is not working properly -- it could be a client or server issue. Before filing a bug, please try to pinpoint it as a server issue first. But definitely report server bugs! Thank you! (Note that ECH is not automatically published for CNAME'd domains, and the domain must already have a record in the zone.) ## Commits ### Beta 1: * 96c5c554c1241430ac9ddea6f4b68948adcc961b admin: fix index validation for PUT requests (#6824) * 3644ee31cae8e20493d7ccd0c55b0a9c21f20693 build(deps): bump github.com/cloudflare/circl from 1.3.3 to 1.3.7 (#6876) * eacd7720e99f51b6d2dd340849897c0ff812b8c8 build(deps): bump github.com/go-jose/go-jose/v3 from 3.0.3 to 3.0.4 (#6871) * 9996d6a70ba76a94dfc90548f25fbac0ce9da497 build(deps): bump github.com/golang/glog from 1.2.2 to 1.2.4 (#6814) * 11151586165946453275b66ef33794d41a5e047b caddyhttp: ResponseRecorder sets stream regardless of 1xx * 8861eae22350d9e8f94653db951faf85a50a82da caddytest: Support configuration defaults override (#6850) * d7764dfdbbee04d2f63aa1b05150737dfddc0bcf caddytls: Encrypted ClientHello (ECH) (#6862) * a807fe065959baa8ee2ad95156183c0850c2b584 caddytls: Enhance ECH documentation * bc3d497739444a5ce550696b7b0da36e6e3bc777 caddytls: Fix broken refactor * 7b8f3505e33139de0d542566478e98b361bb84bf caddytls: Fix sni_regexp matcher to obtain layer4 contexts (#6804) * 2c4295ee48f494bc8dda5fa09b37612d520c8b3b caddytls: Initial support for ACME profiles * d7872c3bfa673ce9584d00f01a725b93fa7bedf1 caddytls: Refactor sni matcher (#6812) * 172136a0a0f6aa47be4eab3727fa2482d7af6617 caddytls: Support post-quantum key exchange mechanism X25519MLKEM768 * 066d770409917b409d0bdc14cb5ba33d3e4cb33e cmd: automatically set GOMEMLIMIT (#6809) * 1f35a8a4029a338e89998acafa95e1e931a46a27 fastcgi: improve parsePHPFastCGI docs (#6779) * 22563a70eb7b590fcb698680a3ec6d76c0968748 file_server: use the UTC timezone for modified time (#6830) * cfc3af67492eba22686fd13a2b2201c66cd737f3 fix: update broken link to Ardan Labs (#6800) * 99073eaa33af62bff51c31305e3437c57d936284 go.mod: Upgrade CertMagic to v0.21.7 * 1641e76fd742408c85363e4826451ba9ef22bc99 go.mod: Upgrade dependencies * 0d7c63920daecec510202c42816c883fd2dbe047 go.mod: remove glog dependency (#6838) * 932dac157a3c4693b80576477498bb86208b9b30 logging: Always set fields func; fix #6829 * 9e0e5a4b4c2babda81c58f28fe61adfa91d04524 logging: Fix crash if logging error is not HandlerError (#6777) * 904a0fa368b7eacac3c7156ce4a1f6ced8f61f34 reverse_proxy: re-add healthy upstreams metric (#6806) * e7da3b267bcec986aaca960dd22ef834d3b9d4a6 reverseproxy: Via header (#6275) * 9283770f68f570f47ca20aa9c6f9de8cc50063ba reverseproxy: ignore duplicate collector registration error (#6820) ### Beta 2: * f4432a306ac59feee1fc45c8efefad3619e37629 caddyfile: add error handling for unrecognized subdirective/options in various modules (#6884) * 84364ffcd06e35a93c9bb08ed80617bde72d4f74 caddypki: Remove lifetime check at Caddyfile parse (fix #6878) * adbe7f87e6bda96a1dddd94ecedefe3219a5304d caddytls: Only make DNS solver if not already set (fix #6880) * d57ab215a2f198a465ea33abe4588bb5696e7abd caddytls: Pointer receiver (fix #6885) * 4ebcfed9c942c59f473f12f8108e1d0fa92e0855 caddytls: Reorder provisioning steps (fix #6877) * a686f7c346fe011ad153a3bd4ac3e31e6758bcce cmd: Only set memory/CPU limits on run (fix #6879) * 19876208c79a476a46beec2430e554d4161ab426 cmd: Promote undo maxProcs func to caller * 220cd1c2bcecc07bcf6a0141069538c1b1109907 reverseproxy: more comments about buffering and add new tests (#6778) ### Beta 3: * b3e692ed09f8ba15b741621c4b16d8bfee38f8a1 caddyfile: Fix formatting for backquote wrapped braces (#6903) * 55c89ccf2a39dcfd7286fcaed54787821ff9a1aa caddytls: Convert AP subjects to punycode * 1f8dab572ca9681464fdadc65bfb5f250fc496c3 caddytls: Don't publish ECH configs if other records don't exist * 782a3c7ac60c82311fe9fb8889dd843dfe26c0bc caddytls: Don't publish HTTPS record for CNAME'd domain (fix #6922) * 49f9af9a4ab2a28fa5c445630017f5284a5afa48 caddytls: Fix TrustedCACerts backwards compatibility (#6889) * e276994174983dbb190d4bb9acaab157ef14373b caddytls: Initialize permission module earlier (fix #6901) * 39262f86632401ae4915600b042ef5a28141d3d5 caddytls: Minor fixes for ECH * 173573035c7484bb4aad4498a90bf5a1cf1bb5be core: add modular `network_proxy` support (#6399) * 86c620fb4e7bfad5888832c491147af53fd5390a go.mod: Minor dependency upgrades * af2d33afbb52389cda139a6a0fd8a9d65f558676 headers: Allow nil HeaderOps (fix #6893) * dccf3d8982d1b428e840d43f71fa5c3becf6ea8f requestbody: Add set option to replace request body (#5795) * 2ac09fdb2046957597e17096adf6335a6d589a2f requestbody: Fix ContentLength calculation after body replacement (#6896) ## What's Changed * Add error handling for unrecognized subdirective/options by @steffenbusch in https://github.com/caddyserver/caddy/pull/6884 * ci: allow using the toolchain Go "toolchain" by @dunglas in https://github.com/caddyserver/caddy/pull/6846 * chore: more comments about reverse_proxy buffering and add new tests by @WeidiDeng in https://github.com/caddyserver/caddy/pull/6778 * docs: improve parsePHPFastCGI docs by @dunglas in https://github.com/caddyserver/caddy/pull/6779 * Fixes crash if logging error is not HandlerError by @kkroo in https://github.com/caddyserver/caddy/pull/6777 * chore: update quic-go to v0.49.0 by @marten-seemann in https://github.com/caddyserver/caddy/pull/6803 * chore: don't use deprecated `archives.format_overrides.format` by @mohammed90 in https://github.com/caddyserver/caddy/pull/6807 * caddytls: Fix sni_regexp matcher to obtain layer4 contexts by @vnxme in https://github.com/caddyserver/caddy/pull/6804 * feat: automatically set GOMEMLIMIT by @dunglas in https://github.com/caddyserver/caddy/pull/6809 * caddytls: Refactor sni matcher by @vnxme in https://github.com/caddyserver/caddy/pull/6812 * reverse_proxy: re-add healthy upstreams metric by @mohammed90 in https://github.com/caddyserver/caddy/pull/6806 * fix: update broken link to Ardan Labs by @sbruens in https://github.com/caddyserver/caddy/pull/6800 * build(deps): bump github.com/golang/glog from 1.2.2 to 1.2.4 by @dependabot in https://github.com/caddyserver/caddy/pull/6814 * reverseproxy: ignore duplicate collector registration error by @mohammed90 in https://github.com/caddyserver/caddy/pull/6820 * fix: fix index validation for PUT requests by @debug-ing in https://github.com/caddyserver/caddy/pull/6824 * file_server: use the UTC timezone for modified time by @WeidiDeng in https://github.com/caddyserver/caddy/pull/6830 * feat/tests: tests for error handling & metrics in admin endpoints by @gdhameeja in https://github.com/caddyserver/caddy/pull/6805 * chore: upgrade Go version to 1.24 by @mohammed90 in https://github.com/caddyserver/caddy/pull/6839 * remove glog dependency by @Ns2Kracy in https://github.com/caddyserver/caddy/pull/6838 * update quic-go to v0.50.0 by @marten-seemann in https://github.com/caddyserver/caddy/pull/6854 * Support Caddy Test Configuration Defaults Override. by @baruchyahalom in https://github.com/caddyserver/caddy/pull/6850 * chore: upgrade cobra by @mohammed90 in https://github.com/caddyserver/caddy/pull/6868 * build(deps): bump github.com/go-jose/go-jose/v3 from 3.0.3 to 3.0.4 by @dependabot in https://github.com/caddyserver/caddy/pull/6871 * caddytls: Encrypted ClientHello (ECH) by @mholt in https://github.com/caddyserver/caddy/pull/6862 * build(deps): bump github.com/cloudflare/circl from 1.3.3 to 1.3.7 by @dependabot in https://github.com/caddyserver/caddy/pull/6876 * docs: replaced the name and twitter link by @sashaphmn in https://github.com/caddyserver/caddy/pull/6874 * Fix TrustedCACerts backwards compatibility by @jjiang-stripe in https://github.com/caddyserver/caddy/pull/6889 * requestbody: Add `replace` for optional body replacement by @AdrienPensart in https://github.com/caddyserver/caddy/pull/5795 * requestbody: Fix ContentLength calculation after body replacement by @steffenbusch in https://github.com/caddyserver/caddy/pull/6896 * Fix caddy fmt breaks backquote wrapped braces in template by @keystroke3 in https://github.com/caddyserver/caddy/pull/6903 * update quic-go to v0.50.1 by @marten-seemann in https://github.com/caddyserver/caddy/pull/6918 * core: add modular `network_proxy` support by @mohammed90 in https://github.com/caddyserver/caddy/pull/6399 ## New Contributors * @sbruens made their first contribution in https://github.com/caddyserver/caddy/pull/6800 * @debug-ing made their first contribution in https://github.com/caddyserver/caddy/pull/6824 * @Ns2Kracy made their first contribution in https://github.com/caddyserver/caddy/pull/6838 * @baruchyahalom made their first contribution in https://github.com/caddyserver/caddy/pull/6850 * @sashaphmn made their first contribution in https://github.com/caddyserver/caddy/pull/6874 * @AdrienPensart made their first contribution in https://github.com/caddyserver/caddy/pull/5795 * @keystroke3 made their first contribution in https://github.com/caddyserver/caddy/pull/6903 **Full Changelog**: https://github.com/caddyserver/caddy/compare/v2.9.1...v2.10.0-beta.4

v2.10.0-beta.3预发布
? · 2025-03-24

Welcome to the pre-release versions for Caddy 2.10! We hope you will try these betas in your production environments after verifying them in testing/staging, and offer your feedback so the stable release will be better. We're excited for 2.10, as it will bring many improvements, new features, and fixes to your web server. Expect several beta versions as we work through a backlog of issues and pull requests. Aside from many bug fixes, this beta already features: - **Encrypted ClientHello (ECH):** The [draft spec](https://www.ietf.org/archive/id/draft-ietf-tls-esni-23.html) for ECH is almost finalized, so we can now support this privacy feature for TLS. This is a powerful but nuanced capability; see below (and docs on the website) for details. - **Post-quantum (PQC) key exchange:** Caddy now supports the standardized `x25519mlkem768` cryptographic group by default. - **ACME profiles:** ACME profiles are an experimental draft that allow you to choose properties of your certificates with more flexibility than traditional CSR methods. For example, [Let's Encrypt will issue 6-day certificates](https://letsencrypt.org/2025/01/16/6-day-and-ip-certs/) under a certain profile. Caddy may eventually use that profile by default. - **Via header:** The reverse proxy now sets a Via header instead of a duplicate Server header. - **Global DNS provider:** You can now specify a default "global" DNS module to use instead of having to configure it locally in every part of your config that requires a DNS provider (for example, ACME DNS challenges, and ECH). This is the `dns` global option in the Caddyfile, or in JSON config, it's the `dns` parameter in the `tls` app configuration. :warning: While have traditionally supported the last 2 minor Go versions to accommodate some distribution / package manager policies, we now only support the latest minor Go version. The privacy and security benefits added in new Go versions (such as post-quantum cryptography) are worth making available to everyone as soon as possible, rather than holding back the entire user base or maintaining multiple code compilation configurations. ## Encrypted ClientHello (ECH) details Typically, server names (domain names, or "SNI") are sent in the plaintext ClientHello when establishing TLS connections. With ECH, the true server name is encrypted (and wrapped) by an "outer" ClientHello which has a generic SNI of your choosing. With many sites on the same server sharing the same outer SNI, both clients and the server have more privacy relative to domain names. Caddy implements fully automated ECH, meaning that it generates (and [soon](https://github.com/golang/go/issues/71920), rotates), publishes, and serves ECH configurations simply by specifying a DNS provider, and the outer/public domain name to use. **Fully automated ECH requires a DNS module built into your Caddy binary.** In order for a client, such as a browser, to know it can use ECH, and what parameters to use, the server's ECH configuration must be published. This config includes the public name, cryptographic parameters, and a public key for encrypting the inner ClientHello. By convention, browsers read the standardized HTTPS-type DNS record containing a `ech` SvcParamKey. Caddy sets this DNS record for all domains being protected, but it needs that DNS provider module plugged in and configured in order to do this. If you are already using the DNS ACME challenge, you should already have a DNS provider plugged in. If you prefer to build Caddy from source with [a DNS module](https://github.com/caddy-dns), it's easy with [xcaddy](https://github.com/caddyserver/xcaddy), for example: `$ xcaddy build --with github.com/caddy-dns/cloudflare` The minimum config needed to enable ClientHello is also the _recommended_ config, as it maximizes privacy benefits in most situations. You just need the `ech` global option and a DNS provider specified. Here's an example using Cloudflare as the nameserver: **Caddyfile:** ```caddy { debug # not required; recommended while testing dns cloudflare {env.CLOUDFLARE_API_KEY} ech ech.example.net } example.com { respond "Hello there!" } ``` This protects all your sites (`example.com` in this case) behind the public name of `ech.example.net`. (As another example, Cloudflare uses `cloudflare-ech.com` for all the sites it serves. We recommend choosing a single public domain and use it to protect all your sites.) **The outer/public name you choose should point to your server.** Caddy will obtain a certificate for this name in order to facilitate safe, reliable connections for clients when needed. Without a certificate, clients may be forced to connect insecurely, or fail to connect at all, in some cases, which not only leaves them vulnerable, but also risks exposing the names of your server's sites. Caddy then uses the specified DNS provider to publish the ECH config(s) for your various site names. It creates (or augments) HTTPS-type records for the domains of your sites (not your ECH public name). Note that DNS provider modules are independently-maintained, and may not have been tested for compatibility with HTTPS-type records. Please contact your module's maintainers if you experience issues. If you have more advanced configuration needs, you can use the JSON configuration (more details coming soon; for now, see #6862 or look at the source code; or use `caddy adapt` to convert a Caddyfile to JSON). ### Testing and verifying Encrypted ClientHello First make sure Caddy runs successfully with ECH enabled (and a DNS module) in the config. You should see logs that it is generating an ECH config and publishing it to your domain name(s). You will need to use a client that supports ECH. Some custom builds of `curl` do, and Firefox and modern Chrome-based browsers do as well, but you need to enable DNS-over-HTTPS or DNS-over-TLS first (since, obviously, querying DNS in plaintext for a protected domain name will expose the domain and defeat the purpose of ECH). If reusing an existing domain name, clear your DNS cache. Firefox has a way of doing this for its cache at `about:networking#dns`. Once you have a suitable client, use [Wireshark](https://www.wireshark.org/) to capture network packets as you load your site. You should see _only_ the outer/public name as SNI (ServerName Indicator) values in the packet capture. If at any time you see the true site name, ECH is not working properly -- it could be a client or server issue. Before filing a bug, please try to pinpoint it as a server issue first. But definitely report server bugs! Thank you! (Note that ECH is not automatically published for CNAME'd domains, and the domain must already have a record in the zone.) ## Commits ### Beta 1: * 96c5c554c1241430ac9ddea6f4b68948adcc961b admin: fix index validation for PUT requests (#6824) * 3644ee31cae8e20493d7ccd0c55b0a9c21f20693 build(deps): bump github.com/cloudflare/circl from 1.3.3 to 1.3.7 (#6876) * eacd7720e99f51b6d2dd340849897c0ff812b8c8 build(deps): bump github.com/go-jose/go-jose/v3 from 3.0.3 to 3.0.4 (#6871) * 9996d6a70ba76a94dfc90548f25fbac0ce9da497 build(deps): bump github.com/golang/glog from 1.2.2 to 1.2.4 (#6814) * 11151586165946453275b66ef33794d41a5e047b caddyhttp: ResponseRecorder sets stream regardless of 1xx * 8861eae22350d9e8f94653db951faf85a50a82da caddytest: Support configuration defaults override (#6850) * d7764dfdbbee04d2f63aa1b05150737dfddc0bcf caddytls: Encrypted ClientHello (ECH) (#6862) * a807fe065959baa8ee2ad95156183c0850c2b584 caddytls: Enhance ECH documentation * bc3d497739444a5ce550696b7b0da36e6e3bc777 caddytls: Fix broken refactor * 7b8f3505e33139de0d542566478e98b361bb84bf caddytls: Fix sni_regexp matcher to obtain layer4 contexts (#6804) * 2c4295ee48f494bc8dda5fa09b37612d520c8b3b caddytls: Initial support for ACME profiles * d7872c3bfa673ce9584d00f01a725b93fa7bedf1 caddytls: Refactor sni matcher (#6812) * 172136a0a0f6aa47be4eab3727fa2482d7af6617 caddytls: Support post-quantum key exchange mechanism X25519MLKEM768 * 066d770409917b409d0bdc14cb5ba33d3e4cb33e cmd: automatically set GOMEMLIMIT (#6809) * 1f35a8a4029a338e89998acafa95e1e931a46a27 fastcgi: improve parsePHPFastCGI docs (#6779) * 22563a70eb7b590fcb698680a3ec6d76c0968748 file_server: use the UTC timezone for modified time (#6830) * cfc3af67492eba22686fd13a2b2201c66cd737f3 fix: update broken link to Ardan Labs (#6800) * 99073eaa33af62bff51c31305e3437c57d936284 go.mod: Upgrade CertMagic to v0.21.7 * 1641e76fd742408c85363e4826451ba9ef22bc99 go.mod: Upgrade dependencies * 0d7c63920daecec510202c42816c883fd2dbe047 go.mod: remove glog dependency (#6838) * 932dac157a3c4693b80576477498bb86208b9b30 logging: Always set fields func; fix #6829 * 9e0e5a4b4c2babda81c58f28fe61adfa91d04524 logging: Fix crash if logging error is not HandlerError (#6777) * 904a0fa368b7eacac3c7156ce4a1f6ced8f61f34 reverse_proxy: re-add healthy upstreams metric (#6806) * e7da3b267bcec986aaca960dd22ef834d3b9d4a6 reverseproxy: Via header (#6275) * 9283770f68f570f47ca20aa9c6f9de8cc50063ba reverseproxy: ignore duplicate collector registration error (#6820) ### Beta 2: * f4432a306ac59feee1fc45c8efefad3619e37629 caddyfile: add error handling for unrecognized subdirective/options in various modules (#6884) * 84364ffcd06e35a93c9bb08ed80617bde72d4f74 caddypki: Remove lifetime check at Caddyfile parse (fix #6878) * adbe7f87e6bda96a1dddd94ecedefe3219a5304d caddytls: Only make DNS solver if not already set (fix #6880) * d57ab215a2f198a465ea33abe4588bb5696e7abd caddytls: Pointer receiver (fix #6885) * 4ebcfed9c942c59f473f12f8108e1d0fa92e0855 caddytls: Reorder provisioning steps (fix #6877) * a686f7c346fe011ad153a3bd4ac3e31e6758bcce cmd: Only set memory/CPU limits on run (fix #6879) * 19876208c79a476a46beec2430e554d4161ab426 cmd: Promote undo maxProcs func to caller * 220cd1c2bcecc07bcf6a0141069538c1b1109907 reverseproxy: more comments about buffering and add new tests (#6778) ### Beta 3: * b3e692ed09f8ba15b741621c4b16d8bfee38f8a1 caddyfile: Fix formatting for backquote wrapped braces (#6903) * 55c89ccf2a39dcfd7286fcaed54787821ff9a1aa caddytls: Convert AP subjects to punycode * 1f8dab572ca9681464fdadc65bfb5f250fc496c3 caddytls: Don't publish ECH configs if other records don't exist * 782a3c7ac60c82311fe9fb8889dd843dfe26c0bc caddytls: Don't publish HTTPS record for CNAME'd domain (fix #6922) * 49f9af9a4ab2a28fa5c445630017f5284a5afa48 caddytls: Fix TrustedCACerts backwards compatibility (#6889) * e276994174983dbb190d4bb9acaab157ef14373b caddytls: Initialize permission module earlier (fix #6901) * 39262f86632401ae4915600b042ef5a28141d3d5 caddytls: Minor fixes for ECH * 173573035c7484bb4aad4498a90bf5a1cf1bb5be core: add modular `network_proxy` support (#6399) * 86c620fb4e7bfad5888832c491147af53fd5390a go.mod: Minor dependency upgrades * af2d33afbb52389cda139a6a0fd8a9d65f558676 headers: Allow nil HeaderOps (fix #6893) * dccf3d8982d1b428e840d43f71fa5c3becf6ea8f requestbody: Add set option to replace request body (#5795) * 2ac09fdb2046957597e17096adf6335a6d589a2f requestbody: Fix ContentLength calculation after body replacement (#6896) ## What's Changed * Add error handling for unrecognized subdirective/options by @steffenbusch in https://github.com/caddyserver/caddy/pull/6884 * ci: allow using the toolchain Go "toolchain" by @dunglas in https://github.com/caddyserver/caddy/pull/6846 * chore: more comments about reverse_proxy buffering and add new tests by @WeidiDeng in https://github.com/caddyserver/caddy/pull/6778 * docs: improve parsePHPFastCGI docs by @dunglas in https://github.com/caddyserver/caddy/pull/6779 * Fixes crash if logging error is not HandlerError by @kkroo in https://github.com/caddyserver/caddy/pull/6777 * chore: update quic-go to v0.49.0 by @marten-seemann in https://github.com/caddyserver/caddy/pull/6803 * chore: don't use deprecated `archives.format_overrides.format` by @mohammed90 in https://github.com/caddyserver/caddy/pull/6807 * caddytls: Fix sni_regexp matcher to obtain layer4 contexts by @vnxme in https://github.com/caddyserver/caddy/pull/6804 * feat: automatically set GOMEMLIMIT by @dunglas in https://github.com/caddyserver/caddy/pull/6809 * caddytls: Refactor sni matcher by @vnxme in https://github.com/caddyserver/caddy/pull/6812 * reverse_proxy: re-add healthy upstreams metric by @mohammed90 in https://github.com/caddyserver/caddy/pull/6806 * fix: update broken link to Ardan Labs by @sbruens in https://github.com/caddyserver/caddy/pull/6800 * build(deps): bump github.com/golang/glog from 1.2.2 to 1.2.4 by @dependabot in https://github.com/caddyserver/caddy/pull/6814 * reverseproxy: ignore duplicate collector registration error by @mohammed90 in https://github.com/caddyserver/caddy/pull/6820 * fix: fix index validation for PUT requests by @debug-ing in https://github.com/caddyserver/caddy/pull/6824 * file_server: use the UTC timezone for modified time by @WeidiDeng in https://github.com/caddyserver/caddy/pull/6830 * feat/tests: tests for error handling & metrics in admin endpoints by @gdhameeja in https://github.com/caddyserver/caddy/pull/6805 * chore: upgrade Go version to 1.24 by @mohammed90 in https://github.com/caddyserver/caddy/pull/6839 * remove glog dependency by @Ns2Kracy in https://github.com/caddyserver/caddy/pull/6838 * update quic-go to v0.50.0 by @marten-seemann in https://github.com/caddyserver/caddy/pull/6854 * Support Caddy Test Configuration Defaults Override. by @baruchyahalom in https://github.com/caddyserver/caddy/pull/6850 * chore: upgrade cobra by @mohammed90 in https://github.com/caddyserver/caddy/pull/6868 * build(deps): bump github.com/go-jose/go-jose/v3 from 3.0.3 to 3.0.4 by @dependabot in https://github.com/caddyserver/caddy/pull/6871 * caddytls: Encrypted ClientHello (ECH) by @mholt in https://github.com/caddyserver/caddy/pull/6862 * build(deps): bump github.com/cloudflare/circl from 1.3.3 to 1.3.7 by @dependabot in https://github.com/caddyserver/caddy/pull/6876 * docs: replaced the name and twitter link by @sashaphmn in https://github.com/caddyserver/caddy/pull/6874 * Fix TrustedCACerts backwards compatibility by @jjiang-stripe in https://github.com/caddyserver/caddy/pull/6889 * requestbody: Add `replace` for optional body replacement by @AdrienPensart in https://github.com/caddyserver/caddy/pull/5795 * requestbody: Fix ContentLength calculation after body replacement by @steffenbusch in https://github.com/caddyserver/caddy/pull/6896 * Fix caddy fmt breaks backquote wrapped braces in template by @keystroke3 in https://github.com/caddyserver/caddy/pull/6903 * update quic-go to v0.50.1 by @marten-seemann in https://github.com/caddyserver/caddy/pull/6918 * core: add modular `network_proxy` support by @mohammed90 in https://github.com/caddyserver/caddy/pull/6399 ## New Contributors * @sbruens made their first contribution in https://github.com/caddyserver/caddy/pull/6800 * @debug-ing made their first contribution in https://github.com/caddyserver/caddy/pull/6824 * @Ns2Kracy made their first contribution in https://github.com/caddyserver/caddy/pull/6838 * @baruchyahalom made their first contribution in https://github.com/caddyserver/caddy/pull/6850 * @sashaphmn made their first contribution in https://github.com/caddyserver/caddy/pull/6874 * @AdrienPensart made their first contribution in https://github.com/caddyserver/caddy/pull/5795 * @keystroke3 made their first contribution in https://github.com/caddyserver/caddy/pull/6903 **Full Changelog**: https://github.com/caddyserver/caddy/compare/v2.9.1...v2.10.0-beta.3

v2.10.0-beta.2预发布
? · 2025-03-09

Welcome to the pre-release versions for Caddy 2.10! We hope you will try these betas in your production environments after verifying them in testing/staging, and offer your feedback so the stable release will be better. We're excited for 2.10, as it will bring many improvements, new features, and fixes to your web server. Expect several beta versions as we work through a backlog of issues and pull requests. Aside from many bug fixes, this beta already features: - **Encrypted ClientHello (ECH):** The [draft spec](https://www.ietf.org/archive/id/draft-ietf-tls-esni-23.html) for ECH is almost finalized, so we can now support this privacy feature for TLS. This is a powerful but nuanced capability; see below (and docs on the website) for details. - **Post-quantum (PQC) key exchange:** Caddy now supports the standardized `x25519mlkem768` cryptographic group by default. - **ACME profiles:** ACME profiles are an experimental draft that allow you to choose properties of your certificates with more flexibility than traditional CSR methods. For example, [Let's Encrypt will issue 6-day certificates](https://letsencrypt.org/2025/01/16/6-day-and-ip-certs/) under a certain profile. Caddy may eventually use that profile by default. - **Via header:** The reverse proxy now sets a Via header instead of a duplicate Server header. - **Global DNS provider:** You can now specify a default "global" DNS module to use instead of having to configure it locally in every part of your config that requires a DNS provider (for example, ACME DNS challenges, and ECH). This is the `dns` global option in the Caddyfile, or in JSON config, it's the `dns` parameter in the `tls` app configuration. :warning: While have traditionally supported the last 2 minor Go versions to accommodate some distribution / package manager policies, we now only support the latest minor Go version. The privacy and security benefits added in new Go versions (such as post-quantum cryptography) are worth making available to everyone as soon as possible, rather than holding back the entire user base or maintaining multiple code compilation configurations. ## Encrypted ClientHello (ECH) details Typically, server names (domain names, or "SNI") are sent in the plaintext ClientHello when establishing TLS connections. With ECH, the true server name is encrypted (and wrapped) by an "outer" ClientHello which has a generic SNI of your choosing. With many sites on the same server sharing the same outer SNI, both clients and the server have more privacy relative to domain names. Caddy implements fully automated ECH, meaning that it generates (and [soon](https://github.com/golang/go/issues/71920), rotates), publishes, and serves ECH configurations simply by specifying a DNS provider, and the outer/public domain name to use. **Fully automated ECH requires a DNS module built into your Caddy binary.** In order for a client, such as a browser, to know it can use ECH, and what parameters to use, the server's ECH configuration must be published. This config includes the public name, cryptographic parameters, and a public key for encrypting the inner ClientHello. By convention, browsers read the standardized HTTPS-type DNS record containing a `ech` SvcParamKey. Caddy sets this DNS record for all domains being protected, but it needs that DNS provider module plugged in and configured in order to do this. If you are already using the DNS ACME challenge, you should already have a DNS provider plugged in. If you prefer to build Caddy from source with [a DNS module](https://github.com/caddy-dns), it's easy with [xcaddy](https://github.com/caddyserver/xcaddy), for example: `$ xcaddy build --with github.com/caddy-dns/cloudflare` The minimum config needed to enable ClientHello is also the _recommended_ config, as it maximizes privacy benefits in most situations. You just need the `ech` global option and a DNS provider specified. Here's an example using Cloudflare as the nameserver: **Caddyfile:** ```caddy { debug # not required; recommended while testing dns cloudflare {env.CLOUDFLARE_API_KEY} ech ech.example.net } example.com { respond "Hello there!" } ``` This protects all your sites (`example.com` in this case) behind the public name of `ech.example.net`. (As another example, Cloudflare uses `cloudflare-ech.com` for all the sites it serves. We recommend choosing a single public domain and use it to protect all your sites.) **The outer/public name you choose should point to your server.** Caddy will obtain a certificate for this name in order to facilitate safe, reliable connections for clients when needed. Without a certificate, clients may be forced to connect insecurely, or fail to connect at all, in some cases, which not only leaves them vulnerable, but also risks exposing the names of your server's sites. Caddy then uses the specified DNS provider to publish the ECH config(s) for your various site names. It creates (or augments) HTTPS-type records for the domains of your sites (not your ECH public name). Note that DNS provider modules are independently-maintained, and may not have been tested for compatibility with HTTPS-type records. Please contact your module's maintainers if you experience issues. If you have more advanced configuration needs, you can use the JSON configuration (more details coming soon; for now, see #6862 or look at the source code; or use `caddy adapt` to convert a Caddyfile to JSON). ### Testing and verifying Encrypted ClientHello First make sure Caddy runs successfully with ECH enabled (and a DNS module) in the config. You should see logs that it is generating an ECH config and publishing it to your domain name(s). You will need to use a client that supports ECH. Some custom builds of `curl` do, and Firefox and modern Chrome-based browsers do as well, but you need to enable DNS-over-HTTPS or DNS-over-TLS first (since, obviously, querying DNS in plaintext for a protected domain name will expose the domain and defeat the purpose of ECH). If reusing an existing domain name, clear your DNS cache. Firefox has a way of doing this for its cache at `about:networking#dns`. Once you have a suitable client, use [Wireshark](https://www.wireshark.org/) to capture network packets as you load your site. You should see _only_ the outer/public name as SNI (ServerName Indicator) values in the packet capture. If at any time you see the true site name, ECH is not working properly -- it could be a client or server issue. Before filing a bug, please try to pinpoint it as a server issue first. But definitely report server bugs! Thank you! ## Commits ### Beta 1: * 96c5c554c1241430ac9ddea6f4b68948adcc961b admin: fix index validation for PUT requests (#6824) * 3644ee31cae8e20493d7ccd0c55b0a9c21f20693 build(deps): bump github.com/cloudflare/circl from 1.3.3 to 1.3.7 (#6876) * eacd7720e99f51b6d2dd340849897c0ff812b8c8 build(deps): bump github.com/go-jose/go-jose/v3 from 3.0.3 to 3.0.4 (#6871) * 9996d6a70ba76a94dfc90548f25fbac0ce9da497 build(deps): bump github.com/golang/glog from 1.2.2 to 1.2.4 (#6814) * 11151586165946453275b66ef33794d41a5e047b caddyhttp: ResponseRecorder sets stream regardless of 1xx * 8861eae22350d9e8f94653db951faf85a50a82da caddytest: Support configuration defaults override (#6850) * d7764dfdbbee04d2f63aa1b05150737dfddc0bcf caddytls: Encrypted ClientHello (ECH) (#6862) * a807fe065959baa8ee2ad95156183c0850c2b584 caddytls: Enhance ECH documentation * bc3d497739444a5ce550696b7b0da36e6e3bc777 caddytls: Fix broken refactor * 7b8f3505e33139de0d542566478e98b361bb84bf caddytls: Fix sni_regexp matcher to obtain layer4 contexts (#6804) * 2c4295ee48f494bc8dda5fa09b37612d520c8b3b caddytls: Initial support for ACME profiles * d7872c3bfa673ce9584d00f01a725b93fa7bedf1 caddytls: Refactor sni matcher (#6812) * 172136a0a0f6aa47be4eab3727fa2482d7af6617 caddytls: Support post-quantum key exchange mechanism X25519MLKEM768 * 066d770409917b409d0bdc14cb5ba33d3e4cb33e cmd: automatically set GOMEMLIMIT (#6809) * 1f35a8a4029a338e89998acafa95e1e931a46a27 fastcgi: improve parsePHPFastCGI docs (#6779) * 22563a70eb7b590fcb698680a3ec6d76c0968748 file_server: use the UTC timezone for modified time (#6830) * cfc3af67492eba22686fd13a2b2201c66cd737f3 fix: update broken link to Ardan Labs (#6800) * 99073eaa33af62bff51c31305e3437c57d936284 go.mod: Upgrade CertMagic to v0.21.7 * 1641e76fd742408c85363e4826451ba9ef22bc99 go.mod: Upgrade dependencies * 0d7c63920daecec510202c42816c883fd2dbe047 go.mod: remove glog dependency (#6838) * 932dac157a3c4693b80576477498bb86208b9b30 logging: Always set fields func; fix #6829 * 9e0e5a4b4c2babda81c58f28fe61adfa91d04524 logging: Fix crash if logging error is not HandlerError (#6777) * 904a0fa368b7eacac3c7156ce4a1f6ced8f61f34 reverse_proxy: re-add healthy upstreams metric (#6806) * e7da3b267bcec986aaca960dd22ef834d3b9d4a6 reverseproxy: Via header (#6275) * 9283770f68f570f47ca20aa9c6f9de8cc50063ba reverseproxy: ignore duplicate collector registration error (#6820) ### Beta 2: * f4432a306ac59feee1fc45c8efefad3619e37629 caddyfile: add error handling for unrecognized subdirective/options in various modules (#6884) * 84364ffcd06e35a93c9bb08ed80617bde72d4f74 caddypki: Remove lifetime check at Caddyfile parse (fix #6878) * adbe7f87e6bda96a1dddd94ecedefe3219a5304d caddytls: Only make DNS solver if not already set (fix #6880) * d57ab215a2f198a465ea33abe4588bb5696e7abd caddytls: Pointer receiver (fix #6885) * 4ebcfed9c942c59f473f12f8108e1d0fa92e0855 caddytls: Reorder provisioning steps (fix #6877) * a686f7c346fe011ad153a3bd4ac3e31e6758bcce cmd: Only set memory/CPU limits on run (fix #6879) * 19876208c79a476a46beec2430e554d4161ab426 cmd: Promote undo maxProcs func to caller * 220cd1c2bcecc07bcf6a0141069538c1b1109907 reverseproxy: more comments about buffering and add new tests (#6778) ## What's Changed * Add error handling for unrecognized subdirective/options by @steffenbusch in https://github.com/caddyserver/caddy/pull/6884 * ci: allow using the toolchain Go "toolchain" by @dunglas in https://github.com/caddyserver/caddy/pull/6846 * chore: more comments about reverse_proxy buffering and add new tests by @WeidiDeng in https://github.com/caddyserver/caddy/pull/6778 * docs: improve parsePHPFastCGI docs by @dunglas in https://github.com/caddyserver/caddy/pull/6779 * Fixes crash if logging error is not HandlerError by @kkroo in https://github.com/caddyserver/caddy/pull/6777 * chore: update quic-go to v0.49.0 by @marten-seemann in https://github.com/caddyserver/caddy/pull/6803 * chore: don't use deprecated `archives.format_overrides.format` by @mohammed90 in https://github.com/caddyserver/caddy/pull/6807 * caddytls: Fix sni_regexp matcher to obtain layer4 contexts by @vnxme in https://github.com/caddyserver/caddy/pull/6804 * feat: automatically set GOMEMLIMIT by @dunglas in https://github.com/caddyserver/caddy/pull/6809 * caddytls: Refactor sni matcher by @vnxme in https://github.com/caddyserver/caddy/pull/6812 * reverse_proxy: re-add healthy upstreams metric by @mohammed90 in https://github.com/caddyserver/caddy/pull/6806 * fix: update broken link to Ardan Labs by @sbruens in https://github.com/caddyserver/caddy/pull/6800 * build(deps): bump github.com/golang/glog from 1.2.2 to 1.2.4 by @dependabot in https://github.com/caddyserver/caddy/pull/6814 * reverseproxy: ignore duplicate collector registration error by @mohammed90 in https://github.com/caddyserver/caddy/pull/6820 * fix: fix index validation for PUT requests by @debug-ing in https://github.com/caddyserver/caddy/pull/6824 * file_server: use the UTC timezone for modified time by @WeidiDeng in https://github.com/caddyserver/caddy/pull/6830 * feat/tests: tests for error handling & metrics in admin endpoints by @gdhameeja in https://github.com/caddyserver/caddy/pull/6805 * chore: upgrade Go version to 1.24 by @mohammed90 in https://github.com/caddyserver/caddy/pull/6839 * remove glog dependency by @Ns2Kracy in https://github.com/caddyserver/caddy/pull/6838 * update quic-go to v0.50.0 by @marten-seemann in https://github.com/caddyserver/caddy/pull/6854 * Support Caddy Test Configuration Defaults Override. by @baruchyahalom in https://github.com/caddyserver/caddy/pull/6850 * chore: upgrade cobra by @mohammed90 in https://github.com/caddyserver/caddy/pull/6868 * build(deps): bump github.com/go-jose/go-jose/v3 from 3.0.3 to 3.0.4 by @dependabot in https://github.com/caddyserver/caddy/pull/6871 * caddytls: Encrypted ClientHello (ECH) by @mholt in https://github.com/caddyserver/caddy/pull/6862 * build(deps): bump github.com/cloudflare/circl from 1.3.3 to 1.3.7 by @dependabot in https://github.com/caddyserver/caddy/pull/6876 * docs: replaced the name and twitter link by @sashaphmn in https://github.com/caddyserver/caddy/pull/6874 ## New Contributors * @sbruens made their first contribution in https://github.com/caddyserver/caddy/pull/6800 * @debug-ing made their first contribution in https://github.com/caddyserver/caddy/pull/6824 * @Ns2Kracy made their first contribution in https://github.com/caddyserver/caddy/pull/6838 * @baruchyahalom made their first contribution in https://github.com/caddyserver/caddy/pull/6850 * @sashaphmn made their first contribution in https://github.com/caddyserver/caddy/pull/6874 **Full Changelog**: https://github.com/caddyserver/caddy/compare/v2.9.1...v2.10.0-beta.2

v2.10.0-beta.1预发布
? · 2025-03-06

Welcome to the pre-release versions for Caddy 2.10! We hope you will try these betas in your production environments after verifying them in testing/staging, and offer your feedback so the stable release will be better. We're excited for 2.10, as it will bring many improvements, new features, and fixes to your web server. Expect several beta versions as we work through a backlog of issues and pull requests. Aside from many bug fixes, this first beta already features: - **Encrypted ClientHello (ECH):** The [draft spec](https://www.ietf.org/archive/id/draft-ietf-tls-esni-23.html) for ECH is almost finalized, so we can now support this privacy feature for TLS. This is a powerful but nuanced capability; see below (and docs on the website) for details. - **Post-quantum (PQC) key exchange:** Caddy now supports the standardized `x25519mlkem768` cryptographic group by default. - **ACME profiles:** ACME profiles are an experimental draft that allow you to choose properties of your certificates with more flexibility than traditional CSR methods. For example, [Let's Encrypt will issue 6-day certificates](https://letsencrypt.org/2025/01/16/6-day-and-ip-certs/) under a certain profile. Caddy may eventually use that profile by default. - **Via header:** The reverse proxy now sets a Via header instead of a duplicate Server header. - **Global DNS provider:** You can now specify a default "global" DNS module to use instead of having to configure it locally in every part of your config that requires a DNS provider (for example, ACME DNS challenges, and ECH). This is the `dns` global option in the Caddyfile, or in JSON config, it's the `dns` parameter in the `tls` app configuration. ## Encrypted ClientHello (ECH) details Typically, server names (domain names, or "SNI") are sent in the plaintext ClientHello when establishing TLS connections. With ECH, the true server name is encrypted (and wrapped) by an "outer" ClientHello which has a generic SNI of your choosing. With many sites on the same server sharing the same outer SNI, both clients and the server have more privacy related to domain names. Caddy implements fully automated ECH, meaning that it generates (and [soon](https://github.com/golang/go/issues/71920), rotates), publishes, and serves ECH configurations simply by specifying a DNS provider, and the outer/public domain name to use. **Fully automated ECH requires a DNS module built into your Caddy binary.** In order for a client, such as a browser, to know it can use ECH, and what parameters to use, the server's ECH configuration must be published. This config includes the public name, cryptographic parameters, and a public key for encrypting the inner ClientHello. By convention, browsers read the standardized HTTPS-type DNS record containing a `ech` SvcParamKey. Caddy sets this DNS record for all domains being protected, but it needs that DNS provider module plugged in and configured in order to do this. If you are already using the DNS ACME challenge, you should already have a DNS provider plugged in. If you prefer to build Caddy from source with [a DNS module](https://github.com/caddy-dns), it's easy with [xcaddy](https://github.com/caddyserver/xcaddy), for example: `$ xcaddy build ech --with github.com/caddy-dns/cloudflare` The minimum config needed to enable ClientHello is also the _recommended_ config, as it maximizes privacy benefits in most situations. You just need the `ech` global option and a DNS provider specified. Here's an example using Cloudflare as the nameserver: **Caddyfile:** ``` { debug # not required; recommended while testing dns cloudflare {env.CLOUDFLARE_API_KEY} ech ech.example.net } example.com { respond "Hello there!" } ``` This protects all your sites (`example.com` in this case) behind the public name of `ech.example.net`. (As another example, Cloudflare uses `cloudflare-ech.com` for all the sites it serves. We recommend choosing a single public domain and use it to protect all your sites.) **The outer/public name you choose should point to your server.** Caddy will obtain a certificate for this name in order to facilitate safe, reliable connections for clients when needed. Without a certificate, clients may be forced to connect insecurely, or fail to connect at all, in some cases, which not only leaves them vulnerable, but also risks exposing the names of your server's sites. Caddy then uses the specified DNS provider to publish the ECH config(s) for your various site names. It creates (or augments) HTTPS-type records for the domains of your sites (not your ECH public name). If you have more advanced configuration needs, you can use the JSON configuration (more details coming soon; for now, see #6862 or look at the source code). ### Testing and verifying Encrypted ClientHello First make sure Caddy runs successfully with ECH enabled (and a DNS module) in the config. You should see logs that it is generating an ECH config and publishing it to your domain name(s). You will need to use a client that supports ECH. Some custom builds of `curl` do, and Firefox and modern Chrome-based browsers do as well, but you need to enable DNS-over-HTTPS or DNS-over-TLS first (since, obviously, querying DNS in plaintext for a protected domain name will expose the domain and defeat the purpose of ECH). Make sure that your DNS cache is cleared if reusing an existing domain name. Firefox has a way of doing this at `about:networking#dns`. Once you have a suitable client, use [Wireshark](https://www.wireshark.org/) to capture network packets as you load your site. You should see _only_ the outer/public name as SNI (ServerName Indicator) values in the packet capture. If at any time you see the true site name, ECH is not working properly -- it could be a client or server issue. Before filing a bug, please try to pinpoint it as a server issue first. But definitely report server bugs! Thank you! ## Commits * 96c5c554c1241430ac9ddea6f4b68948adcc961b admin: fix index validation for PUT requests (#6824) * 3644ee31cae8e20493d7ccd0c55b0a9c21f20693 build(deps): bump github.com/cloudflare/circl from 1.3.3 to 1.3.7 (#6876) * eacd7720e99f51b6d2dd340849897c0ff812b8c8 build(deps): bump github.com/go-jose/go-jose/v3 from 3.0.3 to 3.0.4 (#6871) * 9996d6a70ba76a94dfc90548f25fbac0ce9da497 build(deps): bump github.com/golang/glog from 1.2.2 to 1.2.4 (#6814) * 11151586165946453275b66ef33794d41a5e047b caddyhttp: ResponseRecorder sets stream regardless of 1xx * 8861eae22350d9e8f94653db951faf85a50a82da caddytest: Support configuration defaults override (#6850) * d7764dfdbbee04d2f63aa1b05150737dfddc0bcf caddytls: Encrypted ClientHello (ECH) (#6862) * a807fe065959baa8ee2ad95156183c0850c2b584 caddytls: Enhance ECH documentation * bc3d497739444a5ce550696b7b0da36e6e3bc777 caddytls: Fix broken refactor * 7b8f3505e33139de0d542566478e98b361bb84bf caddytls: Fix sni_regexp matcher to obtain layer4 contexts (#6804) * 2c4295ee48f494bc8dda5fa09b37612d520c8b3b caddytls: Initial support for ACME profiles * d7872c3bfa673ce9584d00f01a725b93fa7bedf1 caddytls: Refactor sni matcher (#6812) * 172136a0a0f6aa47be4eab3727fa2482d7af6617 caddytls: Support post-quantum key exchange mechanism X25519MLKEM768 * 066d770409917b409d0bdc14cb5ba33d3e4cb33e cmd: automatically set GOMEMLIMIT (#6809) * 1f35a8a4029a338e89998acafa95e1e931a46a27 fastcgi: improve parsePHPFastCGI docs (#6779) * 22563a70eb7b590fcb698680a3ec6d76c0968748 file_server: use the UTC timezone for modified time (#6830) * cfc3af67492eba22686fd13a2b2201c66cd737f3 fix: update broken link to Ardan Labs (#6800) * 99073eaa33af62bff51c31305e3437c57d936284 go.mod: Upgrade CertMagic to v0.21.7 * 1641e76fd742408c85363e4826451ba9ef22bc99 go.mod: Upgrade dependencies * 0d7c63920daecec510202c42816c883fd2dbe047 go.mod: remove glog dependency (#6838) * 932dac157a3c4693b80576477498bb86208b9b30 logging: Always set fields func; fix #6829 * 9e0e5a4b4c2babda81c58f28fe61adfa91d04524 logging: Fix crash if logging error is not HandlerError (#6777) * 904a0fa368b7eacac3c7156ce4a1f6ced8f61f34 reverse_proxy: re-add healthy upstreams metric (#6806) * e7da3b267bcec986aaca960dd22ef834d3b9d4a6 reverseproxy: Via header (#6275) * 9283770f68f570f47ca20aa9c6f9de8cc50063ba reverseproxy: ignore duplicate collector registration error (#6820) ## What's Changed * docs: improve parsePHPFastCGI docs by @dunglas in https://github.com/caddyserver/caddy/pull/6779 * Fixes crash if logging error is not HandlerError by @kkroo in https://github.com/caddyserver/caddy/pull/6777 * chore: update quic-go to v0.49.0 by @marten-seemann in https://github.com/caddyserver/caddy/pull/6803 * chore: don't use deprecated `archives.format_overrides.format` by @mohammed90 in https://github.com/caddyserver/caddy/pull/6807 * caddytls: Fix sni_regexp matcher to obtain layer4 contexts by @vnxme in https://github.com/caddyserver/caddy/pull/6804 * feat: automatically set GOMEMLIMIT by @dunglas in https://github.com/caddyserver/caddy/pull/6809 * caddytls: Refactor sni matcher by @vnxme in https://github.com/caddyserver/caddy/pull/6812 * reverse_proxy: re-add healthy upstreams metric by @mohammed90 in https://github.com/caddyserver/caddy/pull/6806 * fix: update broken link to Ardan Labs by @sbruens in https://github.com/caddyserver/caddy/pull/6800 * build(deps): bump github.com/golang/glog from 1.2.2 to 1.2.4 by @dependabot in https://github.com/caddyserver/caddy/pull/6814 * reverseproxy: ignore duplicate collector registration error by @mohammed90 in https://github.com/caddyserver/caddy/pull/6820 * fix: fix index validation for PUT requests by @debug-ing in https://github.com/caddyserver/caddy/pull/6824 * file_server: use the UTC timezone for modified time by @WeidiDeng in https://github.com/caddyserver/caddy/pull/6830 * feat/tests: tests for error handling & metrics in admin endpoints by @gdhameeja in https://github.com/caddyserver/caddy/pull/6805 * chore: upgrade Go version to 1.24 by @mohammed90 in https://github.com/caddyserver/caddy/pull/6839 * remove glog dependency by @Ns2Kracy in https://github.com/caddyserver/caddy/pull/6838 * update quic-go to v0.50.0 by @marten-seemann in https://github.com/caddyserver/caddy/pull/6854 * Support Caddy Test Configuration Defaults Override. by @baruchyahalom in https://github.com/caddyserver/caddy/pull/6850 * chore: upgrade cobra by @mohammed90 in https://github.com/caddyserver/caddy/pull/6868 * build(deps): bump github.com/go-jose/go-jose/v3 from 3.0.3 to 3.0.4 by @dependabot in https://github.com/caddyserver/caddy/pull/6871 * caddytls: Encrypted ClientHello (ECH) by @mholt in https://github.com/caddyserver/caddy/pull/6862 * build(deps): bump github.com/cloudflare/circl from 1.3.3 to 1.3.7 by @dependabot in https://github.com/caddyserver/caddy/pull/6876 * docs: replaced the name and twitter link by @sashaphmn in https://github.com/caddyserver/caddy/pull/6874 ## New Contributors * @sbruens made their first contribution in https://github.com/caddyserver/caddy/pull/6800 * @debug-ing made their first contribution in https://github.com/caddyserver/caddy/pull/6824 * @Ns2Kracy made their first contribution in https://github.com/caddyserver/caddy/pull/6838 * @baruchyahalom made their first contribution in https://github.com/caddyserver/caddy/pull/6850 * @sashaphmn made their first contribution in https://github.com/caddyserver/caddy/pull/6874 **Full Changelog**: https://github.com/caddyserver/caddy/compare/v2.9.1...v2.10.0-beta.1

v2.9.1
? · 2025-01-08

This is a patch release fixing a few issues related to FastCGI, HTTP/3 and unix sockets, log file permissions, repeated TERM signals, and an ARI edge case. It also adds Caddyfile support for response matching in the `header` directive. Thanks to everyone who reported bugs and helped with fixes! ## Changelog * 34cff4af7db1365bba6decc647ccfb6bf1b21afd core: Only initiate exit once (should fix #6707) * 50778b55425d378f709599c0d424b0138af592f4 fix: disable h3 for unix domain socket (#6769) * 0e570e0cc717f02cf3800ae741df70cd074c7275 go.mod: Upgrade CertMagic to 0.21.6 (fix ARI handshake maintenance) * e48b75843b7eff2948b573391fb41535b5e333ef header: `match` subdirective for response matching (#6765) * 1f927d6b07d52d7cf46f1f3020c1ea5993a3e5e8 log: Only chmod if permission bits differ; make log dir (#6761) * 1bd567d7ad41d5509e2aa60cf36e749f195ad83c reverseproxy: buffer requests for fastcgi by default (#6759) ## What's Changed * reverse proxy: fastcgi buffer requests for fastcgi by default by @WeidiDeng in https://github.com/caddyserver/caddy/pull/6759 * fix: disable h3 for unix domain socket by @Geun-Oh in https://github.com/caddyserver/caddy/pull/6769 * log: Only chmod if permission bits differ by @mholt in https://github.com/caddyserver/caddy/pull/6761 * header: `match` subdirective for response matching by @lilnasy in https://github.com/caddyserver/caddy/pull/6765 ## New Contributors * @Geun-Oh made their first contribution in https://github.com/caddyserver/caddy/pull/6769 * @lilnasy made their first contribution in https://github.com/caddyserver/caddy/pull/6765 **Full Changelog**: https://github.com/caddyserver/caddy/compare/v2.9.0...v2.9.1