Commit Graph

108 Commits (2.11)

Author SHA1 Message Date
D'Ali Ben Macha 9a83df63f4
admin: authorize remote requests matching any permission entry (#8317)
* admin: authorize remote requests matching any permission entry

enforceAccessControls rejected a request as soon as one permission entry
did not match its method or path, so only the first entry was usable.
Allow the request if any entry permits both, and deny only after all fail.

* admin: check every access entry that holds the client key

A key listed in several access control entries was only checked
against the first one; deny only after all of them are tried.

(cherry picked from commit c168dbc4ca)
2026-11-03 18:21:22 -05:00
Kévin Dunglas cee467814d
admin: better Cache-Control handling (#8330)
(cherry picked from commit 84eaf50b7b)
2026-11-03 00:53:50 -05:00
amir daraby 7e82a6b528
admin: fix warnings and status code in /load API (#7267)
* admin: fix warnings and status code in /load API

* fix admin.go: gci import formatting

---------

Signed-off-by: Matt Holt <mholt@users.noreply.github.com>
Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
2026-09-23 08:55:38 -06:00
Abdellatif Anaflous f7d58438b0
admin: fix host allow-list comparison to be case-insensitive (#7993)
The admin host check compared r.Host against the allowed URL's Host
with byte-for-byte equality. url.Parse does not normalize host case,
so an allowed 'http://Example.com:2019' rejected a client Host of
'example.com:2019' with 'host not allowed', and the same happened for
an uppercase variant of a lowercase entry like localhost.

The Origin check got this treatment in 7973 already, the DNS rebinding
Host check right next to it did not. Both read the same allowedOrigins
list, so this applies the same strings.EqualFold treatment there.

Regression test covers both fold directions, the default localhost
entry and the negative case that must keep failing
2026-09-05 12:39:37 +00:00
Mohammed Al Sahaf af29f9ea91
admin: fix origin allow-list host comparison to be case-insensitive (#7973)
The admin origin allow-list compared origin.Host against the allowed
URL's Host with byte-for-byte equality. url.Parse does not normalize
host case, so an allowed 'http://Example.com:8080' rejected a client
origin of 'http://example.com:8080' even though RFC 3986 §3.2.2 says
host names are case-insensitive. Use strings.EqualFold.

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>
2026-09-03 07:46:43 +10:00
Amariah Abishai d6637934e8
admin: normalize request path in remote admin access-control check (defense-in-depth) (#7910)
* admin: normalize request path in remote admin access-control check

Co-authored-by: atlarix-agent <agent@atlarix.dev>

* admin: fix empty allowedPath regression and dead code in path normalization

path.Clean("") returns ".", so cleaning allowedPath unconditionally
silently broke the allow-all behavior when Paths: [""] is configured.
Short-circuit the empty case before cleaning to preserve that behavior.

Also remove the dead strings.HasSuffix(allowedPath, "/") branch —
after path.Clean the path never has a trailing slash, so the unified
reqPath == allowedPath || HasPrefix(reqPath, allowedPath+"/") form
covers exact match, subpath boundary, and trailing-slash requests.

Co-authored-by: atlarix-agent <agent@atlarix.dev>
Co-authored-by: iabdullah215 <muhammadabdullah8040@gmail.com>

* admin: validate non-canonical configured paths at provisioning

path.Clean(allowedPath) silently broadens misconfigured values like
// or /.. into /, which grants unintended access to all endpoints.
Reject non-canonical paths during provisioning in
replaceRemoteAdminServer so misconfigurations fail fast with a
clear error. The path.Clean in adminPathAllowed remains as
defense-in-depth but is now a safe no-op on validated inputs.

Co-authored-by: atlarix-agent <agent@atlarix.dev>

* admin: validate non-canonical configured paths at provisioning

path.Clean(allowedPath) silently broadens misconfigured values like
// or /.. into /, which grants unintended access to all endpoints.
Reject non-canonical paths during provisioning in
replaceRemoteAdminServer so misconfigurations fail fast with a
clear error. The path.Clean in adminPathAllowed remains as
defense-in-depth but is now a safe no-op on validated inputs.

Co-authored-by: atlarix-agent <agent@atlarix.dev>

* admin: fix TrimRight → TrimSuffix in provisioning path validation

strings.TrimRight strips all trailing slashes, so a configured path
like /foo// passed validation (both slashes trimmed to /foo matching
path.Clean output) but was silently broadened to /foo at runtime.

Use strings.TrimSuffix instead, which removes exactly one trailing
slash — the only form the exemption was meant to allow (users write
/pki/ca/prod/ meaning the /pki/ca/prod scope).

Also update the // test case: with TrimSuffix, // is just / + one
trailing slash, which is valid under the exemption. Add a new test
for /foo// (double trailing slashes → wantErr: true).

Co-authored-by: atlarix-agent <agent@atlarix.dev>

* admin: reject non-canonical root permission path

* admin: preserve trailing-slash permission semantics

---------

Co-authored-by: atlarix-agent <agent@atlarix.dev>
Co-authored-by: iabdullah215 <muhammadabdullah8040@gmail.com>
Co-authored-by: Zen Dodd <mail@steadytao.com>
2026-08-25 12:12:08 -06:00
Br1an d80774cb3f
metrics: Add nil check for metricsHandler in AdminMetrics.serveHTTP (#7553)
* metrics: Add nil check for metricsHandler in AdminMetrics.serveHTTP

Prevents panic when the admin metrics endpoint is accessed before
the module is fully provisioned. Returns a proper API error instead
of crashing.

* admin: provision router modules before registering routes

Instead of adding a nil check for metricsHandler, address the root
cause by provisioning admin router modules before calling Routes().
This ensures all handler state is initialized before routes are
registered on the mux.

Merge newAdminHandler and provisionAdminRouters into a single step,
removing the two-phase setup where routes were registered first and
modules provisioned later. The AdminConfig.routers field is no longer
needed since provisioning happens inline.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: go fmt admin.go

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-11 17:27:03 -06:00
Amemoyoi 18ab0f955f
admin: reject non-canonical config array indices (#7592)
* admin: reject non-canonical config array indices

* admin: expand canonical array index test coverage

* Update admin.go

Co-authored-by: Matt Holt <mholt@users.noreply.github.com>

* Update admin.go

Co-authored-by: Matt Holt <mholt@users.noreply.github.com>

* admin: improve canonical array index test diagnostics

---------

Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
2026-04-30 09:39:57 -06:00
Amemoyoi 2d33271482
admin: require path segment boundary in remote access control (#7673) 2026-04-27 08:43:39 -06:00
Matthew Holt 48c08e3890
admin: Limit config size (by @omercnet)
GitHub was giving me errors related to merge status so we are doing this instead
2026-04-24 11:28:40 -06:00
Zen Dodd 4430756d5c
admin: Redact sensitive request headers in API logs (#7578)
* admin: Redact sensitive request headers in API logs

* Fix govulncheck and typed atomic lint failures

* Sync Go module metadata after dependency downgrade
2026-04-17 14:56:42 -06:00
Matthew Holt c35ba5588d
Add missing return to` handleError` in admin server
Thanks to @Wernerina's LLM for finding this bug
2026-03-25 16:33:24 -06:00
Francis Lavoie 6e5e08cf58
Wire up Cause for most context cancels (#7538) 2026-03-04 17:14:52 -07:00
Francis Lavoie 3adcafd4c1
admin: Fix tests locally, properly isolate storage (#7486)
* admin: Fix tests locally, properly isolate storage

* Fix flaky pki_test

* Drop testdata dir logic

* Safer temp dir

* Test handlers without a full server
2026-02-17 13:14:06 -07:00
Matthew Holt 72ac479f5d
admin: Enforce origin implicitly based on request headers 2026-02-11 09:52:56 -07:00
Matthew Holt 42ca010e9d
admin: Reject requests with Sec-Fetch-Mode headers
And buggy Origin: null headers.

Resolves a low-risk security report by @1seal.
2026-02-05 09:39:11 -07:00
Francis Lavoie d269405eab
core: Show JSON error offsets where possible (#7437) 2026-01-14 22:54:19 -05:00
Francis Lavoie 65e0ddc221
core: Reloading with `SIGUSR1` if config never changed via admin (#7258) 2025-09-26 16:50:15 +00:00
Ping Shuijie 6de2c9e135
chore: fix minor issue in comment (#7140)
Signed-off-by: pingshuijie <pingshuijie@outlook.com>
2025-07-22 11:27:36 +00:00
Jimmy Lipham 320c57291d
admin: Make sure that any admin routers are provisioned when local/re… (#6997)
* admin: Make sure that any admin routers are provisioned when local/remote admin servers are replaced at runtime.

* admin: check for provisioning errors during admin server replacements
2025-05-06 15:28:38 -06:00
Matthew Holt f297bc0a04
admin: Remove host checking for UDS (close #6832)
The consensus is that host enforcement on unix sockets is ineffective, frustrating, and confusing. (Unix sockets have their own OS-level permissions system.)
2025-04-15 14:20:22 -06:00
Mahdi Mohammadi 96c5c554c1
admin: fix index validation for PUT requests (#6824) 2025-02-04 08:57:32 -07:00
Matthew Holt 00f948c605
go.mod: Update dependencies 2024-11-04 14:53:10 -07:00
Mohammed Al Sahaf 41f5dd56e1
metrics: scope metrics to active config, add optional per-host metrics (#6531)
* Add per host config

* Pass host label when option is enabled

* Test per host enabled

* metrics: scope metrics per loaded config

* doc and linter

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* inject the custom registry into the admin handler

Co-Authored-By: Dave Henderson <dhenderson@gmail.com>

* remove `TODO` comment

* fixes

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

* refactor to delay metrics admin handler provision

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

---------

Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>
Co-authored-by: Hussam Almarzooq <me@hussam.io>
Co-authored-by: Dave Henderson <dhenderson@gmail.com>
2024-10-02 08:23:26 -06:00
Aaron Paterson 4b1a9b6cc1
core: Implement socket activation listeners (#6573)
* caddy adapt for listen_protocols

* adapt listen_socket

* allow multiple listen sockets for port ranges and readd socket fd listen logic

* readd logic to start servers according to listener protocols

* gofmt

* adapt caddytest

* gosec

* fmt and rename listen to listenWithSocket

* fmt and rename listen to listenWithSocket

* more consistent error msg

* non unix listenReusableWithSocketFile

* remove unused func

* doc comment typo

* nonosec

* commit

* doc comments

* more doc comments

* comment was misleading, cardinality did not change

* addressesWithProtocols

* update test

* fd/ and fdgram/

* rm addr

* actually write...

* i guess we doin' "skip": now

* wrong var in placeholder

* wrong var in placeholder II

* update param name in comment

* dont save nil file pointers

* windows

* key -> parsedKey

* osx

* multiple default_bind with protocols

* check for h1 and h2 listener netw
2024-09-30 10:55:03 -06:00
Francis Lavoie 2faeac0a10
chore: Use slices package where possible (#6585)
* chore: Use slices package where possible

* More, mostly using ContainsFunc

* Even more slice operations
2024-09-25 14:30:56 -06:00
coderwander eafc875ea9
chore: fix some typos in comments (#6243) 2024-04-16 04:10:11 +00:00
Matt Holt 81413caea2
caddytls: Upgrade ACMEz to v2; support ZeroSSL API; various fixes (#6229)
* WIP: acmez v2, CertMagic, and ZeroSSL issuer upgrades

* caddytls: ZeroSSLIssuer now uses ZeroSSL API instead of ACME

* Fix go.mod

* caddytls: Fix automation related to managers (fix #6060)

* Fix typo (appease linter)

* Fix HTTP validation with ZeroSSL API
2024-04-13 21:31:43 -04:00
Hayder 4a0492f3e1
admin: Make `Etag` a header, not a trailer (#6208)
* Making eTags a header not a trailer

* Checked the write

* Fixed typo

* Corrected comment

* Added sync Pool

* Changed control flow of buffer reset / putting and changed error code

* Switched from interface{} to any in bufferPool
2024-04-11 21:19:24 +00:00
Hayder 1217449609
admin: Use xxhash for etag (#6207) 2024-03-30 07:24:50 -06:00
Norman Soetbeer 0e204b730a
admin: Respond with 4xx on non-existing config path (#5870)
Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
2023-10-11 20:24:29 +00:00
Jacob Gadikian b32f265eca
ci: Use gofumpt to format code (#5707) 2023-08-07 19:40:31 +00:00
Matt Holt f66493efef
core: Allow loopback hosts for admin endpoint (fix #5650) (#5664) 2023-08-02 11:13:52 -06:00
Matt Holt b51dc5d5d0
core: Refine mutex during reloads (fix #5628) (#5645)
Separate currentCtxMu to protect currentCtx, and a new
rawCfgMu to protect rawCfg and synchronize loads.
2023-07-21 15:32:20 -06:00
Matt Holt 0e2c7e1d35
caddytls: Reuse certificate cache through reloads (#5623)
* caddytls: Don't purge cert cache on config reload

* Update CertMagic

This actually avoids reloading managed certs from storage
when already in the cache, d'oh.

* Fix bug; re-implement HasCertificateForSubject

* Update go.mod: CertMagic tag
2023-07-11 19:10:58 +00:00
Matthew Holt 12b2f22092
Add doc comment about changing admin endpoint 2023-05-09 20:05:27 -06:00
Francis Lavoie ac83b7e218
admin: Add `CADDY_ADMIN` env var to override the default (#5332) 2023-02-06 17:55:16 +00:00
bit 762b02789a
admin: set certmagic cache logger (#5173)
same way it is set in modules/caddytls/tls.go
2022-11-23 20:49:22 -07:00
bit ac96455a9a
admin: fix certificate renewal for admin (#5169)
certmagic.New takes a template and returns pointer to the new config.
GetConfigForCert later must return a pointer to the new config not the
template.

fixes #5162
2022-11-23 11:48:37 -07:00
Cory Cooper 037dc23cad
admin: Use replacer on listen addresses (#5071)
* admin: use replacer on listen address

* admin: consolidate replacer logic
2022-09-29 11:24:52 -06:00
Matt Holt e3e8aabbcf
core: Refactor and improve listener logic (#5089)
* core: Refactor, improve listener logic

Deprecate:
- caddy.Listen
- caddy.ListenTimeout
- caddy.ListenPacket

Prefer caddy.NetworkAddress.Listen() instead.

Change:
- caddy.ListenQUIC (hopefully to remove later)
- caddy.ListenerFunc signature (add context and ListenConfig)

- Don't emit Alt-Svc header advertising h3 over HTTP/3

- Use quic.ListenEarly instead of quic.ListenEarlyAddr; this gives us
more flexibility (e.g. possibility of HTTP/3 over UDS) but also
introduces a new issue:
https://github.com/lucas-clemente/quic-go/issues/3560#issuecomment-1258959608

- Unlink unix socket before and after use

* Appease the linter

* Keep ListenAll
2022-09-28 13:35:51 -06:00
Matthew Holt 59286d2c7e notify: Don't send ready after error (fix #5003)
Also simplify the notify package quite a bit.
Also move stop notification into better place.
Add ability to send status or error.
2022-09-02 09:24:05 -06:00
WeidiDeng 4c282e86da
admin: Don't stop old server if new one fails (#4964)
Fixes #4954

Co-authored-by: Matthew Holt <mholt@users.noreply.github.com>
2022-08-25 22:17:52 -06:00
Francis Lavoie 141872ed80
chore: Bump up to Go 1.19, minimum 1.18 (#4925) 2022-08-02 16:39:09 -04:00
Matt Holt f783290f40
caddyhttp: Implement `caddy respond` command (#4870) 2022-08-01 13:36:22 -06:00
jhwz ad3a83fb91
admin: expect quoted ETags (#4879)
* expect quoted etags

* admin: Minor refactor of etag facilities

Co-authored-by: Matthew Holt <mholt@users.noreply.github.com>
2022-07-12 12:23:55 -06:00
jhwz f259ed52bb
admin: support ETag on config endpoints (#4579)
* admin: support ETags

* support etags

Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
2022-07-06 13:50:07 -06:00
Matthew Holt d06d0e79f8
go.mod: Upgrade CertMagic to v0.16.0
Includes several breaking changes; code base updated accordingly.

- Added lots of context arguments
- Use fs.ErrNotExist
- Rename ACMEManager -> ACMEIssuer; CertificateManager -> Manager
2022-03-25 11:28:54 -06:00
Matthew Holt a72acd21b0
core: Retry dynamic config load if config unchanged
(see discussion in #4603)
2022-03-03 21:41:51 -07:00
Matthew Holt ceef70dbc5
core: Retry dynamic config load if error or no-op (#4603)
Also fix ineffectual assignment (unrelated)
2022-03-03 10:58:15 -07:00