github caddyserver/caddy v2.10.0-beta.2

pre-release20 hours ago

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 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 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.

⚠️ 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, 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, it's easy with 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:

{
	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 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:

  • 96c5c55 admin: fix index validation for PUT requests (#6824)
  • 3644ee3 build(deps): bump github.com/cloudflare/circl from 1.3.3 to 1.3.7 (#6876)
  • eacd772 build(deps): bump github.com/go-jose/go-jose/v3 from 3.0.3 to 3.0.4 (#6871)
  • 9996d6a build(deps): bump github.com/golang/glog from 1.2.2 to 1.2.4 (#6814)
  • 1115158 caddyhttp: ResponseRecorder sets stream regardless of 1xx
  • 8861eae caddytest: Support configuration defaults override (#6850)
  • d7764df caddytls: Encrypted ClientHello (ECH) (#6862)
  • a807fe0 caddytls: Enhance ECH documentation
  • bc3d497 caddytls: Fix broken refactor
  • 7b8f350 caddytls: Fix sni_regexp matcher to obtain layer4 contexts (#6804)
  • 2c4295e caddytls: Initial support for ACME profiles
  • d7872c3 caddytls: Refactor sni matcher (#6812)
  • 172136a caddytls: Support post-quantum key exchange mechanism X25519MLKEM768
  • 066d770 cmd: automatically set GOMEMLIMIT (#6809)
  • 1f35a8a fastcgi: improve parsePHPFastCGI docs (#6779)
  • 22563a7 file_server: use the UTC timezone for modified time (#6830)
  • cfc3af6 fix: update broken link to Ardan Labs (#6800)
  • 99073ea go.mod: Upgrade CertMagic to v0.21.7
  • 1641e76 go.mod: Upgrade dependencies
  • 0d7c639 go.mod: remove glog dependency (#6838)
  • 932dac1 logging: Always set fields func; fix #6829
  • 9e0e5a4 logging: Fix crash if logging error is not HandlerError (#6777)
  • 904a0fa reverse_proxy: re-add healthy upstreams metric (#6806)
  • e7da3b2 reverseproxy: Via header (#6275)
  • 9283770 reverseproxy: ignore duplicate collector registration error (#6820)

Beta 2:

  • f4432a3 caddyfile: add error handling for unrecognized subdirective/options in various modules (#6884)
  • 84364ff caddypki: Remove lifetime check at Caddyfile parse (fix #6878)
  • adbe7f8 caddytls: Only make DNS solver if not already set (fix #6880)
  • d57ab21 caddytls: Pointer receiver (fix #6885)
  • 4ebcfed caddytls: Reorder provisioning steps (fix #6877)
  • a686f7c cmd: Only set memory/CPU limits on run (fix #6879)
  • 1987620 cmd: Promote undo maxProcs func to caller
  • 220cd1c reverseproxy: more comments about buffering and add new tests (#6778)

What's Changed

New Contributors

Full Changelog: v2.9.1...v2.10.0-beta.2

Don't miss a new caddy release

NewReleases is sending notifications on new releases.