fleet/server/service/debug_handler.go
Zach Wasserman 0bb9d69ece
Add debug endpoints and associated fleetctl commands (#45)
Adds endpoints and fleetctl commands to retrieve various debug profiles
from the Fleet server.

The best summary is from the help text:

```
fleetctl debug
NAME:
   fleetctl debug - Tools for debugging Fleet

USAGE:
   fleetctl debug command [command options] [arguments...]

COMMANDS:
   profile    Record a CPU profile from the Fleet server.
   cmdline    Get the command line used to invoke the Fleet server.
   heap       Report the allocated memory in the Fleet server.
   goroutine  Get stack traces of all goroutines (threads) in the Fleet server.
   trace      Record an execution trace on the Fleet server.
   archive    Create an archive with the entire suite of debug profiles.

OPTIONS:
   --config value   Path to the Fleet config file (default: "/Users/zwass/.fleet/config") [$CONFIG]
   --context value  Name of Fleet config context to use (default: "default") [$CONTEXT]
   --help, -h       show help
```
2020-11-17 17:12:37 -08:00

63 lines
1.7 KiB
Go

package service
import (
"context"
"net/http"
"net/http/pprof"
"github.com/fleetdm/fleet/server/config"
"github.com/fleetdm/fleet/server/contexts/token"
"github.com/fleetdm/fleet/server/kolide"
kitlog "github.com/go-kit/kit/log"
"github.com/gorilla/mux"
)
type debugAuthenticationMiddleware struct {
service kolide.Service
jwtKey string
}
// Authenticate the user and ensure the account is not disabled.
func (m *debugAuthenticationMiddleware) Middleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
bearer := token.FromHTTPRequest(r)
if bearer == "" {
http.Error(w, "Please authenticate", http.StatusUnauthorized)
return
}
ctx := token.NewContext(context.Background(), bearer)
v, err := authViewer(ctx, m.jwtKey, bearer, m.service)
if err != nil {
http.Error(w, "Invalid authentication", http.StatusUnauthorized)
return
}
if !v.CanPerformActions() {
http.Error(w, "Unauthorized", http.StatusForbidden)
return
}
next.ServeHTTP(w, r)
})
}
// MakeDebugHandler creates an HTTP handler for the Fleet debug endpoints.
func MakeDebugHandler(svc kolide.Service, config config.KolideConfig, logger kitlog.Logger) http.Handler {
r := mux.NewRouter()
r.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
r.HandleFunc("/debug/pprof/profile", pprof.Profile)
r.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
r.HandleFunc("/debug/pprof/trace", pprof.Trace)
r.PathPrefix("/debug/pprof/").HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
pprof.Index(rw, req)
})
mw := &debugAuthenticationMiddleware{
service: svc,
jwtKey: config.Auth.JwtKey,
}
r.Use(mw.Middleware)
return r
}