outposts: add outpost_name label to metrics

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-09-16 10:03:31 +02:00
parent 48ad3dccda
commit a6a6b3bd06
13 changed files with 105 additions and 93 deletions

View File

@ -42,6 +42,7 @@ func (ls *LDAPServer) Bind(bindDN string, bindPW string, conn net.Conn) (ldap.LD
defer func() { defer func() {
span.Finish() span.Finish()
metrics.Requests.With(prometheus.Labels{ metrics.Requests.With(prometheus.Labels{
"outpost_name": ls.ac.Outpost.Name,
"type": "bind", "type": "bind",
"filter": "", "filter": "",
"dn": req.BindDN, "dn": req.BindDN,
@ -59,6 +60,7 @@ func (ls *LDAPServer) Bind(bindDN string, bindPW string, conn net.Conn) (ldap.LD
} }
req.log.WithField("request", "bind").Warning("No provider found for request") req.log.WithField("request", "bind").Warning("No provider found for request")
metrics.RequestsRejected.With(prometheus.Labels{ metrics.RequestsRejected.With(prometheus.Labels{
"outpost_name": ls.ac.Outpost.Name,
"type": "bind", "type": "bind",
"reason": "no_provider", "reason": "no_provider",
"dn": bindDN, "dn": bindDN,

View File

@ -51,6 +51,7 @@ func (pi *ProviderInstance) Bind(username string, req BindRequest) (ldap.LDAPRes
passed, err := fe.Execute() passed, err := fe.Execute()
if !passed { if !passed {
metrics.RequestsRejected.With(prometheus.Labels{ metrics.RequestsRejected.With(prometheus.Labels{
"outpost_name": pi.outpostName,
"type": "bind", "type": "bind",
"reason": "invalid_credentials", "reason": "invalid_credentials",
"dn": req.BindDN, "dn": req.BindDN,
@ -60,6 +61,7 @@ func (pi *ProviderInstance) Bind(username string, req BindRequest) (ldap.LDAPRes
} }
if err != nil { if err != nil {
metrics.RequestsRejected.With(prometheus.Labels{ metrics.RequestsRejected.With(prometheus.Labels{
"outpost_name": pi.outpostName,
"type": "bind", "type": "bind",
"reason": "flow_error", "reason": "flow_error",
"dn": req.BindDN, "dn": req.BindDN,
@ -73,6 +75,7 @@ func (pi *ProviderInstance) Bind(username string, req BindRequest) (ldap.LDAPRes
if !access { if !access {
req.log.Info("Access denied for user") req.log.Info("Access denied for user")
metrics.RequestsRejected.With(prometheus.Labels{ metrics.RequestsRejected.With(prometheus.Labels{
"outpost_name": pi.outpostName,
"type": "bind", "type": "bind",
"reason": "access_denied", "reason": "access_denied",
"dn": req.BindDN, "dn": req.BindDN,
@ -82,6 +85,7 @@ func (pi *ProviderInstance) Bind(username string, req BindRequest) (ldap.LDAPRes
} }
if err != nil { if err != nil {
metrics.RequestsRejected.With(prometheus.Labels{ metrics.RequestsRejected.With(prometheus.Labels{
"outpost_name": pi.outpostName,
"type": "bind", "type": "bind",
"reason": "access_check_fail", "reason": "access_check_fail",
"dn": req.BindDN, "dn": req.BindDN,
@ -96,6 +100,7 @@ func (pi *ProviderInstance) Bind(username string, req BindRequest) (ldap.LDAPRes
userInfo, _, err := fe.ApiClient().CoreApi.CoreUsersMeRetrieve(context.Background()).Execute() userInfo, _, err := fe.ApiClient().CoreApi.CoreUsersMeRetrieve(context.Background()).Execute()
if err != nil { if err != nil {
metrics.RequestsRejected.With(prometheus.Labels{ metrics.RequestsRejected.With(prometheus.Labels{
"outpost_name": pi.outpostName,
"type": "bind", "type": "bind",
"reason": "user_info_fail", "reason": "user_info_fail",
"dn": req.BindDN, "dn": req.BindDN,

View File

@ -36,6 +36,7 @@ func (pi *ProviderInstance) Search(req SearchRequest) (ldap.ServerSearchResult,
filterEntity, err := ldap.GetFilterObjectClass(req.Filter) filterEntity, err := ldap.GetFilterObjectClass(req.Filter)
if err != nil { if err != nil {
metrics.RequestsRejected.With(prometheus.Labels{ metrics.RequestsRejected.With(prometheus.Labels{
"outpost_name": pi.outpostName,
"type": "search", "type": "search",
"reason": "filter_parse_fail", "reason": "filter_parse_fail",
"dn": req.BindDN, "dn": req.BindDN,
@ -45,6 +46,7 @@ func (pi *ProviderInstance) Search(req SearchRequest) (ldap.ServerSearchResult,
} }
if len(req.BindDN) < 1 { if len(req.BindDN) < 1 {
metrics.RequestsRejected.With(prometheus.Labels{ metrics.RequestsRejected.With(prometheus.Labels{
"outpost_name": pi.outpostName,
"type": "search", "type": "search",
"reason": "empty_bind_dn", "reason": "empty_bind_dn",
"dn": req.BindDN, "dn": req.BindDN,
@ -54,6 +56,7 @@ func (pi *ProviderInstance) Search(req SearchRequest) (ldap.ServerSearchResult,
} }
if !strings.HasSuffix(req.BindDN, baseDN) { if !strings.HasSuffix(req.BindDN, baseDN) {
metrics.RequestsRejected.With(prometheus.Labels{ metrics.RequestsRejected.With(prometheus.Labels{
"outpost_name": pi.outpostName,
"type": "search", "type": "search",
"reason": "invalid_bind_dn", "reason": "invalid_bind_dn",
"dn": req.BindDN, "dn": req.BindDN,
@ -68,6 +71,7 @@ func (pi *ProviderInstance) Search(req SearchRequest) (ldap.ServerSearchResult,
if !ok { if !ok {
pi.log.Debug("User info not cached") pi.log.Debug("User info not cached")
metrics.RequestsRejected.With(prometheus.Labels{ metrics.RequestsRejected.With(prometheus.Labels{
"outpost_name": pi.outpostName,
"type": "search", "type": "search",
"reason": "user_info_not_cached", "reason": "user_info_not_cached",
"dn": req.BindDN, "dn": req.BindDN,
@ -84,6 +88,7 @@ func (pi *ProviderInstance) Search(req SearchRequest) (ldap.ServerSearchResult,
parsedFilter, err := ldap.CompileFilter(req.Filter) parsedFilter, err := ldap.CompileFilter(req.Filter)
if err != nil { if err != nil {
metrics.RequestsRejected.With(prometheus.Labels{ metrics.RequestsRejected.With(prometheus.Labels{
"outpost_name": pi.outpostName,
"type": "search", "type": "search",
"reason": "filter_parse_fail", "reason": "filter_parse_fail",
"dn": req.BindDN, "dn": req.BindDN,
@ -99,6 +104,7 @@ func (pi *ProviderInstance) Search(req SearchRequest) (ldap.ServerSearchResult,
switch filterEntity { switch filterEntity {
default: default:
metrics.RequestsRejected.With(prometheus.Labels{ metrics.RequestsRejected.With(prometheus.Labels{
"outpost_name": pi.outpostName,
"type": "search", "type": "search",
"reason": "unhandled_filter_type", "reason": "unhandled_filter_type",
"dn": req.BindDN, "dn": req.BindDN,

View File

@ -31,7 +31,7 @@ type ProviderInstance struct {
tlsServerName *string tlsServerName *string
cert *tls.Certificate cert *tls.Certificate
outpostName string
searchAllowedGroups []*strfmt.UUID searchAllowedGroups []*strfmt.UUID
boundUsersMutex sync.RWMutex boundUsersMutex sync.RWMutex
boundUsers map[string]UserFlags boundUsers map[string]UserFlags

View File

@ -13,11 +13,11 @@ var (
Requests = promauto.NewHistogramVec(prometheus.HistogramOpts{ Requests = promauto.NewHistogramVec(prometheus.HistogramOpts{
Name: "authentik_outpost_ldap_requests", Name: "authentik_outpost_ldap_requests",
Help: "The total number of configured providers", Help: "The total number of configured providers",
}, []string{"type", "dn", "filter", "client"}) }, []string{"outpost_name", "type", "dn", "filter", "client"})
RequestsRejected = promauto.NewCounterVec(prometheus.CounterOpts{ RequestsRejected = promauto.NewCounterVec(prometheus.CounterOpts{
Name: "authentik_outpost_ldap_requests_rejected", Name: "authentik_outpost_ldap_requests_rejected",
Help: "Total number of rejected requests", Help: "Total number of rejected requests",
}, []string{"type", "reason", "dn", "client"}) }, []string{"outpost_name", "type", "reason", "dn", "client"})
) )
func RunServer() { func RunServer() {

View File

@ -50,6 +50,7 @@ func (ls *LDAPServer) Refresh() error {
tlsServerName: provider.TlsServerName, tlsServerName: provider.TlsServerName,
uidStartNumber: *provider.UidStartNumber, uidStartNumber: *provider.UidStartNumber,
gidStartNumber: *provider.GidStartNumber, gidStartNumber: *provider.GidStartNumber,
outpostName: ls.ac.Outpost.Name,
} }
if provider.Certificate.Get() != nil { if provider.Certificate.Get() != nil {
kp := provider.Certificate.Get() kp := provider.Certificate.Get()

View File

@ -46,6 +46,7 @@ func (ls *LDAPServer) Search(bindDN string, searchReq ldap.SearchRequest, conn n
defer func() { defer func() {
span.Finish() span.Finish()
metrics.Requests.With(prometheus.Labels{ metrics.Requests.With(prometheus.Labels{
"outpost_name": ls.ac.Outpost.Name,
"type": "search", "type": "search",
"filter": req.Filter, "filter": req.Filter,
"dn": req.BindDN, "dn": req.BindDN,

View File

@ -31,6 +31,7 @@ type Application struct {
endpint OIDCEndpoint endpint OIDCEndpoint
oauthConfig oauth2.Config oauthConfig oauth2.Config
tokenVerifier *oidc.IDTokenVerifier tokenVerifier *oidc.IDTokenVerifier
outpostName string
sessions sessions.Store sessions sessions.Store
proxyConfig api.ProxyOutpostConfig proxyConfig api.ProxyOutpostConfig
@ -40,7 +41,7 @@ type Application struct {
mux *mux.Router mux *mux.Router
} }
func NewApplication(p api.ProxyOutpostConfig, c *http.Client, cs *ak.CryptoStore, akHost string) *Application { func NewApplication(p api.ProxyOutpostConfig, c *http.Client, cs *ak.CryptoStore, ak *ak.APIController) *Application {
gob.Register(Claims{}) gob.Register(Claims{})
externalHost, err := url.Parse(p.ExternalHost) externalHost, err := url.Parse(p.ExternalHost)
@ -56,7 +57,7 @@ func NewApplication(p api.ProxyOutpostConfig, c *http.Client, cs *ak.CryptoStore
}) })
// Configure an OpenID Connect aware OAuth2 client. // Configure an OpenID Connect aware OAuth2 client.
endpoint := GetOIDCEndpoint(p, akHost) endpoint := GetOIDCEndpoint(p, ak.Outpost.Config["authentik_host"].(string))
oauth2Config := oauth2.Config{ oauth2Config := oauth2.Config{
ClientID: *p.ClientId, ClientID: *p.ClientId,
ClientSecret: *p.ClientSecret, ClientSecret: *p.ClientSecret,
@ -68,6 +69,7 @@ func NewApplication(p api.ProxyOutpostConfig, c *http.Client, cs *ak.CryptoStore
a := &Application{ a := &Application{
Host: externalHost.Host, Host: externalHost.Host,
log: log.WithField("logger", "authentik.outpost.proxy.bundle").WithField("provider", p.Name), log: log.WithField("logger", "authentik.outpost.proxy.bundle").WithField("provider", p.Name),
outpostName: ak.Outpost.Name,
endpint: endpoint, endpint: endpoint,
oauthConfig: oauth2Config, oauthConfig: oauth2Config,
tokenVerifier: verifier, tokenVerifier: verifier,
@ -103,6 +105,7 @@ func NewApplication(p api.ProxyOutpostConfig, c *http.Client, cs *ak.CryptoStore
inner.ServeHTTP(rw, r) inner.ServeHTTP(rw, r)
after := time.Since(before) after := time.Since(before)
metrics.Requests.With(prometheus.Labels{ metrics.Requests.With(prometheus.Labels{
"outpost_name": a.outpostName,
"type": "app", "type": "app",
"scheme": r.URL.Scheme, "scheme": r.URL.Scheme,
"method": r.Method, "method": r.Method,

View File

@ -50,6 +50,7 @@ func (a *Application) configureProxy() error {
user = claims.Email user = claims.Email
} }
metrics.UpstreamTiming.With(prometheus.Labels{ metrics.UpstreamTiming.With(prometheus.Labels{
"outpost_name": a.outpostName,
"upstream_host": u.String(), "upstream_host": u.String(),
"scheme": r.URL.Scheme, "scheme": r.URL.Scheme,
"method": r.Method, "method": r.Method,

View File

@ -44,15 +44,6 @@ func (a *Application) getClaims(r *http.Request) (*Claims, error) {
return &c, nil return &c, nil
} }
func contains(s []string, e string) bool {
for _, a := range s {
if a == e {
return true
}
}
return false
}
// toString Generic to string function, currently supports actual strings and integers // toString Generic to string function, currently supports actual strings and integers
func toString(in interface{}) string { func toString(in interface{}) string {
switch v := in.(type) { switch v := in.(type) {

View File

@ -15,6 +15,7 @@ func (ps *ProxyServer) HandlePing(rw http.ResponseWriter, r *http.Request) {
rw.WriteHeader(204) rw.WriteHeader(204)
after := time.Since(before) after := time.Since(before)
metrics.Requests.With(prometheus.Labels{ metrics.Requests.With(prometheus.Labels{
"outpost_name": ps.akAPI.Outpost.Name,
"method": r.Method, "method": r.Method,
"schema": r.URL.Scheme, "schema": r.URL.Scheme,
"path": r.URL.Path, "path": r.URL.Path,
@ -30,6 +31,7 @@ func (ps *ProxyServer) HandleStatic(rw http.ResponseWriter, r *http.Request) {
http.StripPrefix("/akprox/static", staticFs).ServeHTTP(rw, r) http.StripPrefix("/akprox/static", staticFs).ServeHTTP(rw, r)
after := time.Since(before) after := time.Since(before)
metrics.Requests.With(prometheus.Labels{ metrics.Requests.With(prometheus.Labels{
"outpost_name": ps.akAPI.Outpost.Name,
"method": r.Method, "method": r.Method,
"schema": r.URL.Scheme, "schema": r.URL.Scheme,
"path": r.URL.Path, "path": r.URL.Path,

View File

@ -13,11 +13,11 @@ var (
Requests = promauto.NewHistogramVec(prometheus.HistogramOpts{ Requests = promauto.NewHistogramVec(prometheus.HistogramOpts{
Name: "authentik_outpost_proxy_requests", Name: "authentik_outpost_proxy_requests",
Help: "The total number of configured providers", Help: "The total number of configured providers",
}, []string{"method", "scheme", "path", "host", "type", "user"}) }, []string{"outpost_name", "method", "scheme", "path", "host", "type", "user"})
UpstreamTiming = promauto.NewHistogramVec(prometheus.HistogramOpts{ UpstreamTiming = promauto.NewHistogramVec(prometheus.HistogramOpts{
Name: "authentik_outpost_proxy_upstream_time", Name: "authentik_outpost_proxy_upstream_time",
Help: "A summary of the duration we wait for the upstream reply", Help: "A summary of the duration we wait for the upstream reply",
}, []string{"method", "scheme", "path", "host", "upstream_host", "user"}) }, []string{"outpost_name", "method", "scheme", "path", "host", "upstream_host", "user"})
) )
func RunServer() { func RunServer() {

View File

@ -24,7 +24,7 @@ func (ps *ProxyServer) Refresh() error {
hc := &http.Client{ hc := &http.Client{
Transport: ak.NewUserAgentTransport(constants.OutpostUserAgent()+ua, ak.NewTracingTransport(context.TODO(), ak.GetTLSTransport())), Transport: ak.NewUserAgentTransport(constants.OutpostUserAgent()+ua, ak.NewTracingTransport(context.TODO(), ak.GetTLSTransport())),
} }
a := application.NewApplication(provider, hc, ps.cryptoStore, ps.akAPI.Outpost.Config["authentik_host"].(string)) a := application.NewApplication(provider, hc, ps.cryptoStore, ps.akAPI)
apps[a.Host] = a apps[a.Host] = a
} }
ps.apps = apps ps.apps = apps