proxy

package
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 1, 2019 License: MIT Imports: 37 Imported by: 0

Documentation

Index

Constants

View Source
const HMACSignatureHeader = "Gap-Signature"

HMACSignatureHeader is the header name where the signed request header is stored.

View Source
const VERSION = "2.2.1-alpha"

VERSION is the version of sso proxy

Variables

View Source
var (
	ErrLifetimeExpired   = errors.New("user lifetime expired")
	ErrUserNotAuthorized = errors.New("user not authorized")
	ErrUnknownHost       = errors.New("unknown host")
)

Errors

View Source
var SignatureHeaders = []string{
	"Content-Length",
	"Content-Md5",
	"Content-Type",
	"Date",
	"Authorization",
	"X-Forwarded-User",
	"X-Forwarded-Email",
	"X-Forwarded-Groups",
	"Cookie",
}

SignatureHeaders are the headers that are valid in the request.

Functions

func GetActionTag

func GetActionTag(req *http.Request) string

GetActionTag returns the action triggered by an http.Request .

func NewLoggingHandler

func NewLoggingHandler(out io.Writer, h http.Handler, v bool, StatsdClient *statsd.Client) http.Handler

NewLoggingHandler returns a new loggingHandler that wraps a handler, statsd client, and writer.

func NewReverseProxy

func NewReverseProxy(to *url.URL, config *UpstreamConfig) *httputil.ReverseProxy

NewReverseProxy creates a reverse proxy to a specified url. It adds an X-Forwarded-Host header that is the request's host.

func NewReverseProxyHandler

func NewReverseProxyHandler(reverseProxy *httputil.ReverseProxy, opts *Options, config *UpstreamConfig, signer *RequestSigner) (http.Handler, []string)

NewReverseProxyHandler creates a new http.Handler given a httputil.ReverseProxy

func NewRewriteReverseProxy

func NewRewriteReverseProxy(route *RewriteRoute, config *UpstreamConfig) *httputil.ReverseProxy

NewRewriteReverseProxy creates a reverse proxy that is capable of creating upstream urls on the fly based on a from regex and a templated to field. It adds an X-Forwarded-Host header to the the upstream's request.

func NewStreamingHandler

func NewStreamingHandler(handler http.Handler, opts *Options, config *UpstreamConfig) http.Handler

NewStreamingHandler creates a new handler capable of proxying a stream

func NewTimeoutHandler

func NewTimeoutHandler(handler http.Handler, config *UpstreamConfig) http.Handler

NewTimeoutHandler creates a new handler with a configure timeout.

func SetCookieStore added in v1.2.0

func SetCookieStore(opts *Options) func(*OAuthProxy) error

SetCookieStore sets the session and csrf stores as a functional option

Types

type EmailValidatorFn

type EmailValidatorFn func(string) bool

EmailValidatorFn function type for validating email addresses.

type ErrParsingConfig

type ErrParsingConfig struct {
	Message string
	Err     error
}

ErrParsingConfig is an error specific to config parsing.

func (*ErrParsingConfig) Error

func (e *ErrParsingConfig) Error() string

Error() implements the error interface, returning a string representation of the error.

type OAuthProxy

type OAuthProxy struct {
	CookieSecure bool
	CookieCipher aead.Cipher

	EmailValidator EmailValidatorFn

	PassAccessToken bool

	StatsdClient *statsd.Client
	// contains filtered or unexported fields
}

OAuthProxy stores all the information associated with proxying the request.

func NewOAuthProxy

func NewOAuthProxy(opts *Options, optFuncs ...func(*OAuthProxy) error) (*OAuthProxy, error)

NewOAuthProxy creates a new OAuthProxy struct.

func (*OAuthProxy) Authenticate

func (p *OAuthProxy) Authenticate(rw http.ResponseWriter, req *http.Request) (err error)

Authenticate authenticates a request by checking for a session cookie, and validating its expiration, clearing the session cookie if it's invalid and returning an error if necessary..

func (*OAuthProxy) AuthenticateOnly

func (p *OAuthProxy) AuthenticateOnly(rw http.ResponseWriter, req *http.Request)

AuthenticateOnly calls the Authenticate handler.

func (*OAuthProxy) Certs added in v1.1.0

func (p *OAuthProxy) Certs(rw http.ResponseWriter, _ *http.Request)

Certs publishes the public key necessary for upstream services to validate the digital signature used to sign each request.

func (*OAuthProxy) ErrorPage

func (p *OAuthProxy) ErrorPage(rw http.ResponseWriter, req *http.Request, code int, title string, message string)

ErrorPage renders an error page with a given status code, title, and message.

func (*OAuthProxy) Favicon

func (p *OAuthProxy) Favicon(rw http.ResponseWriter, req *http.Request)

Favicon will proxy the request as usual if the user is already authenticated but responds with a 404 otherwise, to avoid spurious and confusing authentication attempts when a browser automatically requests the favicon on an error page.

func (*OAuthProxy) GetRedirectURL

func (p *OAuthProxy) GetRedirectURL(host string) *url.URL

GetRedirectURL returns the redirect url for a given OAuthProxy, setting the scheme to be https if CookieSecure is true.

func (*OAuthProxy) Handle

func (p *OAuthProxy) Handle(host string, handler http.Handler, tags []string, upstreamConfig *UpstreamConfig)

Handle constructs a route from the given host string and matches it to the provided http.Handler and UpstreamConfig

func (*OAuthProxy) HandleRegex

func (p *OAuthProxy) HandleRegex(regex *regexp.Regexp, handler http.Handler, tags []string, upstreamConfig *UpstreamConfig)

HandleRegex constructs a route from the given regexp and matches it to the provided http.Handler and UpstreamConfig

func (*OAuthProxy) Handler

func (p *OAuthProxy) Handler() http.Handler

Handler returns a http handler for an OAuthProxy

func (*OAuthProxy) IsWhitelistedRequest

func (p *OAuthProxy) IsWhitelistedRequest(req *http.Request) bool

IsWhitelistedRequest cheks that proxy host exists and checks the SkipAuthRegex

func (*OAuthProxy) OAuthCallback

func (p *OAuthProxy) OAuthCallback(rw http.ResponseWriter, req *http.Request)

OAuthCallback validates the cookie sent back from the provider, then validates the user information, and if authorized, redirects the user back to the original application.

func (*OAuthProxy) OAuthStart

func (p *OAuthProxy) OAuthStart(rw http.ResponseWriter, req *http.Request, tags []string)

OAuthStart begins the authentication flow, encrypting the redirect url in a request to the provider's sign in endpoint.

func (*OAuthProxy) PingPage

func (p *OAuthProxy) PingPage(rw http.ResponseWriter, _ *http.Request)

PingPage send back a 200 OK response.

func (*OAuthProxy) Proxy

func (p *OAuthProxy) Proxy(rw http.ResponseWriter, req *http.Request)

Proxy authenticates a request, either proxying the request if it is authenticated, or starting the authentication process if not.

func (*OAuthProxy) RobotsTxt

func (p *OAuthProxy) RobotsTxt(rw http.ResponseWriter, _ *http.Request)

RobotsTxt sets the User-Agent header in the response to be "Disallow"

func (*OAuthProxy) SignOut

func (p *OAuthProxy) SignOut(rw http.ResponseWriter, req *http.Request)

SignOut redirects the request to the provider's sign out url.

func (*OAuthProxy) UnknownHost

func (p *OAuthProxy) UnknownHost(rw http.ResponseWriter, req *http.Request)

UnknownHost returns an http error for unknown or invalid hosts

func (*OAuthProxy) XHRError added in v1.1.0

func (p *OAuthProxy) XHRError(rw http.ResponseWriter, req *http.Request, code int, err error)

XHRError returns a simple error response with an error message to the application if the request is an XML request

type Options

type Options struct {
	Port int `envconfig:"PORT" default:"4180"`

	ProviderURLString         string `envconfig:"PROVIDER_URL"`
	ProviderURLInternalString string `envconfig:"PROVIDER_URL_INTERNAL"`
	UpstreamConfigsFile       string `envconfig:"UPSTREAM_CONFIGS"`
	Cluster                   string `envconfig:"CLUSTER"`
	Scheme                    string `envconfig:"SCHEME" default:"https"`

	SkipAuthPreflight bool `envconfig:"SKIP_AUTH_PREFLIGHT"`

	EmailDomains         []string `envconfig:"EMAIL_DOMAIN"`
	EmailAddresses       []string `envconfig:"EMAIL_ADDRESSES"`
	DefaultAllowedGroups []string `envconfig:"DEFAULT_ALLOWED_GROUPS"`

	ClientID     string `envconfig:"CLIENT_ID"`
	ClientSecret string `envconfig:"CLIENT_SECRET"`

	DefaultUpstreamTimeout          time.Duration `envconfig:"DEFAULT_UPSTREAM_TIMEOUT" default:"10s"`
	DefaultUpstreamTCPResetDeadline time.Duration `envconfig:"DEFAULT_UPSTREAM_TCP_RESET_DEADLINE" default:"60s"`

	TCPWriteTimeout time.Duration `envconfig:"TCP_WRITE_TIMEOUT" default:"30s"`
	TCPReadTimeout  time.Duration `envconfig:"TCP_READ_TIMEOUT" default:"30s"`

	CookieName     string
	CookieSecret   string        `envconfig:"COOKIE_SECRET"`
	CookieDomain   string        `envconfig:"COOKIE_DOMAIN"`
	CookieExpire   time.Duration `envconfig:"COOKIE_EXPIRE" default:"168h"`
	CookieSecure   bool          `envconfig:"COOKIE_SECURE" default:"true"`
	CookieHTTPOnly bool          `envconfig:"COOKIE_HTTP_ONLY"`

	PassAccessToken bool `envconfig:"PASS_ACCESS_TOKEN" default:"false"`

	// These options allow for other providers besides Google, with potential overrides.
	Provider string `envconfig:"PROVIDER" default:"google"`
	Scope    string `envconfig:"SCOPE"`

	SessionLifetimeTTL time.Duration `envconfig:"SESSION_LIFETIME_TTL" default:"720h"`
	SessionValidTTL    time.Duration `envconfig:"SESSION_VALID_TTL" default:"1m"`
	GracePeriodTTL     time.Duration `envconfig:"GRACE_PERIOD_TTL" default:"3h"`

	RequestLogging bool `envconfig:"REQUEST_LOGGING" default:"true"`

	StatsdHost string `envconfig:"STATSD_HOST"`
	StatsdPort int    `envconfig:"STATSD_PORT"`

	RequestSigningKey string `envconfig:"REQUEST_SIGNATURE_KEY"`

	StatsdClient *statsd.Client
	// contains filtered or unexported fields
}

Options are configuration options that can be set by Environment Variables Port - int - port to listen on for HTTP clients ProviderURLString - the URL for the provider in this environment: "https://sso-auth.example.com" ProxyProviderURLString - the internal URL for the provider in this environment: "https://sso-auth-int.example.com" UpstreamConfigsFile - the path to upstream configs file Cluster - the cluster in which this is running, used for upstream configs Scheme - the default scheme, used for upstream configs SkipAuthPreflight - will skip authentication for OPTIONS requests, default false EmailDomains - csv list of emails with the specified domain to authenticate. Use * to authenticate any email EmailAddresses - []string - authenticate emails with the specified email address (may be given multiple times). Use * to authenticate any email DefaultAllowedGroups - csv list of default allowed groups that are applied to authorize access to upstreams. Will be overriden by groups specified in upstream configs. ClientID - the OAuth Client ID: ie: "123456.apps.googleusercontent.com" ClientSecret - The OAuth Client Secret DefaultUpstreamTimeout - the default time period to wait for a response from an upstream DefaultUpstreamTCPResetDeadline - the default time period to wait for a response from an upstream TCPWriteTimeout - http server tcp write timeout - set to: max(default value specified, max(upstream timeouts)) TCPReadTimeout - http server tcp read timeout CookieName - name of the cookie CookieSecret - the seed string for secure cookies (optionally base64 encoded) CookieDomain - an optional cookie domain to force cookies to (ie: .yourcompany.com)* CookieExpire - expire timeframe for cookie CookieSecure - set secure (HTTPS) cookie flag CookieHTTPOnly - set HttpOnly cookie flag PassAccessToken - send access token in the http headers Provider - OAuth provider Scope - OAuth scope specification SessionLifetimeTTL - time to live for a session lifetime SessionValidTTL - time to live for a valid session GracePeriodTTL - time to reuse session data when provider unavailable RequestLoging - boolean whether or not to log requests StatsdHost - host addr for statsd client to listen on StatsdPort - port for statsdclient to listen on

func NewOptions

func NewOptions() *Options

NewOptions returns a new options struct

func (*Options) Validate

func (o *Options) Validate() error

Validate validates options

type OptionsConfig

type OptionsConfig struct {
	HeaderOverrides    map[string]string `yaml:"header_overrides"`
	SkipAuthRegex      []string          `yaml:"skip_auth_regex"`
	AllowedGroups      []string          `yaml:"allowed_groups"`
	TLSSkipVerify      bool              `yaml:"tls_skip_verify"`
	PreserveHost       bool              `yaml:"preserve_host"`
	Timeout            time.Duration     `yaml:"timeout"`
	ResetDeadline      time.Duration     `yaml:"reset_deadline"`
	FlushInterval      time.Duration     `yaml:"flush_interval"`
	SkipRequestSigning bool              `yaml:"skip_request_signing"`
}

OptionsConfig maps to the yaml config fields:

  • header_overrides - overrides any heads set either by sso proxy itself or upstream applications. This can be useful for modifying browser security headers.
  • skip_auth_regex - skips authentication for paths matching these regular expressions.
  • allowed_groups - optional list of authorized google groups that can access the service.
  • timeout - duration before timing out request.
  • flush_interval - interval at which the proxy should flush data to the browser

type RequestSigner added in v1.1.0

type RequestSigner struct {
	// contains filtered or unexported fields
}

RequestSigner exposes an interface for digitally signing requests using an RSA private key. See comments for the Sign() method below, for more on how this signature is constructed.

func NewRequestSigner added in v1.1.0

func NewRequestSigner(signingKeyPemStr string) (*RequestSigner, error)

NewRequestSigner constructs a RequestSigner object from a PEM+PKCS8 encoded RSA public key.

func (RequestSigner) PublicKey added in v1.1.0

func (signer RequestSigner) PublicKey() (string, string)

PublicKey returns a pair (KeyID, Key), where:

  • KeyID is a unique identifier (currently the SHA256 hash of Key),
  • Key is the (PEM+PKCS1)-encoding of a public key, usable for validating signed requests.

func (RequestSigner) Sign added in v1.1.0

func (signer RequestSigner) Sign(req *http.Request) error

Sign appends a header to the request, with a public-key encrypted signature derive from a subset of the request headers, together with the request URL and body.

Signature is computed as:

repr := Representation(request)  <- Computed by mapRequestToHashInput()
hash := SHA256(repr)
sig  := SIGN(hash, SigningKey)
final := WEB_SAFE_BASE64(sig)

The header `Sso-Signature` is given the value of `final`.

Receiving endpoints authenticating the integrity of a request should:

  1. Strip the WEB_SAFE_BASE64 encoding from the value of `signatureHeader`,

  2. Decrypt the resulting value using the public key published by sso_proxy, thus obtaining the hash of the request representation,

  3. Compute the request representation from the received request, using the same format as the mapRequestToHashInput() function above,

  4. Apply SHA256 hash to the recomputed representation, and verify that it matches the decrypted hash value received through the `Sso-Signature` of the request.

    Any requests failing this check should be considered tampered with, and rejected.

type RewriteRoute

type RewriteRoute struct {
	FromRegex  *regexp.Regexp
	ToTemplate *url.URL
}

RewriteRoute contains a FromRegex and ToTemplate used to construct rewrite routes in the reverse proxy.

type RouteConfig

type RouteConfig struct {
	From    string         `yaml:"from"`
	To      string         `yaml:"to"`
	Type    string         `yaml:"type"`
	Options *OptionsConfig `yaml:"options"`
}

RouteConfig maps to the yaml config fields, * "from" - the domain that will be used to access the service * "to" - the cname of the proxied service (this tells sso proxy where to proxy requests that come in on the from field)

type ServiceConfig

type ServiceConfig struct {
	Service        string                     `yaml:"service"`
	ClusterConfigs map[string]*UpstreamConfig `yaml:",inline"`
}

ServiceConfig represents the configuration for a given service

type SimpleRoute

type SimpleRoute struct {
	FromURL *url.URL
	ToURL   *url.URL
}

SimpleRoute contains a FromURL and ToURL used to construct simple routes in the reverse proxy.

type StateParameter

type StateParameter struct {
	SessionID   string `json:"session_id"`
	RedirectURI string `json:"redirect_uri"`
}

StateParameter holds the redirect id along with the session id.

type UpstreamConfig

type UpstreamConfig struct {
	Service string

	RouteConfig RouteConfig `yaml:",inline"`

	ExtraRoutes []*RouteConfig `yaml:"extra_routes"`

	// Generated at Parse Time
	Route interface{} // note: :/

	SkipAuthCompiledRegex []*regexp.Regexp
	AllowedGroups         []string
	TLSSkipVerify         bool
	PreserveHost          bool
	HMACAuth              hmacauth.HmacAuth
	Timeout               time.Duration
	ResetDeadline         time.Duration
	FlushInterval         time.Duration
	HeaderOverrides       map[string]string
	SkipRequestSigning    bool
}

UpstreamConfig represents the configuration for a given cluster in a given service

type UpstreamProxy

type UpstreamProxy struct {
	// contains filtered or unexported fields
}

UpstreamProxy stores information necessary for proxying the request back to the upstream.

func (*UpstreamProxy) ServeHTTP

func (u *UpstreamProxy) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP signs the http request and deletes cookie headers before calling the upstream's ServeHTTP function.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL