Browse Source

feat(api, gui): allow authentication bypass for metrics (#10045)

### Purpose

Give the ability to skip authentication for prometheus metrics
("/metrics").

### Testing

When authentication is enabled and "Metrics Without Auth" is checked
(not the default), the "/metrics" path remains accessible even when
disconnected.

### Screenshots


![image](https://github.com/user-attachments/assets/144b696b-dd72-46f4-94d5-cd21848e4a4c)

### Documentation

https://github.com/syncthing/docs/pull/906
Sébastien WENSKE 6 months ago
parent
commit
ab5c42f4a0
3 changed files with 8 additions and 3 deletions
  1. 6 2
      lib/api/api_auth.go
  2. 1 1
      lib/api/api_csrf.go
  3. 1 0
      lib/config/guiconfiguration.go

+ 6 - 2
lib/api/api_auth.go

@@ -51,7 +51,7 @@ func forbidden(w http.ResponseWriter) {
 	http.Error(w, "Forbidden", http.StatusForbidden)
 }
 
-func isNoAuthPath(path string) bool {
+func isNoAuthPath(path string, metricsWithoutAuth bool) bool {
 	// Local variable instead of module var to prevent accidental mutation
 	noAuthPaths := []string{
 		"/",
@@ -60,6 +60,10 @@ func isNoAuthPath(path string) bool {
 		"/rest/svc/lang", // Required to load language settings on login page
 	}
 
+	if metricsWithoutAuth {
+		noAuthPaths = append(noAuthPaths, "/metrics")
+	}
+
 	// Local variable instead of module var to prevent accidental mutation
 	noAuthPrefixes := []string{
 		// Static assets
@@ -115,7 +119,7 @@ func (m *basicAuthAndSessionMiddleware) ServeHTTP(w http.ResponseWriter, r *http
 	}
 
 	// Exception for static assets and REST calls that don't require authentication.
-	if isNoAuthPath(r.URL.Path) {
+	if isNoAuthPath(r.URL.Path, m.guiCfg.MetricsWithoutAuth) {
 		m.next.ServeHTTP(w, r)
 		return
 	}

+ 1 - 1
lib/api/api_csrf.go

@@ -78,7 +78,7 @@ func (m *csrfManager) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 
-	if isNoAuthPath(r.URL.Path) {
+	if isNoAuthPath(r.URL.Path, false) {
 		// REST calls that don't require authentication also do not
 		// need a CSRF token.
 		m.next.ServeHTTP(w, r)

+ 1 - 0
lib/config/guiconfiguration.go

@@ -25,6 +25,7 @@ type GUIConfiguration struct {
 	User                      string   `json:"user" xml:"user,omitempty"`
 	Password                  string   `json:"password" xml:"password,omitempty"`
 	AuthMode                  AuthMode `json:"authMode" xml:"authMode,omitempty"`
+	MetricsWithoutAuth        bool     `json:"metricsWithoutAuth" xml:"metricsWithoutAuth" default:"false"`
 	RawUseTLS                 bool     `json:"useTLS" xml:"tls,attr"`
 	APIKey                    string   `json:"apiKey" xml:"apikey,omitempty"`
 	InsecureAdminAccess       bool     `json:"insecureAdminAccess" xml:"insecureAdminAccess,omitempty"`