internal: cleanup duplicate and redundant code, properly set sentry SDK scope settings

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-12-16 11:00:19 +01:00
parent 5123bc1316
commit f8aab40e3e
9 changed files with 40 additions and 91 deletions

View File

@ -60,6 +60,7 @@ type FlowExecutor struct {
func NewFlowExecutor(ctx context.Context, flowSlug string, refConfig *api.Configuration, logFields log.Fields) *FlowExecutor { func NewFlowExecutor(ctx context.Context, flowSlug string, refConfig *api.Configuration, logFields log.Fields) *FlowExecutor {
rsp := sentry.StartSpan(ctx, "authentik.outposts.flow_executor") rsp := sentry.StartSpan(ctx, "authentik.outposts.flow_executor")
rsp.Description = flowSlug
l := log.WithField("flow", flowSlug).WithFields(logFields) l := log.WithField("flow", flowSlug).WithFields(logFields)
jar, err := cookiejar.New(nil) jar, err := cookiejar.New(nil)
@ -153,8 +154,8 @@ func (fe *FlowExecutor) solveFlowChallenge(depth int) (bool, error) {
} }
ch := challenge.GetActualInstance().(ChallengeInt) ch := challenge.GetActualInstance().(ChallengeInt)
fe.log.WithField("component", ch.GetComponent()).WithField("type", ch.GetType()).Debug("Got challenge") fe.log.WithField("component", ch.GetComponent()).WithField("type", ch.GetType()).Debug("Got challenge")
gcsp.SetTag("ak_challenge", string(ch.GetType())) gcsp.SetTag("authentik.flow.challenge", string(ch.GetType()))
gcsp.SetTag("ak_component", ch.GetComponent()) gcsp.SetTag("authentik.flow.component", ch.GetComponent())
gcsp.Finish() gcsp.Finish()
FlowTimingGet.With(prometheus.Labels{ FlowTimingGet.With(prometheus.Labels{
"stage": ch.GetComponent(), "stage": ch.GetComponent(),
@ -202,8 +203,8 @@ func (fe *FlowExecutor) solveFlowChallenge(depth int) (bool, error) {
response, _, err := responseReq.Execute() response, _, err := responseReq.Execute()
ch = response.GetActualInstance().(ChallengeInt) ch = response.GetActualInstance().(ChallengeInt)
fe.log.WithField("component", ch.GetComponent()).WithField("type", ch.GetType()).Debug("Got response") fe.log.WithField("component", ch.GetComponent()).WithField("type", ch.GetType()).Debug("Got response")
scsp.SetTag("ak_challenge", string(ch.GetType())) scsp.SetTag("authentik.flow.challenge", string(ch.GetType()))
scsp.SetTag("ak_component", ch.GetComponent()) scsp.SetTag("authentik.flow.component", ch.GetComponent())
scsp.Finish() scsp.Finish()
switch ch.GetComponent() { switch ch.GetComponent() {

View File

@ -23,9 +23,14 @@ type Request struct {
func NewRequest(bindDN string, bindPW string, conn net.Conn) (*Request, *sentry.Span) { func NewRequest(bindDN string, bindPW string, conn net.Conn) (*Request, *sentry.Span) {
span := sentry.StartSpan(context.TODO(), "authentik.providers.ldap.bind", span := sentry.StartSpan(context.TODO(), "authentik.providers.ldap.bind",
sentry.TransactionName("authentik.providers.ldap.bind")) sentry.TransactionName("authentik.providers.ldap.bind"))
span.Description = bindDN
rid := uuid.New().String() rid := uuid.New().String()
span.SetTag("request_uid", rid) 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) bindDN = strings.ToLower(bindDN)
return &Request{ return &Request{

View File

@ -2,6 +2,7 @@ package search
import ( import (
"context" "context"
"fmt"
"net" "net"
"strings" "strings"
@ -27,10 +28,15 @@ func NewRequest(bindDN string, searchReq ldap.SearchRequest, conn net.Conn) (*Re
bindDN = strings.ToLower(bindDN) bindDN = strings.ToLower(bindDN)
searchReq.BaseDN = strings.ToLower(searchReq.BaseDN) searchReq.BaseDN = strings.ToLower(searchReq.BaseDN)
span := sentry.StartSpan(context.TODO(), "authentik.providers.ldap.search", sentry.TransactionName("authentik.providers.ldap.search")) 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("request_uid", rid)
span.SetTag("user.username", bindDN) sentry.GetHubFromContext(span.Context()).Scope().SetUser(sentry.User{
span.SetTag("ak_filter", searchReq.Filter) Username: bindDN,
span.SetTag("ak_base_dn", searchReq.BaseDN) ID: bindDN,
IPAddress: utils.GetIP(conn.RemoteAddr()),
})
span.SetTag("ldap_filter", searchReq.Filter)
span.SetTag("ldap_base_dn", searchReq.BaseDN)
return &Request{ return &Request{
SearchRequest: searchReq, SearchRequest: searchReq,
BindDN: bindDN, BindDN: bindDN,

View File

@ -12,6 +12,8 @@ import (
"time" "time"
"github.com/coreos/go-oidc" "github.com/coreos/go-oidc"
"github.com/getsentry/sentry-go"
sentryhttp "github.com/getsentry/sentry-go/http"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/gorilla/sessions" "github.com/gorilla/sessions"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -109,6 +111,11 @@ func NewApplication(p api.ProxyOutpostConfig, c *http.Client, cs *ak.CryptoStore
user := "" user := ""
if c != nil { if c != nil {
user = c.PreferredUsername user = c.PreferredUsername
sentry.GetHubFromContext(r.Context()).Scope().SetUser(sentry.User{
Username: user,
ID: c.Sub,
IPAddress: r.RemoteAddr,
})
} }
before := time.Now() before := time.Now()
inner.ServeHTTP(rw, r) inner.ServeHTTP(rw, r)
@ -124,6 +131,7 @@ func NewApplication(p api.ProxyOutpostConfig, c *http.Client, cs *ak.CryptoStore
}).Observe(float64(after)) }).Observe(float64(after))
}) })
}) })
mux.Use(sentryhttp.New(sentryhttp.Options{}).Handle)
// Support /start and /sign_in for backwards compatibility // Support /start and /sign_in for backwards compatibility
mux.HandleFunc("/akprox/start", a.handleRedirect) mux.HandleFunc("/akprox/start", a.handleRedirect)

View File

@ -10,6 +10,7 @@ import (
"sync" "sync"
"time" "time"
sentryhttp "github.com/getsentry/sentry-go/http"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/pires/go-proxyproto" "github.com/pires/go-proxyproto"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
@ -52,6 +53,7 @@ func NewProxyServer(ac *ak.APIController, portOffset int) *ProxyServer {
globalMux := rootMux.NewRoute().Subrouter() globalMux := rootMux.NewRoute().Subrouter()
globalMux.Use(web.NewLoggingHandler(l.WithField("logger", "authentik.outpost.proxyv2.http"), nil)) globalMux.Use(web.NewLoggingHandler(l.WithField("logger", "authentik.outpost.proxyv2.http"), nil))
globalMux.Use(sentryhttp.New(sentryhttp.Options{}).Handle)
s := &ProxyServer{ s := &ProxyServer{
Listen: "0.0.0.0:%d", Listen: "0.0.0.0:%d",
PortOffset: portOffset, PortOffset: portOffset,

View File

@ -99,8 +99,8 @@ func (h loggingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
h.handler.ServeHTTP(responseLogger, req) h.handler.ServeHTTP(responseLogger, req)
duration := float64(time.Since(t)) / float64(time.Millisecond) duration := float64(time.Since(t)) / float64(time.Millisecond)
h.afterHandler(h.logger.WithFields(log.Fields{ h.afterHandler(h.logger.WithFields(log.Fields{
"host": req.RemoteAddr, "remote": req.RemoteAddr,
"vhost": GetHost(req), "host": GetHost(req),
"request_protocol": req.Proto, "request_protocol": req.Proto,
"runtime": fmt.Sprintf("%0.3f", duration), "runtime": fmt.Sprintf("%0.3f", duration),
"method": req.Method, "method": req.Method,

View File

@ -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()
})
}
}

View File

@ -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")
}
}
}()
})
}
}

View File

@ -6,6 +6,7 @@ import (
"net" "net"
"net/http" "net/http"
sentryhttp "github.com/getsentry/sentry-go/http"
"github.com/gorilla/handlers" "github.com/gorilla/handlers"
"github.com/gorilla/mux" "github.com/gorilla/mux"
"github.com/pires/go-proxyproto" "github.com/pires/go-proxyproto"
@ -13,6 +14,7 @@ import (
"goauthentik.io/internal/config" "goauthentik.io/internal/config"
"goauthentik.io/internal/gounicorn" "goauthentik.io/internal/gounicorn"
"goauthentik.io/internal/outpost/proxyv2" "goauthentik.io/internal/outpost/proxyv2"
"goauthentik.io/internal/utils/web"
) )
type WebServer struct { type WebServer struct {
@ -34,13 +36,11 @@ type WebServer struct {
func NewWebServer(g *gounicorn.GoUnicorn) *WebServer { func NewWebServer(g *gounicorn.GoUnicorn) *WebServer {
l := log.WithField("logger", "authentik.router") l := log.WithField("logger", "authentik.router")
mainHandler := mux.NewRouter() mainHandler := mux.NewRouter()
if config.G.ErrorReporting.Enabled { mainHandler.Use(sentryhttp.New(sentryhttp.Options{}).Handle)
mainHandler.Use(recoveryMiddleware())
}
mainHandler.Use(handlers.ProxyHeaders) mainHandler.Use(handlers.ProxyHeaders)
mainHandler.Use(handlers.CompressHandler) mainHandler.Use(handlers.CompressHandler)
logginRouter := mainHandler.NewRoute().Subrouter() logginRouter := mainHandler.NewRoute().Subrouter()
logginRouter.Use(loggingMiddleware(l)) logginRouter.Use(web.NewLoggingHandler(l, nil))
ws := &WebServer{ ws := &WebServer{
LegacyProxy: true, LegacyProxy: true,
@ -72,7 +72,7 @@ func (ws *WebServer) Shutdown() {
func (ws *WebServer) listenPlain() { func (ws *WebServer) listenPlain() {
ln, err := net.Listen("tcp", config.G.Web.Listen) ln, err := net.Listen("tcp", config.G.Web.Listen)
if err != nil { 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") 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) err = http.ListenAndServe(config.G.Web.Listen, ws.m)
if err != nil && !errors.Is(err, http.ErrServerClosed) { 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. // We received an interrupt signal, shut down.
if err := srv.Shutdown(context.Background()); err != nil { if err := srv.Shutdown(context.Background()); err != nil {
// Error from closing listeners, or context timeout: // 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) close(idleConnsClosed)
}() }()
err := srv.Serve(listener) err := srv.Serve(listener)
if err != nil && !errors.Is(err, http.ErrServerClosed) { 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 <-idleConnsClosed
} }