wire up authenticating front proxy:

This commit is contained in:
deads2k 2016-10-24 12:49:44 -04:00
parent 557e653785
commit 3f9a4d51d5
11 changed files with 176 additions and 53 deletions

View File

@ -232,6 +232,7 @@ func Run(s *options.APIServer) error {
KeystoneURL: s.KeystoneURL, KeystoneURL: s.KeystoneURL,
WebhookTokenAuthnConfigFile: s.WebhookTokenAuthnConfigFile, WebhookTokenAuthnConfigFile: s.WebhookTokenAuthnConfigFile,
WebhookTokenAuthnCacheTTL: s.WebhookTokenAuthnCacheTTL, WebhookTokenAuthnCacheTTL: s.WebhookTokenAuthnCacheTTL,
RequestHeaderConfig: s.AuthenticationRequestHeaderConfig(),
}) })
if err != nil { if err != nil {

View File

@ -117,17 +117,18 @@ func Run(s *options.ServerRunOptions) error {
} }
apiAuthenticator, securityDefinitions, err := authenticator.New(authenticator.AuthenticatorConfig{ apiAuthenticator, securityDefinitions, err := authenticator.New(authenticator.AuthenticatorConfig{
Anonymous: s.AnonymousAuth, Anonymous: s.AnonymousAuth,
AnyToken: s.EnableAnyToken, AnyToken: s.EnableAnyToken,
BasicAuthFile: s.BasicAuthFile, BasicAuthFile: s.BasicAuthFile,
ClientCAFile: s.ClientCAFile, ClientCAFile: s.ClientCAFile,
TokenAuthFile: s.TokenAuthFile, TokenAuthFile: s.TokenAuthFile,
OIDCIssuerURL: s.OIDCIssuerURL, OIDCIssuerURL: s.OIDCIssuerURL,
OIDCClientID: s.OIDCClientID, OIDCClientID: s.OIDCClientID,
OIDCCAFile: s.OIDCCAFile, OIDCCAFile: s.OIDCCAFile,
OIDCUsernameClaim: s.OIDCUsernameClaim, OIDCUsernameClaim: s.OIDCUsernameClaim,
OIDCGroupsClaim: s.OIDCGroupsClaim, OIDCGroupsClaim: s.OIDCGroupsClaim,
KeystoneURL: s.KeystoneURL, KeystoneURL: s.KeystoneURL,
RequestHeaderConfig: s.AuthenticationRequestHeaderConfig(),
}) })
if err != nil { if err != nil {
glog.Fatalf("Invalid Authentication Config: %v", err) glog.Fatalf("Invalid Authentication Config: %v", err)

View File

@ -464,6 +464,9 @@ replication-controller-lookup-cache-size
repo-root repo-root
report-dir report-dir
report-prefix report-prefix
requestheader-allowed-names
requestheader-client-ca-file
requestheader-username-headers
require-kubeconfig require-kubeconfig
required-contexts required-contexts
resolv-conf resolv-conf

View File

@ -25,6 +25,7 @@ go_library(
"//plugin/pkg/auth/authenticator/password/passwordfile:go_default_library", "//plugin/pkg/auth/authenticator/password/passwordfile:go_default_library",
"//plugin/pkg/auth/authenticator/request/anonymous:go_default_library", "//plugin/pkg/auth/authenticator/request/anonymous:go_default_library",
"//plugin/pkg/auth/authenticator/request/basicauth:go_default_library", "//plugin/pkg/auth/authenticator/request/basicauth:go_default_library",
"//plugin/pkg/auth/authenticator/request/headerrequest:go_default_library",
"//plugin/pkg/auth/authenticator/request/union:go_default_library", "//plugin/pkg/auth/authenticator/request/union:go_default_library",
"//plugin/pkg/auth/authenticator/request/x509:go_default_library", "//plugin/pkg/auth/authenticator/request/x509:go_default_library",
"//plugin/pkg/auth/authenticator/token/anytoken:go_default_library", "//plugin/pkg/auth/authenticator/token/anytoken:go_default_library",

View File

@ -31,6 +31,7 @@ import (
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/password/passwordfile" "k8s.io/kubernetes/plugin/pkg/auth/authenticator/password/passwordfile"
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/anonymous" "k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/anonymous"
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/basicauth" "k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/basicauth"
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/headerrequest"
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/union" "k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/union"
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/x509" "k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/x509"
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/anytoken" "k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/anytoken"
@ -39,6 +40,15 @@ import (
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/webhook" "k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/webhook"
) )
type RequestHeaderConfig struct {
// UsernameHeaders are the headers to check (in order, case-insensitively) for an identity. The first header with a value wins.
UsernameHeaders []string
// ClientCA points to CA bundle file which is used verify the identity of the front proxy
ClientCA string
// AllowedClientNames is a list of common names that may be presented by the authenticating front proxy. Empty means: accept any.
AllowedClientNames []string
}
type AuthenticatorConfig struct { type AuthenticatorConfig struct {
Anonymous bool Anonymous bool
AnyToken bool AnyToken bool
@ -56,6 +66,8 @@ type AuthenticatorConfig struct {
KeystoneURL string KeystoneURL string
WebhookTokenAuthnConfigFile string WebhookTokenAuthnConfigFile string
WebhookTokenAuthnCacheTTL time.Duration WebhookTokenAuthnCacheTTL time.Duration
RequestHeaderConfig *RequestHeaderConfig
} }
// New returns an authenticator.Request or an error that supports the standard // New returns an authenticator.Request or an error that supports the standard
@ -66,7 +78,20 @@ func New(config AuthenticatorConfig) (authenticator.Request, *spec.SecurityDefin
hasBasicAuth := false hasBasicAuth := false
hasTokenAuth := false hasTokenAuth := false
// BasicAuth methods, local first, then remote // front-proxy, BasicAuth methods, local first, then remote
// Add the front proxy authenticator if requested
if config.RequestHeaderConfig != nil {
requestHeaderAuthenticator, err := headerrequest.NewSecure(
config.RequestHeaderConfig.ClientCA,
config.RequestHeaderConfig.AllowedClientNames,
config.RequestHeaderConfig.UsernameHeaders,
)
if err != nil {
return nil, nil, err
}
authenticators = append(authenticators, requestHeaderAuthenticator)
}
if len(config.BasicAuthFile) > 0 { if len(config.BasicAuthFile) > 0 {
basicAuth, err := newAuthenticatorFromBasicAuthFile(config.BasicAuthFile) basicAuth, err := newAuthenticatorFromBasicAuthFile(config.BasicAuthFile)
if err != nil { if err != nil {

View File

@ -13,6 +13,7 @@ load(
go_library( go_library(
name = "go_default_library", name = "go_default_library",
srcs = [ srcs = [
"authenticator.go",
"doc.go", "doc.go",
"etcd_options.go", "etcd_options.go",
"server_run_options.go", "server_run_options.go",
@ -23,6 +24,7 @@ go_library(
"//pkg/api:go_default_library", "//pkg/api:go_default_library",
"//pkg/api/unversioned:go_default_library", "//pkg/api/unversioned:go_default_library",
"//pkg/apimachinery/registered:go_default_library", "//pkg/apimachinery/registered:go_default_library",
"//pkg/apiserver/authenticator:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library", "//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/client/restclient:go_default_library", "//pkg/client/restclient:go_default_library",
"//pkg/storage/storagebackend:go_default_library", "//pkg/storage/storagebackend:go_default_library",

View File

@ -0,0 +1,35 @@
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package options
import (
"k8s.io/kubernetes/pkg/apiserver/authenticator"
)
// AuthenticationRequestHeaderConfig returns an authenticator config object for these options
// if necessary. nil otherwise.
func (s *ServerRunOptions) AuthenticationRequestHeaderConfig() *authenticator.RequestHeaderConfig {
if len(s.RequestHeaderUsernameHeaders) == 0 {
return nil
}
return &authenticator.RequestHeaderConfig{
UsernameHeaders: s.RequestHeaderUsernameHeaders,
ClientCA: s.RequestHeaderClientCAFile,
AllowedClientNames: s.RequestHeaderAllowedNames,
}
}

View File

@ -67,46 +67,49 @@ type ServerRunOptions struct {
AuthorizationWebhookCacheUnauthorizedTTL time.Duration AuthorizationWebhookCacheUnauthorizedTTL time.Duration
AuthorizationRBACSuperUser string AuthorizationRBACSuperUser string
AnonymousAuth bool AnonymousAuth bool
BasicAuthFile string BasicAuthFile string
BindAddress net.IP BindAddress net.IP
CertDirectory string CertDirectory string
ClientCAFile string ClientCAFile string
CloudConfigFile string CloudConfigFile string
CloudProvider string CloudProvider string
CorsAllowedOriginList []string CorsAllowedOriginList []string
DefaultStorageMediaType string DefaultStorageMediaType string
DeleteCollectionWorkers int DeleteCollectionWorkers int
AuditLogPath string AuditLogPath string
AuditLogMaxAge int AuditLogMaxAge int
AuditLogMaxBackups int AuditLogMaxBackups int
AuditLogMaxSize int AuditLogMaxSize int
EnableGarbageCollection bool EnableGarbageCollection bool
EnableProfiling bool EnableProfiling bool
EnableSwaggerUI bool EnableSwaggerUI bool
EnableWatchCache bool EnableWatchCache bool
EtcdServersOverrides []string EtcdServersOverrides []string
StorageConfig storagebackend.Config StorageConfig storagebackend.Config
ExternalHost string ExternalHost string
InsecureBindAddress net.IP InsecureBindAddress net.IP
InsecurePort int InsecurePort int
KeystoneURL string KeystoneURL string
KubernetesServiceNodePort int KubernetesServiceNodePort int
LongRunningRequestRE string LongRunningRequestRE string
MasterCount int MasterCount int
MasterServiceNamespace string MasterServiceNamespace string
MaxRequestsInFlight int MaxRequestsInFlight int
MinRequestTimeout int MinRequestTimeout int
OIDCCAFile string OIDCCAFile string
OIDCClientID string OIDCClientID string
OIDCIssuerURL string OIDCIssuerURL string
OIDCUsernameClaim string OIDCUsernameClaim string
OIDCGroupsClaim string OIDCGroupsClaim string
RuntimeConfig config.ConfigurationMap RequestHeaderUsernameHeaders []string
SecurePort int RequestHeaderClientCAFile string
ServiceClusterIPRange net.IPNet // TODO: make this a list RequestHeaderAllowedNames []string
ServiceNodePortRange utilnet.PortRange RuntimeConfig config.ConfigurationMap
StorageVersions string SecurePort int
ServiceClusterIPRange net.IPNet // TODO: make this a list
ServiceNodePortRange utilnet.PortRange
StorageVersions string
// The default values for StorageVersions. StorageVersions overrides // The default values for StorageVersions. StorageVersions overrides
// these; you can change this if you want to change the defaults (e.g., // these; you can change this if you want to change the defaults (e.g.,
// for testing). This is not actually exposed as a flag. // for testing). This is not actually exposed as a flag.
@ -423,6 +426,18 @@ func (s *ServerRunOptions) AddUniversalFlags(fs *pflag.FlagSet) {
"The claim value is expected to be a string or array of strings. This flag is experimental, "+ "The claim value is expected to be a string or array of strings. This flag is experimental, "+
"please see the authentication documentation for further details.") "please see the authentication documentation for further details.")
fs.StringSliceVar(&s.RequestHeaderUsernameHeaders, "requestheader-username-headers", s.RequestHeaderUsernameHeaders, ""+
"List of request headers to inspect for usernames. X-Remote-User is common.")
fs.StringVar(&s.RequestHeaderClientCAFile, "requestheader-client-ca-file", s.RequestHeaderClientCAFile, ""+
"Root certificate bundle to use to verify client certificates on incoming requests "+
"before trusting usernames in headers specified by --requestheader-username-headers")
fs.StringSliceVar(&s.RequestHeaderAllowedNames, "requestheader-allowed-names", s.RequestHeaderAllowedNames, ""+
"List of client certificate common names to allow to provide usernames in headers "+
"specified by --requestheader-username-headers. If empty, any client certificate validated "+
"by the authorities in --requestheader-client-ca-file is allowed.")
fs.Var(&s.RuntimeConfig, "runtime-config", ""+ fs.Var(&s.RuntimeConfig, "runtime-config", ""+
"A set of key=value pairs that describe runtime configuration that may be passed "+ "A set of key=value pairs that describe runtime configuration that may be passed "+
"to apiserver. apis/<groupVersion> key can be used to turn on/off specific api versions. "+ "to apiserver. apis/<groupVersion> key can be used to turn on/off specific api versions. "+

View File

@ -0,0 +1,32 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
"go_test",
"cgo_library",
)
go_library(
name = "go_default_library",
srcs = ["requestheader.go"],
tags = ["automanaged"],
deps = [
"//pkg/auth/authenticator:go_default_library",
"//pkg/auth/user:go_default_library",
"//pkg/util/cert:go_default_library",
"//pkg/util/sets:go_default_library",
"//plugin/pkg/auth/authenticator/request/x509:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = ["requestheader_test.go"],
library = "go_default_library",
tags = ["automanaged"],
deps = ["//pkg/auth/user:go_default_library"],
)

View File

@ -31,6 +31,7 @@ import (
) )
type requestHeaderAuthRequestHandler struct { type requestHeaderAuthRequestHandler struct {
// nameHeaders are the headers to check (in order, case-insensitively) for an identity. The first header with a value wins.
nameHeaders []string nameHeaders []string
} }

View File

@ -18,8 +18,11 @@ go_library(
], ],
tags = ["automanaged"], tags = ["automanaged"],
deps = [ deps = [
"//pkg/auth/authenticator:go_default_library",
"//pkg/auth/user:go_default_library", "//pkg/auth/user:go_default_library",
"//pkg/util/errors:go_default_library", "//pkg/util/errors:go_default_library",
"//pkg/util/sets:go_default_library",
"//vendor:github.com/golang/glog",
], ],
) )
@ -29,5 +32,9 @@ go_test(
data = glob(["testdata/*"]), data = glob(["testdata/*"]),
library = "go_default_library", library = "go_default_library",
tags = ["automanaged"], tags = ["automanaged"],
deps = ["//pkg/auth/user:go_default_library"], deps = [
"//pkg/auth/authenticator:go_default_library",
"//pkg/auth/user:go_default_library",
"//pkg/util/sets:go_default_library",
],
) )