mirror of
https://github.com/pomerium/pomerium.git
synced 2025-05-11 16:17:39 +02:00
telemetry: add tracing
- telemetry/tace: add traces throughout code - telemetry/metrics: nest metrics and trace under telemetry - telemetry/tace: add service name span to HTTPMetricsHandler. - telemetry/metrics: removed chain dependency middleware_tests. - telemetry/metrics: wrap and encapsulate variatic view registration. - telemetry/tace: add jaeger support for tracing. - cmd/pomerium: move `parseOptions` to internal/config. - cmd/pomerium: offload server handling to httputil and sub pkgs. - httputil: standardize creation/shutdown of http listeners. - httputil: prefer curve X25519 to P256 when negotiating TLS. - fileutil: use standardized Getw Signed-off-by: Bobby DeSimone <bobbydesimone@gmail.com>
This commit is contained in:
parent
6b61a48fce
commit
5edfa7b03f
49 changed files with 1524 additions and 758 deletions
|
@ -3,12 +3,12 @@ package clients // import "github.com/pomerium/pomerium/proxy/clients"
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/pomerium/pomerium/internal/sessions"
|
||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
||||
pb "github.com/pomerium/pomerium/proto/authenticate"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
// Authenticator provides the authenticate service interface
|
||||
|
@ -48,11 +48,12 @@ type AuthenticateGRPC struct {
|
|||
// Redeem makes an RPC call to the authenticate service to creates a session state
|
||||
// from an encrypted code provided as a result of an oauth2 callback process.
|
||||
func (a *AuthenticateGRPC) Redeem(ctx context.Context, code string) (*sessions.SessionState, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "proxy.client.grpc.Redeem")
|
||||
defer span.End()
|
||||
|
||||
if code == "" {
|
||||
return nil, errors.New("missing code")
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
||||
defer cancel()
|
||||
protoSession, err := a.client.Authenticate(ctx, &pb.AuthenticateRequest{Code: code})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -68,6 +69,9 @@ func (a *AuthenticateGRPC) Redeem(ctx context.Context, code string) (*sessions.S
|
|||
// user's session. Requires a valid refresh token. Will return an error if the identity provider
|
||||
// has revoked the session or if the refresh token is no longer valid in this context.
|
||||
func (a *AuthenticateGRPC) Refresh(ctx context.Context, s *sessions.SessionState) (*sessions.SessionState, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "proxy.client.grpc.Refresh")
|
||||
defer span.End()
|
||||
|
||||
if s.RefreshToken == "" {
|
||||
return nil, errors.New("missing refresh token")
|
||||
}
|
||||
|
@ -75,14 +79,7 @@ func (a *AuthenticateGRPC) Refresh(ctx context.Context, s *sessions.SessionState
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// todo(bdd): handle request id in grpc receiver and add to ctx logger
|
||||
// reqID, ok := middleware.IDFromCtx(ctx)
|
||||
// if ok {
|
||||
// md := metadata.Pairs("req_id", reqID)
|
||||
// ctx = metadata.NewOutgoingContext(ctx, md)
|
||||
// }
|
||||
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// todo(bdd): add grpc specific timeouts to main options
|
||||
// todo(bdd): handle request id (metadata!?) in grpc receiver and add to ctx logger
|
||||
reply, err := a.client.Refresh(ctx, req)
|
||||
|
@ -100,18 +97,13 @@ func (a *AuthenticateGRPC) Refresh(ctx context.Context, s *sessions.SessionState
|
|||
// does NOT do nonce or revokation validation.
|
||||
// https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation
|
||||
func (a *AuthenticateGRPC) Validate(ctx context.Context, idToken string) (bool, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "proxy.client.grpc.Validate")
|
||||
defer span.End()
|
||||
|
||||
if idToken == "" {
|
||||
return false, errors.New("missing id token")
|
||||
}
|
||||
// todo(bdd): add grpc specific timeouts to main options
|
||||
// todo(bdd): handle request id in grpc receiver and add to ctx logger
|
||||
// reqID, ok := middleware.IDFromCtx(ctx)
|
||||
// if ok {
|
||||
// md := metadata.Pairs("req_id", reqID)
|
||||
// ctx = metadata.NewOutgoingContext(ctx, md)
|
||||
// }
|
||||
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
r, err := a.client.Validate(ctx, &pb.ValidateRequest{IdToken: idToken})
|
||||
if err != nil {
|
||||
return false, err
|
||||
|
|
|
@ -3,12 +3,12 @@ package clients // import "github.com/pomerium/pomerium/proxy/clients"
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/pomerium/pomerium/internal/sessions"
|
||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
||||
pb "github.com/pomerium/pomerium/proto/authorize"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
// Authorizer provides the authorize service interface
|
||||
|
@ -47,11 +47,12 @@ type AuthorizeGRPC struct {
|
|||
// Authorize takes a route and user session and returns whether the
|
||||
// request is valid per access policy
|
||||
func (a *AuthorizeGRPC) Authorize(ctx context.Context, route string, s *sessions.SessionState) (bool, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "proxy.client.grpc.Authorize")
|
||||
defer span.End()
|
||||
|
||||
if s == nil {
|
||||
return false, errors.New("session cannot be nil")
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
||||
defer cancel()
|
||||
response, err := a.client.Authorize(ctx, &pb.Identity{
|
||||
Route: route,
|
||||
User: s.User,
|
||||
|
@ -65,11 +66,12 @@ func (a *AuthorizeGRPC) Authorize(ctx context.Context, route string, s *sessions
|
|||
|
||||
// IsAdmin takes a session and returns whether the user is an administrator
|
||||
func (a *AuthorizeGRPC) IsAdmin(ctx context.Context, s *sessions.SessionState) (bool, error) {
|
||||
ctx, span := trace.StartSpan(ctx, "proxy.client.grpc.IsAdmin")
|
||||
defer span.End()
|
||||
|
||||
if s == nil {
|
||||
return false, errors.New("session cannot be nil")
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
||||
defer cancel()
|
||||
response, err := a.client.IsAdmin(ctx, &pb.Identity{Email: s.Email, Groups: s.Groups})
|
||||
return response.GetIsAdmin(), err
|
||||
}
|
||||
|
|
|
@ -11,8 +11,9 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/pomerium/pomerium/internal/log"
|
||||
"github.com/pomerium/pomerium/internal/metrics"
|
||||
"github.com/pomerium/pomerium/internal/middleware"
|
||||
"github.com/pomerium/pomerium/internal/telemetry/metrics"
|
||||
|
||||
"go.opencensus.io/plugin/ocgrpc"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"fmt"
|
||||
"html/template"
|
||||
stdlog "log"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
|
@ -16,9 +17,10 @@ import (
|
|||
"github.com/pomerium/pomerium/internal/config"
|
||||
"github.com/pomerium/pomerium/internal/cryptutil"
|
||||
"github.com/pomerium/pomerium/internal/log"
|
||||
"github.com/pomerium/pomerium/internal/metrics"
|
||||
"github.com/pomerium/pomerium/internal/middleware"
|
||||
"github.com/pomerium/pomerium/internal/sessions"
|
||||
"github.com/pomerium/pomerium/internal/telemetry/metrics"
|
||||
"github.com/pomerium/pomerium/internal/telemetry/trace"
|
||||
"github.com/pomerium/pomerium/internal/templates"
|
||||
"github.com/pomerium/pomerium/internal/tripper"
|
||||
"github.com/pomerium/pomerium/proxy/clients"
|
||||
|
@ -196,11 +198,19 @@ func (p *Proxy) UpdatePolicies(opts *config.Options) error {
|
|||
}
|
||||
proxy := NewReverseProxy(policy.Destination)
|
||||
// build http transport (roundtripper) middleware chain
|
||||
// todo(bdd): this will make vet complain, it is safe
|
||||
// and can be replaced with transport.Clone() in go 1.13
|
||||
// https://go-review.googlesource.com/c/go/+/174597/
|
||||
// https://github.com/golang/go/issues/26013#issuecomment-399481302
|
||||
transport := *(http.DefaultTransport.(*http.Transport))
|
||||
// todo(bdd): replace with transport.Clone() in go 1.13
|
||||
transport := http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
DualStack: true,
|
||||
}).DialContext,
|
||||
MaxIdleConns: 100,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
}
|
||||
c := tripper.NewChain()
|
||||
c = c.Append(metrics.HTTPMetricsRoundTripper("proxy", policy.Destination.Host))
|
||||
if policy.TLSSkipVerify {
|
||||
|
@ -236,7 +246,9 @@ type UpstreamProxy struct {
|
|||
|
||||
// ServeHTTP handles the second (reverse-proxying) leg of pomerium's request flow
|
||||
func (u *UpstreamProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
u.handler.ServeHTTP(w, r)
|
||||
ctx, span := trace.StartSpan(r.Context(), fmt.Sprintf("%s%s", r.Host, r.URL.Path))
|
||||
defer span.End()
|
||||
u.handler.ServeHTTP(w, r.WithContext(ctx))
|
||||
}
|
||||
|
||||
// NewReverseProxy returns a new ReverseProxy that routes URLs to the scheme, host, and
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue