1
0
mirror of https://github.com/oauth2-proxy/oauth2-proxy.git synced 2025-03-27 22:01:28 +02:00

Create server options struct and move legacy server options to legacyOptions

This commit is contained in:
Joel Speed 2021-02-14 18:47:15 +00:00
parent 602dac7852
commit 3d457a8cdf
No known key found for this signature in database
GPG Key ID: 6E80578D6751DEFB
5 changed files with 199 additions and 13 deletions

View File

@ -28,6 +28,18 @@ type AlphaOptions struct {
// Headers may source values from either the authenticated user's session
// or from a static secret value.
InjectResponseHeaders []Header `json:"injectResponseHeaders,omitempty"`
// Server is used to configure the HTTP(S) server for the proxy application.
// You may choose to run both HTTP and HTTPS servers simultaneously.
// This can be done by setting the BindAddress and the SecureBindAddress simultaneously.
// To use the secure server you must configure a TLS certificate and key.
Server Server `json:"server,omitempty"`
// MetricsServer is used to configure the HTTP(S) server for metrics.
// You may choose to run both HTTP and HTTPS servers simultaneously.
// This can be done by setting the BindAddress and the SecureBindAddress simultaneously.
// To use the secure server you must configure a TLS certificate and key.
MetricsServer Server `json:"metricsServer,omitempty"`
}
// MergeInto replaces alpha options in the Options struct with the values
@ -36,6 +48,8 @@ func (a *AlphaOptions) MergeInto(opts *Options) {
opts.UpstreamServers = a.Upstreams
opts.InjectRequestHeaders = a.InjectRequestHeaders
opts.InjectResponseHeaders = a.InjectResponseHeaders
opts.Server = a.Server
opts.MetricsServer = a.MetricsServer
}
// ExtractFrom populates the fields in the AlphaOptions with the values from
@ -44,4 +58,6 @@ func (a *AlphaOptions) ExtractFrom(opts *Options) {
a.Upstreams = opts.UpstreamServers
a.InjectRequestHeaders = opts.InjectRequestHeaders
a.InjectResponseHeaders = opts.InjectResponseHeaders
a.Server = opts.Server
a.MetricsServer = opts.MetricsServer
}

View File

@ -18,6 +18,9 @@ type LegacyOptions struct {
// Legacy options for injecting request/response headers
LegacyHeaders LegacyHeaders `cfg:",squash"`
// Legacy options for the server address and TLS
LegacyServer LegacyServer `cfg:",squash"`
Options Options `cfg:",squash"`
}
@ -35,6 +38,11 @@ func NewLegacyOptions() *LegacyOptions {
SkipAuthStripHeaders: true,
},
LegacyServer: LegacyServer{
HTTPAddress: "127.0.0.1:4180",
HTTPSAddress: ":443",
},
Options: *NewOptions(),
}
}
@ -44,6 +52,7 @@ func NewLegacyFlagSet() *pflag.FlagSet {
flagSet.AddFlagSet(legacyUpstreamsFlagSet())
flagSet.AddFlagSet(legacyHeadersFlagSet())
flagSet.AddFlagSet(legacyServerFlagset())
return flagSet
}
@ -56,6 +65,8 @@ func (l *LegacyOptions) ToOptions() (*Options, error) {
l.Options.UpstreamServers = upstreams
l.Options.InjectRequestHeaders, l.Options.InjectResponseHeaders = l.LegacyHeaders.convert()
l.Options.Server, l.Options.MetricsServer = l.LegacyServer.convert()
return &l.Options, nil
}
@ -403,3 +414,52 @@ func getXAuthRequestAccessTokenHeader() Header {
},
}
}
type LegacyServer struct {
MetricsAddress string `flag:"metrics-address" cfg:"metrics_address"`
HTTPAddress string `flag:"http-address" cfg:"http_address"`
HTTPSAddress string `flag:"https-address" cfg:"https_address"`
TLSCertFile string `flag:"tls-cert-file" cfg:"tls_cert_file"`
TLSKeyFile string `flag:"tls-key-file" cfg:"tls_key_file"`
}
func legacyServerFlagset() *pflag.FlagSet {
flagSet := pflag.NewFlagSet("server", pflag.ExitOnError)
flagSet.String("metrics-address", "", "the address /metrics will be served on (e.g. \":9100\")")
flagSet.String("http-address", "127.0.0.1:4180", "[http://]<addr>:<port> or unix://<path> to listen on for HTTP clients")
flagSet.String("https-address", ":443", "<addr>:<port> to listen on for HTTPS clients")
flagSet.String("tls-cert-file", "", "path to certificate file")
flagSet.String("tls-key-file", "", "path to private key file")
return flagSet
}
func (l LegacyServer) convert() (Server, Server) {
appServer := Server{
BindAddress: l.HTTPAddress,
SecureBindAddress: l.HTTPSAddress,
}
if l.TLSKeyFile != "" || l.TLSCertFile != "" {
appServer.TLS = &TLS{
Key: &SecretSource{
FromFile: l.TLSKeyFile,
},
Cert: &SecretSource{
FromFile: l.TLSCertFile,
},
}
// Preserve backwards compatibility, only run one server
appServer.BindAddress = ""
} else {
// Disable the HTTPS server if there's no certificates.
// This preserves backwards compatibility.
appServer.SecureBindAddress = ""
}
metricsServer := Server{
BindAddress: l.MetricsAddress,
}
return appServer, metricsServer
}

View File

@ -106,6 +106,10 @@ var _ = Describe("Legacy Options", func() {
opts.InjectResponseHeaders = []Header{}
opts.Server = Server{
BindAddress: "127.0.0.1:4180",
}
converted, err := legacyOpts.ToOptions()
Expect(err).ToNot(HaveOccurred())
Expect(converted).To(Equal(opts))
@ -759,4 +763,93 @@ var _ = Describe("Legacy Options", func() {
}),
)
})
Context("Legacy Servers", func() {
type legacyServersTableInput struct {
legacyServer LegacyServer
expectedAppServer Server
expectedMetricsServer Server
}
const (
insecureAddr = "127.0.0.1:8080"
insecureMetricsAddr = ":9090"
secureAddr = ":443"
secureMetricsAddr = ":9443"
crtPath = "tls.crt"
keyPath = "tls.key"
)
var tlsConfig = &TLS{
Cert: &SecretSource{
FromFile: crtPath,
},
Key: &SecretSource{
FromFile: keyPath,
},
}
DescribeTable("should convert to app and metrics servers",
func(in legacyServersTableInput) {
appServer, metricsServer := in.legacyServer.convert()
Expect(appServer).To(Equal(in.expectedAppServer))
Expect(metricsServer).To(Equal(in.expectedMetricsServer))
},
Entry("with default options only starts app HTTP server", legacyServersTableInput{
legacyServer: LegacyServer{
HTTPAddress: insecureAddr,
HTTPSAddress: secureAddr,
},
expectedAppServer: Server{
BindAddress: insecureAddr,
},
}),
Entry("with TLS options specified only starts app HTTPS server", legacyServersTableInput{
legacyServer: LegacyServer{
HTTPAddress: insecureAddr,
HTTPSAddress: secureAddr,
TLSKeyFile: keyPath,
TLSCertFile: crtPath,
},
expectedAppServer: Server{
SecureBindAddress: secureAddr,
TLS: tlsConfig,
},
}),
Entry("with metrics HTTP and HTTPS addresses", legacyServersTableInput{
legacyServer: LegacyServer{
HTTPAddress: insecureAddr,
HTTPSAddress: secureAddr,
MetricsAddress: insecureMetricsAddr,
MetricsSecureAddress: secureMetricsAddr,
},
expectedAppServer: Server{
BindAddress: insecureAddr,
},
expectedMetricsServer: Server{
BindAddress: insecureMetricsAddr,
SecureBindAddress: secureMetricsAddr,
},
}),
Entry("with metrics HTTPS and tls cert/key", legacyServersTableInput{
legacyServer: LegacyServer{
HTTPAddress: insecureAddr,
HTTPSAddress: secureAddr,
MetricsAddress: insecureMetricsAddr,
MetricsSecureAddress: secureMetricsAddr,
MetricsTLSKeyFile: keyPath,
MetricsTLSCertFile: crtPath,
},
expectedAppServer: Server{
BindAddress: insecureAddr,
},
expectedMetricsServer: Server{
BindAddress: insecureMetricsAddr,
SecureBindAddress: secureMetricsAddr,
TLS: tlsConfig,
},
}),
)
})
})

View File

@ -22,9 +22,6 @@ type Options struct {
ProxyPrefix string `flag:"proxy-prefix" cfg:"proxy_prefix"`
PingPath string `flag:"ping-path" cfg:"ping_path"`
PingUserAgent string `flag:"ping-user-agent" cfg:"ping_user_agent"`
MetricsAddress string `flag:"metrics-address" cfg:"metrics_address"`
HTTPAddress string `flag:"http-address" cfg:"http_address"`
HTTPSAddress string `flag:"https-address" cfg:"https_address"`
ReverseProxy bool `flag:"reverse-proxy" cfg:"reverse_proxy"`
RealClientIPHeader string `flag:"real-client-ip-header" cfg:"real_client_ip_header"`
TrustedIPs []string `flag:"trusted-ip" cfg:"trusted_ips"`
@ -33,8 +30,6 @@ type Options struct {
ClientID string `flag:"client-id" cfg:"client_id"`
ClientSecret string `flag:"client-secret" cfg:"client_secret"`
ClientSecretFile string `flag:"client-secret-file" cfg:"client_secret_file"`
TLSCertFile string `flag:"tls-cert-file" cfg:"tls_cert_file"`
TLSKeyFile string `flag:"tls-key-file" cfg:"tls_key_file"`
AuthenticatedEmailsFile string `flag:"authenticated-emails-file" cfg:"authenticated_emails_file"`
KeycloakGroups []string `flag:"keycloak-group" cfg:"keycloak_groups"`
@ -68,6 +63,9 @@ type Options struct {
InjectRequestHeaders []Header `cfg:",internal"`
InjectResponseHeaders []Header `cfg:",internal"`
Server Server `cfg:",internal"`
MetricsServer Server `cfg:",internal"`
SkipAuthRegex []string `flag:"skip-auth-regex" cfg:"skip_auth_regex"`
SkipAuthRoutes []string `flag:"skip-auth-route" cfg:"skip_auth_routes"`
SkipJwtBearerTokens bool `flag:"skip-jwt-bearer-tokens" cfg:"skip_jwt_bearer_tokens"`
@ -136,10 +134,7 @@ func NewOptions() *Options {
return &Options{
ProxyPrefix: "/oauth2",
ProviderType: "google",
MetricsAddress: "",
PingPath: "/ping",
HTTPAddress: "127.0.0.1:4180",
HTTPSAddress: ":443",
RealClientIPHeader: "X-Real-IP",
ForceHTTPS: false,
Cookie: cookieDefaults(),
@ -162,14 +157,10 @@ func NewOptions() *Options {
func NewFlagSet() *pflag.FlagSet {
flagSet := pflag.NewFlagSet("oauth2-proxy", pflag.ExitOnError)
flagSet.String("http-address", "127.0.0.1:4180", "[http://]<addr>:<port> or unix://<path> to listen on for HTTP clients")
flagSet.String("https-address", ":443", "<addr>:<port> to listen on for HTTPS clients")
flagSet.Bool("reverse-proxy", false, "are we running behind a reverse proxy, controls whether headers like X-Real-Ip are accepted")
flagSet.String("real-client-ip-header", "X-Real-IP", "Header used to determine the real IP of the client (one of: X-Forwarded-For, X-Real-IP, or X-ProxyUser-IP)")
flagSet.StringSlice("trusted-ip", []string{}, "list of IPs or CIDR ranges to allow to bypass authentication. WARNING: trusting by IP has inherent security flaws, read the configuration documentation for more information.")
flagSet.Bool("force-https", false, "force HTTPS redirect for HTTP requests")
flagSet.String("tls-cert-file", "", "path to certificate file")
flagSet.String("tls-key-file", "", "path to private key file")
flagSet.String("redirect-url", "", "the OAuth Redirect URL. ie: \"https://internalapp.yourcompany.com/oauth2/callback\"")
flagSet.StringSlice("skip-auth-regex", []string{}, "(DEPRECATED for --skip-auth-route) bypass authentication for requests path's that match (may be given multiple times)")
flagSet.StringSlice("skip-auth-route", []string{}, "bypass authentication for requests that match the method & path. Format: method=path_regex OR path_regex alone for all methods")
@ -204,7 +195,6 @@ func NewFlagSet() *pflag.FlagSet {
flagSet.String("proxy-prefix", "/oauth2", "the url root path that this proxy should be nested under (e.g. /<oauth2>/sign_in)")
flagSet.String("ping-path", "/ping", "the ping endpoint that can be used for basic health checks")
flagSet.String("ping-user-agent", "", "special User-Agent that will be used for basic health checks")
flagSet.String("metrics-address", "", "the address /metrics will be served on (e.g. \":9100\")")
flagSet.String("session-store-type", "cookie", "the session storage provider to use")
flagSet.Bool("session-cookie-minimal", false, "strip OAuth tokens from cookie session stores if they aren't needed (cookie session store only)")
flagSet.String("redis-connection-url", "", "URL of redis server for redis session storage (eg: redis://HOST[:PORT])")

View File

@ -0,0 +1,27 @@
package options
// Server represents the configuration for an HTTP(S) server
type Server struct {
// BindAddress is the the address on which to serve traffic.
// Leave blank or set to "-" to disable.
BindAddress string
// SecureBindAddress is the the address on which to serve secure traffic.
// Leave blank or set to "-" to disable.
SecureBindAddress string
// TLS contains the information for loading the certificate and key for the
// secure traffic.
TLS *TLS
}
// TLS contains the information for loading a TLS certifcate and key.
type TLS struct {
// Key is the the TLS key data to use.
// Typically this will come from a file.
Key *SecretSource
// Cert is the TLS certificate data to use.
// Typically this will come from a file.
Cert *SecretSource
}