aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Crute <mike@crute.us>2023-11-12 11:09:11 -0800
committerMike Crute <mike@crute.us>2023-11-12 11:09:11 -0800
commitc9878e6aa081869ad5b711e15cb4cb561a44dab6 (patch)
tree2b57194887510a265005c84b135f90e79f7515da
parentaaebdc0a79968e68ab24dc1a98fa45607d74f30c (diff)
downloadgolib-c9878e6aa081869ad5b711e15cb4cb561a44dab6.tar.bz2
golib-c9878e6aa081869ad5b711e15cb4cb561a44dab6.tar.xz
golib-c9878e6aa081869ad5b711e15cb4cb561a44dab6.zip
echo: protect profiles by IPecho/v0.16.3
-rw-r--r--echo/echo_default.go47
-rw-r--r--echo/middleware/pprof.go51
2 files changed, 64 insertions, 34 deletions
diff --git a/echo/echo_default.go b/echo/echo_default.go
index dadeb90..5cd4b75 100644
--- a/echo/echo_default.go
+++ b/echo/echo_default.go
@@ -82,6 +82,7 @@ type EchoWrapper struct {
82 autocert autocert.PrimingCertProvider 82 autocert autocert.PrimingCertProvider
83 templateFS fs.FS 83 templateFS fs.FS
84 errorHandler ErrorHandler 84 errorHandler ErrorHandler
85 netboxIpFilter *glmw.NetboxIPFilter
85} 86}
86 87
87// NewEchoWrapper creates a new instance of Echo and wraps it in an 88// NewEchoWrapper creates a new instance of Echo and wraps it in an
@@ -163,10 +164,6 @@ func (w *EchoWrapper) AddErrorHandler(h ContentErrorHandler, mime ...string) {
163} 164}
164 165
165func (w *EchoWrapper) Configure(c EchoConfig) (err error) { 166func (w *EchoWrapper) Configure(c EchoConfig) (err error) {
166 if w.Debug || c.EnableTrace {
167 glmw.RegisterPprof(w.Echo)
168 }
169
170 w.configureAutocert(&c) 167 w.configureAutocert(&c)
171 168
172 if err := w.configureIpExtractor(&c); err != nil { 169 if err := w.configureIpExtractor(&c); err != nil {
@@ -197,7 +194,11 @@ func (w *EchoWrapper) Configure(c EchoConfig) (err error) {
197 w.configureCORS(&c) 194 w.configureCORS(&c)
198 w.configureCSP(&c) 195 w.configureCSP(&c)
199 w.configureServerHeader(&c) 196 w.configureServerHeader(&c)
197
198 // These all depend on w.netboxIpFilter
199 w.configureNetboxIpFilter(&c)
200 w.configurePrometheus(&c) 200 w.configurePrometheus(&c)
201 w.configurePprof(&c)
201 202
202 return nil 203 return nil
203} 204}
@@ -404,19 +405,21 @@ func (w *EchoWrapper) configureServerHeader(c *EchoConfig) {
404 } 405 }
405} 406}
406 407
407func (w *EchoWrapper) configurePrometheus(c *EchoConfig) { 408func (w *EchoWrapper) configureNetboxIpFilter(c *EchoConfig) {
408 if !c.DisablePrometheus && c.NetboxClient != nil { 409 // TODO: Should constrain this by site probably but monitoring happens
409 // TODO: Should constrain this by site probably but monitoring happens 410 // across sites so those prefixes need to be included
410 // across sites so those prefixes need to be included 411 w.netboxIpFilter = &glmw.NetboxIPFilter{
411 f := &glmw.NetboxIPFilter{ 412 NetboxClient: c.NetboxClient,
412 NetboxClient: c.NetboxClient, 413 Tag: "management",
413 Tag: "management", 414 IncludeLocalhost: true,
414 IncludeLocalhost: true, 415 Logger: w.Logger,
415 Logger: w.Logger, 416 }
416 } 417 w.runner.AddInitJob(w.netboxIpFilter.Init)
417 w.runner.AddInitJob(f.Init) 418 w.runner.AddJob(w.netboxIpFilter.RunRefresh)
418 w.runner.AddJob(f.RunRefresh) 419}
419 420
421func (w *EchoWrapper) configurePrometheus(c *EchoConfig) {
422 if !c.DisablePrometheus && w.netboxIpFilter != nil {
420 var prom *prometheus.Prometheus 423 var prom *prometheus.Prometheus
421 if c.PrometheusConfig != nil { 424 if c.PrometheusConfig != nil {
422 prom = prometheus.NewPrometheusWithConfig(c.PrometheusConfig) 425 prom = prometheus.NewPrometheusWithConfig(c.PrometheusConfig)
@@ -425,6 +428,16 @@ func (w *EchoWrapper) configurePrometheus(c *EchoConfig) {
425 } 428 }
426 429
427 w.Use(prom.MiddlewareHandler) 430 w.Use(prom.MiddlewareHandler)
428 w.GET(prom.Config.MetricsPath, prom.MetricsHandler, f.Middleware) 431 w.GET(prom.Config.MetricsPath, prom.MetricsHandler, w.netboxIpFilter.Middleware)
432 }
433}
434
435func (w *EchoWrapper) configurePprof(c *EchoConfig) {
436 if (w.Debug || c.EnableTrace) && w.netboxIpFilter != nil {
437 glmw.RegisterPprofWithConfig(
438 w.Echo,
439 glmw.DefaultPprofConfig,
440 w.netboxIpFilter.Middleware,
441 )
429 } 442 }
430} 443}
diff --git a/echo/middleware/pprof.go b/echo/middleware/pprof.go
index cc69505..8c7fe1b 100644
--- a/echo/middleware/pprof.go
+++ b/echo/middleware/pprof.go
@@ -5,28 +5,45 @@ import (
5 "net/http/pprof" 5 "net/http/pprof"
6 6
7 "github.com/labstack/echo/v4" 7 "github.com/labstack/echo/v4"
8 "github.com/labstack/echo/v4/middleware"
8) 9)
9 10
10func RegisterPprof(e *echo.Echo, prefixOptions ...string) { 11type PprofConfig struct {
11 prefix := "/debug/pprof" 12 Skipper middleware.Skipper
12 if len(prefixOptions) > 0 { 13 Prefix string
13 prefix = prefixOptions[0] 14}
15
16var DefaultPprofConfig = PprofConfig{
17 Skipper: middleware.DefaultSkipper,
18 Prefix: "/debug/pprof",
19}
20
21func RegisterPprof(e *echo.Echo) {
22 RegisterPprofWithConfig(e, DefaultPprofConfig)
23}
24
25func RegisterPprofWithConfig(e *echo.Echo, config PprofConfig, mw ...echo.MiddlewareFunc) {
26 if config.Skipper == nil {
27 config.Skipper = DefaultPprofConfig.Skipper
28 }
29 if config.Prefix == "" {
30 config.Prefix = DefaultPprofConfig.Prefix
14 } 31 }
15 32
16 prefixRouter := e.Group(prefix) 33 g := e.Group(config.Prefix)
17 { 34 {
18 prefixRouter.GET("/", pprofAdapter(pprof.Index)) 35 g.GET("/", pprofAdapter(pprof.Index), mw...)
19 prefixRouter.GET("/allocs", pprofAdapter(pprof.Handler("allocs").ServeHTTP)) 36 g.GET("/allocs", pprofAdapter(pprof.Handler("allocs").ServeHTTP), mw...)
20 prefixRouter.GET("/block", pprofAdapter(pprof.Handler("block").ServeHTTP)) 37 g.GET("/block", pprofAdapter(pprof.Handler("block").ServeHTTP), mw...)
21 prefixRouter.GET("/cmdline", pprofAdapter(pprof.Cmdline)) 38 g.GET("/cmdline", pprofAdapter(pprof.Cmdline), mw...)
22 prefixRouter.GET("/goroutine", pprofAdapter(pprof.Handler("goroutine").ServeHTTP)) 39 g.GET("/goroutine", pprofAdapter(pprof.Handler("goroutine").ServeHTTP), mw...)
23 prefixRouter.GET("/heap", pprofAdapter(pprof.Handler("heap").ServeHTTP)) 40 g.GET("/heap", pprofAdapter(pprof.Handler("heap").ServeHTTP), mw...)
24 prefixRouter.GET("/mutex", pprofAdapter(pprof.Handler("mutex").ServeHTTP)) 41 g.GET("/mutex", pprofAdapter(pprof.Handler("mutex").ServeHTTP), mw...)
25 prefixRouter.GET("/profile", pprofAdapter(pprof.Profile)) 42 g.GET("/profile", pprofAdapter(pprof.Profile), mw...)
26 prefixRouter.POST("/symbol", pprofAdapter(pprof.Symbol)) 43 g.POST("/symbol", pprofAdapter(pprof.Symbol), mw...)
27 prefixRouter.GET("/symbol", pprofAdapter(pprof.Symbol)) 44 g.GET("/symbol", pprofAdapter(pprof.Symbol), mw...)
28 prefixRouter.GET("/threadcreate", pprofAdapter(pprof.Handler("threadcreate").ServeHTTP)) 45 g.GET("/threadcreate", pprofAdapter(pprof.Handler("threadcreate").ServeHTTP), mw...)
29 prefixRouter.GET("/trace", pprofAdapter(pprof.Trace)) 46 g.GET("/trace", pprofAdapter(pprof.Trace), mw...)
30 } 47 }
31} 48}
32 49