Releases: caddyserver/caddy
v2.6.2
This release brings a number of bug fixes and minor enhancements. All users should upgrade after testing and verifying their setups. Thank you to all who contributed!
If you are coming from < 2.6, please see the 2.6 release notes because a lot is new!
Changelog
- 037dc23 admin: Use replacer on listen addresses (#5071)
- 498f32b caddyconfig: Implement retries into HTTPLoader (#5077)
- 9873ff9 caddyhttp: Remote IP prefix placeholders
- 61822f1 caddyhttp: replace placeholders in map defaults (#5081)
- e07a267 caddytest: Revise sleep durations
- 253d97c core: Chdir to executable location on Windows (#5115)
- ab720fb core: Fix ListenQUIC listener key conflict
- e3e8aab core: Refactor and improve listener logic (#5089)
- e4fac12 core: Set version manually via CustomVersion (#5072)
- f7c1a51 fastcgi: Redirect using original URI path (fix #5073)
- 2be56c5 fileserver: Treat invalid file path as NotFound (#5099)
- b1d04f5 fileserver: better dark mode visited link contrast (#5105)
- 33f60da fileserver: stop listing dir when request context is cancelled (#5131)
- 2153a81 forwardauth: Canonicalize header fields (fix #5038) (#5097)
- fe91de6 go.mod: Upgrade select dependencies
- 7041970 headers: Support repeated WriteHeader if 1xx (fix #5074)
- d46ba2e httpcaddyfile: Fix
metrics
global option parsing (#5126) - 6bad878 httpcaddyfile: Improve detection of indistinguishable TLS automation policies (#5120)
- 2808de1 httpcaddyfile: Skip
automate
whenauto_https off
is specified (#5110) - 3e1fd2a httpcaddyfile: Wrap site block in subroute if host matcher used (#5130)
- 9e1d964 logging: Add
time_local
option to use local time instead of UTC (#5108) - 01e192e logging: Better
console
encoder defaults (#5109) - 99ffe93 logging: Fix
skip_hosts
with wildcards (#5102) - ea58d51 logging: Perform filtering on arrays of strings (where possible) (#5101)
- 5e52bbb map: Remove infinite recursion check (#5094)
- b4e28af replacer: working directory global placeholder (#5127)
- e2991eb reverseproxy: On 103 don't delete own headers (#5091)
- 2a8c458 reverseproxy: Parse humanized byte size (fix #5095)
- d055692 reverseproxy: fix upstream scheme handling in command (#5088)
- 013b510 rewrite: Only trim prefix if matched
New Contributors
- @lemmi made their first contribution in #5088
- @willnorris made their first contribution in #5081
- @yroc92 made their first contribution in #5071
- @iliana made their first contribution in #5105
- @TobiX made their first contribution in #5106
- @likev made their first contribution in #5099
- @cherouvim made their first contribution in #5121
Full Changelog: v2.6.1...v2.6.2
v2.6.1
Hotfix for unix sockets, the encode
handler, and the caddy file-server
command. Please see the release notes for v2.6.0 for other important information if you're coming from < 2.6!
Changelog
v2.6.0
Caddy 2.6
This is our biggest release since Caddy 2.
Caddy 2 changed the way the world serves the Web. By providing an online config API, automatic HTTPS, unlimited extensibility, certificate automation at scale, modern protocols, sane defaults, and an unrivaled developer experience, we boldly raised the bar for web servers.
Now with Caddy 2.6, we're doing it again. Caddy 2.6 is the first general-purpose web server to seamlessly enable the newly-standardized HTTP/3 protocol for all configurations by default. We've virtualized the file system so you can serve content from anywhere or anything. New event features let you observe and control Caddy's internals with custom actions. Caddy is more useful than ever for developers with its enhanced CLI tooling and features. And it's faster than ever with non-trivial performance improvements. We think you will love this release.
UPDATE: Please use v2.6.1 for hotfixes related to unix sockets, encode
, and caddy file-server
.
Special dedication
This release is dedicated to the late Peter Eckersley, who passed away September 2, 2022. Peter is one of the brilliant minds behind Let's Encrypt; his work has benefited billions of people. I met Peter at the Let's Encrypt launch party in a little bar in San Francisco in 2015 and have never forgotten that occasion. He later co-authored a published research paper called Let’s Encrypt: An Automated Certificate Authority to Encrypt the Entire Web, which highly espoused Caddy's ACME integration: "We hope to see other popular server software follow Caddy’s lead."
We look forward to when other servers do that, and we hope to honor Peter's work and influence which will live on through his memory and the encrypted Web he made possible.
Sponsors
ZeroSSL remains Caddy's executive sponsor.
We were thrilled to welcome Stripe recently as an enterprise sponsor!
Other notable sponsors include AppCove, Dukaan, Suborbital, Tailscale, plus Bubble and GitHub which both made generous one-time donations.
We have many other vital sponsors and donors on which we also rely. Our sponsors come from all over the world and include independent professionals, startups, and small companies -- and they are the absolute best. Thank you for making a more secure Web possible!
Personal note from Matt: Recent life upgrades mean that your sponsorships now sustain a family of 5 so that I can continue to maintain Caddy. Two years ago, I don't think I would have taken this risk because I'd need to find other work to provide for a family. Thank you for coming together as a professional community to make the Caddy project possible!
We strongly recommend that companies who -- or companies whose customers -- use or benefit from Caddy become a sponsor to ensure ongoing maintenance, priority development, private support, and more. Sponsorship tiers can be tailored to your requirements!
Highlights
HTTP/3 is here (#4707)
Caddy now enables RFC 9114-compliant HTTP/3 by default. The experimental_http3
option has graduated and been removed. We've removed another experimental option, allow_h2c
, and individual HTTP versions (h1 h2 h2c h3
) can now be toggled with the new protocols
setting.
Note that HTTP/3 utilizes the QUIC transport, which requires UDP. If your network or firewall configuration only allows TCP, HTTP/3 connections will fail and clients (should) fall back to HTTP/2. For servers with properly-configured UDP networks, HTTP/3 should "just work" for enabled clients.
HTTP/3 clients can connect by reading Caddy's Alt-Svc header to know how to connect to Caddy via UDP. This header is now emitted automatically and by default. Other than that, there are no other changes needed to existing servers, as Caddy opens a separate UDP socket for HTTP/3.
Our HTTP/3 server attempts to mitigate amplification and reflection attacks by requiring address validation when the server is under load. This adds one round-trip for clients, but is only done as a defensive measure when necessary.
Serious thanks to @marten-seemann who builds and maintains the quic-go library we depend on for this. (Go has not announced any plans to officially support or implement HTTP/3.) We expect numerous QUIC and HTTP/3 improvements to come as implementations and best practices mature with more production experience.
Virtual file systems (#4909)
Caddy's file_server
module now supports virtual file systems. We've replaced all hard-coded os.Open()
, os.Stat()
, etc. calls with Go's relatively new io/fs
package, and introduced a new Caddy module namespace caddy.fs
for implementations of such file systems.
Some examples of what is possible:
- Serve content from S3 or other blob/cloud storage services
- Serve dynamically-generated content that "feels" static
- Embed your site directly into your
caddy
binary and serve it from memory - Serve content directly from an archive file (e.g.
.zip
or.tar.gz
) - Load files from a database instead of disk
Basically, instead of serving files from the local disk, you can have Caddy serve the "files" from somewhere or something else. The default is still the local file system.
Note that this feature isn't limited to just Caddy's file_server
module. Potentially any module that reads the local disk may benefit from using caddy.fs
modules instead.
I wrote a module that lets you embed your site within your caddy
binary -- wherever your server goes, your site goes!
We encourage the community to implement and publish new file system modules for Caddy. (From an early tweet there seems to be quite high demand.)
Events (#4912 and #4984)
Not surprisingly, many people prefer Caddy to automate certificates used with other software/services. Until now, there hasn't been a great way to know when Caddy has obtained or renewed a certificate (deferred in part by our opinion that certificate management should be baked into the software using the certificate in the first place). Cron jobs generally work for reloading new certificates into services because certificate expiry is mostly predictable, but now there is a better way with one of our most requested features: events!
We thought about events in general for a long time and discussed questions like, "What makes an event different from a log?" "Are events synchronous?" "Do self-initiated events get emitted before or after their code (are they past-tense or future-tense) -- or both? or neither (asynchronous)?" "What do we like from existing event systems?" "What do we wish event systems did differently?"
While we think we have pretty good answers to these questions now, we won't be sure until we gather more production experience. For this reason, events are implemented as an experimental app module -- not as part of the core. (Remember, Caddy's core currently only loads config and sets up logging/storage.) This means that Caddy's core cannot emit events.[^1] So even though our event implementation may change, it is likely to be only slight and gradual changes; and we encourage anyone and everyone to start using events as soon as possible and to give us your feedback. We think we have the start of a great event system, but we need you to prove it!
Caddy modules can emit events when interesting things happen. For example, the reverse proxy emits healthy
and unhealthy
events when backends go up and down. The TLS app emits cert_obtaining
, cert_obtained
, and cert_failed
before and after obtaining a certificate or after the operation failed, respectively; and cert_ocsp_revoked
after a certificate is discovered to be revoked by OCSP. There are several more events already, with even more to be added later.
Events can have data associated with them. For example, healthy
/unhealthy
come with the address of the host; cert_obtained
has the domain name, issuer, and storage path. You can access this from config in placeholders, e.g. {event.data.identifier}
.
Caddy modules can subscribe to events by specifying the name(s) of events to bind to, and the Caddy module ID(s) or namespace(s) to watch. When an event is emitted, it propagates from the module that emitted it up the provisioning heirarchy. This means that an event emitted by http.handlers.reverse_proxy
will fire for http.handlers
and http
as well, similar to the DOM in HTML/JavaScript.
Event handlers are invoked synchronously. We chose this for several reasons. First, despite how easy Go makes concurrency, there are many subtleties to concurrency in a server. Goroutines may be lightweight, but their operations might not be; and if event goroutines are starting more quickly than they are stopping, we either drop events arbitrarily or run out of memory/CPU. Also, we think one of the qualities that differentiates events from logs is the ability for an event to influence the emitting code's flow: a true "hook" in that sense. Instead of simply observing that somet...
v2.6.0-beta.5
This release and beta.4 are mainly tests of our CI, but also contains a bunch of small fixes or enhancements, including, notably, the use of sendfile
and other optimizations. See the release notes for beta.3 for everything else until 2.6.0 lands soon. Full release notes coming!
Please see v2.6.0 instead.
v2.6.0-beta.3
This is the first beta release for Caddy 2.6. Please try it out and report any regressions you notice! Thanks to everyone who helped out! 😊
Beta 1 and beta 2 were trial runs for our CI upgrades, so this is technically beta 3. There are no code changes from beta 1 to beta 3. Thank you @mohammed90 for figuring out the CI magic!
Please see the v2.6.0 release.
Changelog: v2.5.2...v2.6.0-beta.3
v2.5.2
This patch release fixes bugs, adds some new features, and makes worthwhile enhancements. We recommend everyone test and upgrade!
Many improvements have been made to the reverse_proxy
module.
Highlights:
- New
/adapt
admin endpoint: Use your installed config adapters via API in addition to the existingcaddy adapt
CLI command. - New
Etag
/If-Match
support for config API: Safely update your config concurrently and avoid collisions by using our unique Etag implementation. - Rename copied headers from reverse_proxy: If you're using
handle_response
, you can more easily map headers to a different name for clients. - Many HTTP matchers have been added to CEL: You can now use the logic of our HTTP request matchers in CEL expressions.
- Notable bug fixes: EAB reuse, various QUIC & HTTP/3 fixes, more specific HTTP status codes, various reverse proxy fixes.
Changelog
- 660c59b admin: Implement /adapt endpoint (close #4465) (#4846)
- ad3a83f admin: expect quoted ETags (#4879)
- f259ed5 admin: support ETag on config endpoints (#4579)
- 1498132 caddyhttp: Log error from CEL evaluation (fix #4832)
- 0a14f97 caddytls: Make peer certificate verification pluggable (#4389)
- 412dcc0 caddytls: Reuse issuer between PreCheck and Issue (#4866)
- 499ad6d core: Micro-optim in run() (#4810)
- c0f76e9 fileserver: Use safe redirects in file browser
- 58e05ca forwardauth: Fix case when
copy_headers
is omitted (#4856) - 0b6f764 forwardauth: Support renaming copied headers, block support (#4783)
- 8bac134 go.mod: Bump up quic-go to v0.28.0, fixes for BC breaks (#4867)
- 3d18bc5 go.mod: Update go-yaml to v3
- 5601393 go.mod: Update some dependencies
- 8e6bc36 go.mod: Upgrade some dependencies
- 53c4d78 headers: Only replace known placeholders (#4880)
- 0bcd02d headers: Support wildcards for delete ops (close #4830) (#4831)
- 58970ca httpcaddyfile: Add
{err.*}
placeholder shortcut (#4798) - b687d7b httpcaddyfile: Support multiple values for
default_bind
(#4774) - a926779 reverseproxy: Add --internal-certs CLI flag #3589 (#4817)
- aaf6794 reverseproxy: Add renegotiation param in TLS client (#4784)
- 54d1923 reverseproxy: Adjust new TLS Caddyfile directive names (#4872)
- 7f9b1f4 reverseproxy: Correct the
tls_server_name
docs (#4827) - c82fe91 reverseproxy: Dynamic ServerName for TLS upstreams (#4836)
- d6bc9e0 reverseproxy: Err 503 if all upstreams unavailable
- 98468af reverseproxy: Fix double headers in response handlers (#4847)
- 25f1051 reverseproxy: Fix panic when TLS is not configured (#4848)
- 5e729c1 reverseproxy: HTTP 504 for upstream timeouts (#4824)
- f9b42c3 reverseproxy: Make TLS renegotiation optional
- b6e96fa reverseproxy: Skip TLS for certain configured ports (#4843)
- 57d27c1 reverseproxy: Support http1.1>h2c (close #4777) (#4778)
- 9864b13 reverseproxy: api: Remove misleading 'healthy' value
- 693e9b5 rewrite: Handle fragment before query (fix #4775)
- 6891f7f templates: Add
humanize
function (#4767) - 9e760e2 templates: Documentation consistency (#4796)
New Contributors
- @nekohasekai made their first contribution in #4782
- @davidbgk made their first contribution in #4796
- @git001 made their first contribution in #4767
- @varianone made their first contribution in #4817
- @Gr33nbl00d made their first contribution in #4389
- @yaslama made their first contribution in #4784
- @kresike made their first contribution in #4836
- @TristonianJones made their first contribution in #4715
- @jhwz made their first contribution in #4579
Full Changelog: v2.5.1...v2.5.2
v2.5.1
This is a minor patch release that fixes some bugs and also enhances reverse_proxy
with capabilities that weren't ready in time for v2.5.0.
Highlights
- Fixed regression in Unix socket admin endpoints.
- Fixed regression in
caddy trust
commands. - Hash-based load balancing policies (ip_hash, uri_hash, header, and cookie) use an improved highest-random-weight (HRW) algorithm for increased consistency. The new rendezvous hash will ensure a client or request is consistently mapped to a particular upstream even if the list of upstreams changes.
- The reverse proxy is now able to rewrite the method and URI on its internal copy of the request that goes to the upstream. Combined with new
handle_response
capabilities, this enables the reverse proxy to fire off "pre-check requests" (for lack of a better term) to make routing decisions based on the results of that call. This enables a commonly-emerging pattern called forward authentication wherein a backend is queried to assess a client's authorization to be proxied. The full, verbose config for this is very flexible but tedious, so we made a new wrapper directive calledforward_auth
that eliminates the boilerplate (very similar to thephp_fastcgi
directive):
forward_auth authelia:9091 {
uri /api/verify?rd=https://auth.example.com
copy_headers Remote-User Remote-Groups Remote-Name Remote-Email
}
This works with authentication providers like Authelia, and more.
What's Changed
- caddypki: Fix
caddy trust
command to use the correct API endpoint by @francislavoie in #4730 - reverseproxy: Improve hashing LB policies with HRW by @mholt in #4724
- Add missing backticks by @mahgoh in #4737
- caddyhttp: Improve listen addr error message for IPv6 by @francislavoie in #4740
- cmd: Fix unix socket addresses for admin API requests by @francislavoie in #4742
- logging: Use
RedirectStdLog
by @francislavoie in #4732 - logging: Implement rename filter, changes field key names by @francislavoie in #4745
- httpcaddyfile: Fix duplicate access log when debug is on by @francislavoie in #4746
- reverseproxy: Fix Caddyfile support for
replace_status
by @francislavoie in #4754 - templates: Add custom template function registration by @kroppt in #4757
- reverseproxy: Permit resolver addresses to not specify a port by @francislavoie in #4760
- caddyfile: Shortcut for
remote_ip
for private IP ranges by @francislavoie in #4753 - reverseproxy: Support performing pre-check requests by @francislavoie in #4739
- map: Prevent output destinations overlap with Caddyfile shorthands by @francislavoie in #4657
New Contributors
Changelog
- ec86a2f caddyfile: Shortcut for
remote_ip
for private IP ranges (#4753) - dcc98da caddyhttp: Improve listen addr error message for IPv6 (#4740)
- d543ad1 caddypki: Fix
caddy trust
command to use the correct API endpoint (#4730) - 2e4c091 cmd: Fix unix socket addresses for admin API requests (#4742)
- af73215 httpcaddyfile: Fix duplicate access log when debug is on (#4746)
- 0be3d99 logging: Implement rename filter, changes field key names (#4745)
- 3017b24 logging: Use
RedirectStdLog
to capture more stdlib logs (#4732) - f7be0ee map: Prevent output destinations overlap with Caddyfile shorthands (#4657)
- 4a223f5 reverseproxy: Fix Caddyfile support for
replace_status
(#4754) - 40b193f reverseproxy: Improve hashing LB policies with HRW (#4724)
- e7fbee8 reverseproxy: Permit resolver addresses to not specify a port (#4760)
- f6900fc reverseproxy: Support performing pre-check requests (#4739)
- e84e19a templates: Add custom template function registration (#4757)
- 3ab6483 templates: Add missing backticks in docs (#4737)
Full Changelog: v2.5.0...v2.5.1
v2.5.0
Caddy 2.5 introduces new features you'll love as well as a huge number of bug fixes and enhancements. Thank you to everyone who contributed!
Feel free to ask on the forum if you have any questions or feedback.
Highlights
- Reverse proxy: ✨ Dynamic upstreams, which is the ability to get the list of upstreams at every request (more specifically, every iteration in the proxy loop of every request) rather than just once at config-load time. Dynamic upstream modules can be plugged in to provide Caddy with the latest list of backends in real-time. Two standard modules have been implemented which can get upstreams from SRV and A/AAAA record lookups.
⚠️ This deprecates thelookup_srv
JSON field for upstreams (andsrv+
scheme prefix in the Caddyfile), which will be removed in the future.
- Automatic HTTPS: Caddy will automatically try to get relevant certificates from the local Tailscale instance (if running with permission to access the Tailscale socket). This makes services running on a Tailscale network automatically available over trusted HTTPS with Caddy.
- Tracing: New OpenTelemetry integration with the
tracing
handler module and associatedtracing
directive. - Reverse proxy: When using the response handlers, a new handler
copy_response
is available to copy the proxy's response back to the client, andcopy_response_headers
may be used to selectively copy header values from the proxy's response. - API: Added new endpoints
/pki/ca/<id>
and/pki/ca/<id>/certificates
for getting information about Caddy's managed CAs, including the chain of root and intermediate certificates.
Notable
- Reverse proxy: The
X-Forwarded-Host
header will now be automatically set, along withX-Forwarded-For
andX-Forwarded-Proto
. ⚠️ Reverse proxy: IncomingX-Forwarded-*
headers will no longer be automatically trusted, to prevent spoofing. Now,trusted_proxies
must be configured to specify a list of downstream proxies which are trusted to have sent good values. You only need to configure trusted proxies if Caddy is not the first server being connected to. For example, if you have Cloudflare in front of Caddy, then you should configure this with Cloudflare's list of IP ranges.- Automatic HTTPS: Revoked certificates will be automatically replaced more reliably.
- Automatic HTTPS: Can now get certificates from Managers. As opposed to Issuers (such as the default ACME issuers) which give Caddy certificates to manage from a CSR, Managers give Caddy certificates to serve (rather than manage) during TLS handshakes.
- Automatic HTTPS: A DNS challenge domain override can be configured to delegate the solving of the challenge to a different domain.
- Automatic HTTPS: The DNS challenge propagation checks can now be delayed or disabled by setting
propagation_delay
orpropagation_timeout
to -1, respectively. - Reverse proxy: The default dial timeout for the HTTP transport has been adjusted down to
3s
(was10s
), which should allow for more easily configuring load balancing retries. - Logging: HTTP access logs will now render empty values for often-sensitive HTTP headers such as Cookie, Authorization, and Proxy-Authorization. Logging such credentials is now opt-in with the
log_credentials
global option in the Caddyfile, or the server'slogs > should_log_credentials
field in JSON. - Logging: Logs can now be filtered by query string parameters, cookie values, and regular expressions; and log values can be hashed. These features are useful for redacting sensitive information.
- Logging: Errors during request handling will now be logged at
DEBUG
level if the error was handled viaerrors
routes (handle_errors
in Caddyfile). ⚠️ Logging: Removed the deprecatedcommon_log
field from HTTP access logs, and thesingle_field
encoder. If you relied on this, you may use the transform encoder plugin to encode logs in Common Log format.⚠️ Logging: Theremote_addr
field has been replaced byremote_ip
andremote_port
fields in HTTP access logs, which split up the two parts of the remote address. This improves ease of use for some tooling which only expect an IP address, without a port.- HTTP server: The
vars
matcher can now match on multiple possible values. - HTTP server: Requests can now be assigned a random and unique UUID from the new
{http.request.uuid}
placeholder. - HTTP server: New
http_redirect
listener wrapper which can be used to redirect HTTP requests that come in on a server listening for HTTPS requests to be redirected tohttps://
. ⚠️ Caddyfile: Deprecated paths in site addresses. Prefer using path matchers within your site block instead.- Caddyfile: New
default_bind
global option lets you specify the default interface all sockets should bind to. - Caddyfile: New
pki
global option lets you configure the properties of the internal CAs managed by Caddy. - Caddyfile: New
method
directive allows rewriting the request method via Caddyfile. ⚠️ Caddyfile: Thereverse_proxy
directive'shandle_response
subdirective has had its status replacement functionality moved to a newreplace_status
subdirective. This makes sure that the functionality ofhandle_response
is not overloaded, and usage is clearer.- Caddyfile: The
map
directive now casts outputs to the appropriate scalar type if possible (int, float, bool). If you need to force a string, you may use double quotes or backticks #4643. - Caddyfile: New
vars
directive allows setting some variables during request handling for later use in another handler or matcher. - Caddyfile: The Caddyfile adapter is now stricter about curly braces for block openers to try to prevent parsing ambiguities.
- Caddyfile: The
caddy fmt
CLI command now has a--diff
option which lets you visually see the formatting differences. ⚠️ Admin: Renamed experimental propertyload_interval
➡️load_delay
for clarification, and improved dynamic config loading.
🛡️ Thanks to David Leadbeater for reporting a security vulnerability related to HTTP methods and metrics cardinality, which was fixed in this release.
New Contributors
- @adamburgess made their first contribution in #4460
- @12f23eddde made their first contribution in #4444
- @rayjlinden made their first contribution in #4023
- @GallopingKylin made their first contribution in #4522
- @ForestJohnson made their first contribution in #4534
- @VojtechVitek made their first contribution in #4535
- @Ikke made their first contribution in #4544
- @YourTechBud made their first contribution in #4603
- @BitWuehler made their first contribution in #4597
- @ttys3 made their first contribution in #4572
- @crccw made their first contribution in #4596
- @andriikushch made their first contribution in #4361
- @renbou made their first contribution in #4654
- @cuishuang made their first contribution in #4702
Changelog
v2.5.0-rc.1
Please see the release notes for v2.5.0. In fact, just use v2.5.0 instead.
Interim Changelog: v2.5.0-beta.1...v2.5.0-rc.1
v2.5.0-beta.1
Please see the release notes for v2.5.0-rc.1. In fact, just use v2.5.0-rc.1 instead.
Interim Changelog: v2.4.6...v2.5.0-beta.1