diff --git a/internal/outpost/flow.go b/internal/outpost/flow.go index 830a6ed62..f19d22b0a 100644 --- a/internal/outpost/flow.go +++ b/internal/outpost/flow.go @@ -60,6 +60,7 @@ type FlowExecutor struct { func NewFlowExecutor(ctx context.Context, flowSlug string, refConfig *api.Configuration, logFields log.Fields) *FlowExecutor { rsp := sentry.StartSpan(ctx, "authentik.outposts.flow_executor") + rsp.Description = flowSlug l := log.WithField("flow", flowSlug).WithFields(logFields) jar, err := cookiejar.New(nil) @@ -153,8 +154,8 @@ func (fe *FlowExecutor) solveFlowChallenge(depth int) (bool, error) { } ch := challenge.GetActualInstance().(ChallengeInt) fe.log.WithField("component", ch.GetComponent()).WithField("type", ch.GetType()).Debug("Got challenge") - gcsp.SetTag("ak_challenge", string(ch.GetType())) - gcsp.SetTag("ak_component", ch.GetComponent()) + gcsp.SetTag("authentik.flow.challenge", string(ch.GetType())) + gcsp.SetTag("authentik.flow.component", ch.GetComponent()) gcsp.Finish() FlowTimingGet.With(prometheus.Labels{ "stage": ch.GetComponent(), @@ -202,8 +203,8 @@ func (fe *FlowExecutor) solveFlowChallenge(depth int) (bool, error) { response, _, err := responseReq.Execute() ch = response.GetActualInstance().(ChallengeInt) fe.log.WithField("component", ch.GetComponent()).WithField("type", ch.GetType()).Debug("Got response") - scsp.SetTag("ak_challenge", string(ch.GetType())) - scsp.SetTag("ak_component", ch.GetComponent()) + scsp.SetTag("authentik.flow.challenge", string(ch.GetType())) + scsp.SetTag("authentik.flow.component", ch.GetComponent()) scsp.Finish() switch ch.GetComponent() { diff --git a/internal/outpost/ldap/bind/request.go b/internal/outpost/ldap/bind/request.go index 43d379282..e91c2e70f 100644 --- a/internal/outpost/ldap/bind/request.go +++ b/internal/outpost/ldap/bind/request.go @@ -23,9 +23,14 @@ type Request struct { func NewRequest(bindDN string, bindPW string, conn net.Conn) (*Request, *sentry.Span) { span := sentry.StartSpan(context.TODO(), "authentik.providers.ldap.bind", sentry.TransactionName("authentik.providers.ldap.bind")) + span.Description = bindDN rid := uuid.New().String() span.SetTag("request_uid", rid) - span.SetTag("user.username", bindDN) + sentry.GetHubFromContext(span.Context()).Scope().SetUser(sentry.User{ + Username: bindDN, + ID: bindDN, + IPAddress: utils.GetIP(conn.RemoteAddr()), + }) bindDN = strings.ToLower(bindDN) return &Request{ diff --git a/internal/outpost/ldap/search/request.go b/internal/outpost/ldap/search/request.go index 183dba226..31c9fde42 100644 --- a/internal/outpost/ldap/search/request.go +++ b/internal/outpost/ldap/search/request.go @@ -2,6 +2,7 @@ package search import ( "context" + "fmt" "net" "strings" @@ -27,10 +28,15 @@ func NewRequest(bindDN string, searchReq ldap.SearchRequest, conn net.Conn) (*Re bindDN = strings.ToLower(bindDN) searchReq.BaseDN = strings.ToLower(searchReq.BaseDN) span := sentry.StartSpan(context.TODO(), "authentik.providers.ldap.search", sentry.TransactionName("authentik.providers.ldap.search")) + span.Description = fmt.Sprintf("%s (%s)", searchReq.BaseDN, ldap.ScopeMap[searchReq.Scope]) span.SetTag("request_uid", rid) - span.SetTag("user.username", bindDN) - span.SetTag("ak_filter", searchReq.Filter) - span.SetTag("ak_base_dn", searchReq.BaseDN) + sentry.GetHubFromContext(span.Context()).Scope().SetUser(sentry.User{ + Username: bindDN, + ID: bindDN, + IPAddress: utils.GetIP(conn.RemoteAddr()), + }) + span.SetTag("ldap_filter", searchReq.Filter) + span.SetTag("ldap_base_dn", searchReq.BaseDN) return &Request{ SearchRequest: searchReq, BindDN: bindDN, diff --git a/internal/outpost/proxyv2/application/application.go b/internal/outpost/proxyv2/application/application.go index b500a5773..c048bbd55 100644 --- a/internal/outpost/proxyv2/application/application.go +++ b/internal/outpost/proxyv2/application/application.go @@ -12,6 +12,8 @@ import ( "time" "github.com/coreos/go-oidc" + "github.com/getsentry/sentry-go" + sentryhttp "github.com/getsentry/sentry-go/http" "github.com/gorilla/mux" "github.com/gorilla/sessions" "github.com/pkg/errors" @@ -109,6 +111,11 @@ func NewApplication(p api.ProxyOutpostConfig, c *http.Client, cs *ak.CryptoStore user := "" if c != nil { user = c.PreferredUsername + sentry.GetHubFromContext(r.Context()).Scope().SetUser(sentry.User{ + Username: user, + ID: c.Sub, + IPAddress: r.RemoteAddr, + }) } before := time.Now() inner.ServeHTTP(rw, r) @@ -124,6 +131,7 @@ func NewApplication(p api.ProxyOutpostConfig, c *http.Client, cs *ak.CryptoStore }).Observe(float64(after)) }) }) + mux.Use(sentryhttp.New(sentryhttp.Options{}).Handle) // Support /start and /sign_in for backwards compatibility mux.HandleFunc("/akprox/start", a.handleRedirect) diff --git a/internal/outpost/proxyv2/proxyv2.go b/internal/outpost/proxyv2/proxyv2.go index f6cd68ff1..dbf481801 100644 --- a/internal/outpost/proxyv2/proxyv2.go +++ b/internal/outpost/proxyv2/proxyv2.go @@ -10,6 +10,7 @@ import ( "sync" "time" + sentryhttp "github.com/getsentry/sentry-go/http" "github.com/gorilla/mux" "github.com/pires/go-proxyproto" log "github.com/sirupsen/logrus" @@ -52,6 +53,7 @@ func NewProxyServer(ac *ak.APIController, portOffset int) *ProxyServer { globalMux := rootMux.NewRoute().Subrouter() globalMux.Use(web.NewLoggingHandler(l.WithField("logger", "authentik.outpost.proxyv2.http"), nil)) + globalMux.Use(sentryhttp.New(sentryhttp.Options{}).Handle) s := &ProxyServer{ Listen: "0.0.0.0:%d", PortOffset: portOffset, diff --git a/internal/utils/web/middleware.go b/internal/utils/web/middleware.go index 0c5f94f82..2b66e0d05 100644 --- a/internal/utils/web/middleware.go +++ b/internal/utils/web/middleware.go @@ -99,8 +99,8 @@ func (h loggingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { h.handler.ServeHTTP(responseLogger, req) duration := float64(time.Since(t)) / float64(time.Millisecond) h.afterHandler(h.logger.WithFields(log.Fields{ - "host": req.RemoteAddr, - "vhost": GetHost(req), + "remote": req.RemoteAddr, + "host": GetHost(req), "request_protocol": req.Proto, "runtime": fmt.Sprintf("%0.3f", duration), "method": req.Method, diff --git a/internal/web/middleware_log.go b/internal/web/middleware_log.go deleted file mode 100644 index 246bbf452..000000000 --- a/internal/web/middleware_log.go +++ /dev/null @@ -1,29 +0,0 @@ -package web - -import ( - "net/http" - "time" - - "github.com/getsentry/sentry-go" - log "github.com/sirupsen/logrus" - "goauthentik.io/internal/utils/web" -) - -func loggingMiddleware(l *log.Entry) func(next http.Handler) http.Handler { - return func(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - span := sentry.StartSpan(r.Context(), "authentik.go.request") - before := time.Now() - // Call the next handler, which can be another middleware in the chain, or the final handler. - next.ServeHTTP(w, r) - after := time.Now() - l.WithFields(log.Fields{ - "remote": r.RemoteAddr, - "method": r.Method, - "took": after.Sub(before), - "host": web.GetHost(r), - }).Info(r.RequestURI) - span.Finish() - }) - } -} diff --git a/internal/web/middleware_sentry.go b/internal/web/middleware_sentry.go deleted file mode 100644 index 88329e66c..000000000 --- a/internal/web/middleware_sentry.go +++ /dev/null @@ -1,44 +0,0 @@ -package web - -import ( - "encoding/json" - "net/http" - - sentryhttp "github.com/getsentry/sentry-go/http" - log "github.com/sirupsen/logrus" -) - -func recoveryMiddleware() func(next http.Handler) http.Handler { - sentryHandler := sentryhttp.New(sentryhttp.Options{}) - l := log.WithField("logger", "authentik.router.sentry") - return func(next http.Handler) http.Handler { - sentryHandler.Handle(next) - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - next.ServeHTTP(w, r) - defer func() { - re := recover() - if re == nil { - return - } - err := re.(error) - if err != nil { - l.WithError(err).Warning("global panic handler") - jsonBody, _ := json.Marshal(struct { - Successful bool - Error string - }{ - Successful: false, - Error: err.Error(), - }) - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusInternalServerError) - _, err := w.Write(jsonBody) - if err != nil { - l.WithError(err).Warning("Failed to write sentry error body") - } - } - }() - }) - } -} diff --git a/internal/web/web.go b/internal/web/web.go index 4096f91dc..5ddd21f72 100644 --- a/internal/web/web.go +++ b/internal/web/web.go @@ -6,6 +6,7 @@ import ( "net" "net/http" + sentryhttp "github.com/getsentry/sentry-go/http" "github.com/gorilla/handlers" "github.com/gorilla/mux" "github.com/pires/go-proxyproto" @@ -13,6 +14,7 @@ import ( "goauthentik.io/internal/config" "goauthentik.io/internal/gounicorn" "goauthentik.io/internal/outpost/proxyv2" + "goauthentik.io/internal/utils/web" ) type WebServer struct { @@ -34,13 +36,11 @@ type WebServer struct { func NewWebServer(g *gounicorn.GoUnicorn) *WebServer { l := log.WithField("logger", "authentik.router") mainHandler := mux.NewRouter() - if config.G.ErrorReporting.Enabled { - mainHandler.Use(recoveryMiddleware()) - } + mainHandler.Use(sentryhttp.New(sentryhttp.Options{}).Handle) mainHandler.Use(handlers.ProxyHeaders) mainHandler.Use(handlers.CompressHandler) logginRouter := mainHandler.NewRoute().Subrouter() - logginRouter.Use(loggingMiddleware(l)) + logginRouter.Use(web.NewLoggingHandler(l, nil)) ws := &WebServer{ LegacyProxy: true, @@ -72,7 +72,7 @@ func (ws *WebServer) Shutdown() { func (ws *WebServer) listenPlain() { ln, err := net.Listen("tcp", config.G.Web.Listen) if err != nil { - ws.log.WithError(err).Fatalf("failed to listen") + ws.log.WithError(err).Fatal("failed to listen") } ws.log.WithField("listen", config.G.Web.Listen).Info("Listening") @@ -83,7 +83,7 @@ func (ws *WebServer) listenPlain() { err = http.ListenAndServe(config.G.Web.Listen, ws.m) if err != nil && !errors.Is(err, http.ErrServerClosed) { - ws.log.Errorf("ERROR: http.Serve() - %s", err) + ws.log.WithError(err).Error("failed to listen") } } @@ -100,14 +100,14 @@ func (ws *WebServer) serve(listener net.Listener) { // We received an interrupt signal, shut down. if err := srv.Shutdown(context.Background()); err != nil { // Error from closing listeners, or context timeout: - ws.log.Printf("HTTP server Shutdown: %v", err) + ws.log.WithError(err).Warning("HTTP server Shutdown") } close(idleConnsClosed) }() err := srv.Serve(listener) if err != nil && !errors.Is(err, http.ErrServerClosed) { - ws.log.Errorf("ERROR: http.Serve() - %s", err) + ws.log.WithError(err).Error("ERROR: http.Serve()") } <-idleConnsClosed }