diff options
author | Mike Crute <mike@crute.us> | 2023-11-12 11:09:11 -0800 |
---|---|---|
committer | Mike Crute <mike@crute.us> | 2023-11-12 11:09:11 -0800 |
commit | c9878e6aa081869ad5b711e15cb4cb561a44dab6 (patch) | |
tree | 2b57194887510a265005c84b135f90e79f7515da | |
parent | aaebdc0a79968e68ab24dc1a98fa45607d74f30c (diff) | |
download | golib-c9878e6aa081869ad5b711e15cb4cb561a44dab6.tar.bz2 golib-c9878e6aa081869ad5b711e15cb4cb561a44dab6.tar.xz golib-c9878e6aa081869ad5b711e15cb4cb561a44dab6.zip |
echo: protect profiles by IPecho/v0.16.3
-rw-r--r-- | echo/echo_default.go | 47 | ||||
-rw-r--r-- | echo/middleware/pprof.go | 51 |
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 | ||
165 | func (w *EchoWrapper) Configure(c EchoConfig) (err error) { | 166 | func (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 | ||
407 | func (w *EchoWrapper) configurePrometheus(c *EchoConfig) { | 408 | func (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 | ||
421 | func (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 | |||
435 | func (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 | ||
10 | func RegisterPprof(e *echo.Echo, prefixOptions ...string) { | 11 | type PprofConfig struct { |
11 | prefix := "/debug/pprof" | 12 | Skipper middleware.Skipper |
12 | if len(prefixOptions) > 0 { | 13 | Prefix string |
13 | prefix = prefixOptions[0] | 14 | } |
15 | |||
16 | var DefaultPprofConfig = PprofConfig{ | ||
17 | Skipper: middleware.DefaultSkipper, | ||
18 | Prefix: "/debug/pprof", | ||
19 | } | ||
20 | |||
21 | func RegisterPprof(e *echo.Echo) { | ||
22 | RegisterPprofWithConfig(e, DefaultPprofConfig) | ||
23 | } | ||
24 | |||
25 | func 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 | ||