From 06ff6b50edecfa3373030a3e8999c26f57dcddd4 Mon Sep 17 00:00:00 2001 From: Thomas Boerger Date: Wed, 21 Mar 2018 13:51:54 +0100 Subject: [PATCH] Use specific token for prometheus metrics --- cmd/drone-server/server.go | 9 +++++++++ router/router.go | 5 +---- server/metrics/prometheus.go | 35 +++++++++++++++++++++++++++++++++-- server/rpc.go | 3 +++ 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/cmd/drone-server/server.go b/cmd/drone-server/server.go index 296ba2976..597f81478 100644 --- a/cmd/drone-server/server.go +++ b/cmd/drone-server/server.go @@ -169,6 +169,12 @@ var flags = []cli.Flag{ Usage: "database driver configuration string", Value: "drone.sqlite", }, + cli.StringFlag{ + EnvVar: "DRONE_PROMETHEUS_AUTH_TOKEN", + Name: "prometheus-auth-token", + Usage: "token to secure prometheus metrics endpoint", + Value: "", + }, // // resource limit parameters // @@ -685,6 +691,9 @@ func setupEvilGlobals(c *cli.Context, v store.Store, r remote.Remote) { // droneserver.Config.Server.Open = cli.Bool("open") // droneserver.Config.Server.Orgs = sliceToMap(cli.StringSlice("orgs")) // droneserver.Config.Server.Admins = sliceToMap(cli.StringSlice("admin")) + + // prometheus + droneserver.Config.Prometheus.AuthToken = c.String("prometheus-auth-token") } type authorizer struct { diff --git a/router/router.go b/router/router.go index b3677aa1b..b0619c080 100644 --- a/router/router.go +++ b/router/router.go @@ -178,10 +178,7 @@ func Load(mux *httptreemux.ContextMux, middleware ...gin.HandlerFunc) http.Handl monitor := e.Group("/metrics") { - monitor.GET("", - session.MustAdmin(), - metrics.PromHandler(), - ) + monitor.GET("", metrics.PromHandler()) } e.GET("/version", server.Version) diff --git a/server/metrics/prometheus.go b/server/metrics/prometheus.go index 3d0bd6a60..d7e7c9ab9 100644 --- a/server/metrics/prometheus.go +++ b/server/metrics/prometheus.go @@ -15,14 +15,45 @@ package metrics import ( - "github.com/gin-gonic/gin" + "errors" + "fmt" + "github.com/drone/drone/server" + "github.com/gin-gonic/gin" "github.com/prometheus/client_golang/prometheus/promhttp" ) +var ( + // errInvalidToken is returned when the api request token is invalid. + errInvalidToken = errors.New("Invalid or missing token") +) + // PromHandler will pass the call from /api/metrics/prometheus to prometheus func PromHandler() gin.HandlerFunc { + handler := promhttp.Handler() + return func(c *gin.Context) { - promhttp.Handler().ServeHTTP(c.Writer, c.Request) + token := server.Config.Prometheus.Token + + if token == "" { + handler.ServeHTTP(c.Writer, c.Request) + return + } + + header := c.Request.Header.Get("Authorization") + + if header == "" { + c.String(401, errInvalidToken.Error()) + return + } + + bearer := fmt.Sprintf("Bearer %s", token) + + if header != bearer { + c.String(401, errInvalidToken.Error()) + return + } + + handler.ServeHTTP(c.Writer, c.Request) } } diff --git a/server/rpc.go b/server/rpc.go index 7c064544e..0bdec222b 100644 --- a/server/rpc.go +++ b/server/rpc.go @@ -80,6 +80,9 @@ var Config = struct { // Orgs map[string]struct{} // Admins map[string]struct{} } + Prometheus struct { + AuthToken string + } Pipeline struct { Limits model.ResourceLimit Volumes []string