From 12b2f22092b4c4efaa9cb5a42870b0d21796f9c1 Mon Sep 17 00:00:00 2001 From: Matthew Holt Date: Tue, 9 May 2023 20:05:27 -0600 Subject: Add doc comment about changing admin endpoint --- admin.go | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'admin.go') diff --git a/admin.go b/admin.go index 674d06a..59b3dcd 100644 --- a/admin.go +++ b/admin.go @@ -71,6 +71,11 @@ type AdminConfig struct { // parsed by Caddy. Accepts placeholders. // Default: the value of the `CADDY_ADMIN` environment variable, // or `localhost:2019` otherwise. + // + // Remember: When changing this value through a config reload, + // be sure to use the `--address` CLI flag to specify the current + // admin address if the currently-running admin endpoint is not + // the default address. Listen string `json:"listen,omitempty"` // If true, CORS headers will be emitted, and requests to the -- cgit v1.2.3 From 0e2c7e1d35b287fc0e56d6db2951f791e09b5a37 Mon Sep 17 00:00:00 2001 From: Matt Holt Date: Tue, 11 Jul 2023 13:10:58 -0600 Subject: 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 --- admin.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'admin.go') diff --git a/admin.go b/admin.go index 59b3dcd..3ea5051 100644 --- a/admin.go +++ b/admin.go @@ -1018,7 +1018,7 @@ func handleConfigID(w http.ResponseWriter, r *http.Request) error { // map the ID to the expanded path currentCtxMu.RLock() expanded, ok := rawCfgIndex[id] - defer currentCtxMu.RUnlock() + currentCtxMu.RUnlock() if !ok { return APIError{ HTTPStatus: http.StatusNotFound, -- cgit v1.2.3 From b51dc5d5d0b8764165170af1f54b77d6de8cb5a1 Mon Sep 17 00:00:00 2001 From: Matt Holt Date: Fri, 21 Jul 2023 15:32:20 -0600 Subject: core: Refine mutex during reloads (fix #5628) (#5645) Separate currentCtxMu to protect currentCtx, and a new rawCfgMu to protect rawCfg and synchronize loads. --- admin.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'admin.go') diff --git a/admin.go b/admin.go index 3ea5051..4a1d23b 100644 --- a/admin.go +++ b/admin.go @@ -1016,9 +1016,9 @@ func handleConfigID(w http.ResponseWriter, r *http.Request) error { id := parts[2] // map the ID to the expanded path - currentCtxMu.RLock() + rawCfgMu.RLock() expanded, ok := rawCfgIndex[id] - currentCtxMu.RUnlock() + rawCfgMu.RUnlock() if !ok { return APIError{ HTTPStatus: http.StatusNotFound, -- cgit v1.2.3 From f66493efef4d909fdeb68a2ce8131d58e17333b3 Mon Sep 17 00:00:00 2001 From: Matt Holt Date: Wed, 2 Aug 2023 11:13:52 -0600 Subject: core: Allow loopback hosts for admin endpoint (fix #5650) (#5664) --- admin.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'admin.go') diff --git a/admin.go b/admin.go index 4a1d23b..1966556 100644 --- a/admin.go +++ b/admin.go @@ -318,7 +318,32 @@ func (admin AdminConfig) allowedOrigins(addr NetworkAddress) []*url.URL { // messages. If the requested URI does not include an Internet host // name for the service being requested, then the Host header field MUST // be given with an empty value." + // + // UPDATE July 2023: Go broke this by patching a minor security bug in 1.20.6. + // Understandable, but frustrating. See: + // https://github.com/golang/go/issues/60374 + // See also the discussion here: + // https://github.com/golang/go/issues/61431 + // + // We can no longer conform to RFC 2616 Section 14.26 from either Go or curl + // in purity. (Curl allowed no host between 7.40 and 7.50, but now requires a + // bogus host; see https://superuser.com/a/925610.) If we disable Host/Origin + // security checks, the infosec community assures me that it is secure to do + // so, because: + // 1) Browsers do not allow access to unix sockets + // 2) DNS is irrelevant to unix sockets + // + // I am not quite ready to trust either of those external factors, so instead + // of disabling Host/Origin checks, we now allow specific Host values when + // accessing the admin endpoint over unix sockets. I definitely don't trust + // DNS (e.g. I don't trust 'localhost' to always resolve to the local host), + // and IP shouldn't even be used, but if it is for some reason, I think we can + // at least be reasonably assured that 127.0.0.1 and ::1 route to the local + // machine, meaning that a hypothetical browser origin would have to be on the + // local machine as well. uniqueOrigins[""] = struct{}{} + uniqueOrigins["127.0.0.1"] = struct{}{} + uniqueOrigins["::1"] = struct{}{} } else { uniqueOrigins[net.JoinHostPort("localhost", addr.port())] = struct{}{} uniqueOrigins[net.JoinHostPort("::1", addr.port())] = struct{}{} -- cgit v1.2.3 From b32f265ecad60404c3818cc9d42e367a8e4eb7d4 Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Tue, 8 Aug 2023 03:40:31 +0800 Subject: ci: Use gofumpt to format code (#5707) --- admin.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'admin.go') diff --git a/admin.go b/admin.go index 1966556..335b8e8 100644 --- a/admin.go +++ b/admin.go @@ -1346,7 +1346,7 @@ var ( // will get deleted before the process gracefully exits. func PIDFile(filename string) error { pid := []byte(strconv.Itoa(os.Getpid()) + "\n") - err := os.WriteFile(filename, pid, 0600) + err := os.WriteFile(filename, pid, 0o600) if err != nil { return err } -- cgit v1.2.3 From 0e204b730aa2b1fa0835336b1117eff8c420f713 Mon Sep 17 00:00:00 2001 From: Norman Soetbeer Date: Wed, 11 Oct 2023 22:24:29 +0200 Subject: admin: Respond with 4xx on non-existing config path (#5870) Co-authored-by: Matt Holt --- admin.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'admin.go') diff --git a/admin.go b/admin.go index 335b8e8..0a9bfc4 100644 --- a/admin.go +++ b/admin.go @@ -1196,15 +1196,27 @@ traverseLoop: } case http.MethodPut: if _, ok := v[part]; ok { - return fmt.Errorf("[%s] key already exists: %s", path, part) + return APIError{ + HTTPStatus: http.StatusConflict, + Err: fmt.Errorf("[%s] key already exists: %s", path, part), + } } v[part] = val case http.MethodPatch: if _, ok := v[part]; !ok { - return fmt.Errorf("[%s] key does not exist: %s", path, part) + return APIError{ + HTTPStatus: http.StatusNotFound, + Err: fmt.Errorf("[%s] key does not exist: %s", path, part), + } } v[part] = val case http.MethodDelete: + if _, ok := v[part]; !ok { + return APIError{ + HTTPStatus: http.StatusNotFound, + Err: fmt.Errorf("[%s] key does not exist: %s", path, part), + } + } delete(v, part) default: return fmt.Errorf("unrecognized method %s", method) -- cgit v1.2.3