update delegating auth to include front-proxy

This commit is contained in:
deads2k 2016-12-05 13:46:25 -05:00
parent 4f625db133
commit fbb35b72ed
5 changed files with 59 additions and 23 deletions

View File

@ -96,14 +96,14 @@ func Run(s *options.ServerRunOptions) error {
genericapiserver.DefaultAndValidateRunOptions(s.GenericServerRunOptions) genericapiserver.DefaultAndValidateRunOptions(s.GenericServerRunOptions)
genericConfig, err := genericapiserver.NewConfig(). // create the new config genericConfig := genericapiserver.NewConfig(). // create the new config
ApplyOptions(s.GenericServerRunOptions). // apply the options selected ApplyOptions(s.GenericServerRunOptions). // apply the options selected
ApplyInsecureServingOptions(s.InsecureServing). ApplyInsecureServingOptions(s.InsecureServing)
ApplyAuthenticationOptions(s.Authentication).
ApplySecureServingOptions(s.SecureServing) if _, err := genericConfig.ApplySecureServingOptions(s.SecureServing); err != nil {
if err != nil {
return fmt.Errorf("failed to configure https: %s", err) return fmt.Errorf("failed to configure https: %s", err)
} }
genericConfig.ApplyAuthenticationOptions(s.Authentication)
capabilities.Initialize(capabilities.Capabilities{ capabilities.Initialize(capabilities.Capabilities{
AllowPrivileged: s.AllowPrivileged, AllowPrivileged: s.AllowPrivileged,

View File

@ -99,14 +99,14 @@ func (serverOptions *ServerRunOptions) Run(stopCh <-chan struct{}) error {
glog.Fatalf("Error creating self-signed certificates: %v", err) glog.Fatalf("Error creating self-signed certificates: %v", err)
} }
config, err := genericapiserver.NewConfig(). config := genericapiserver.NewConfig().
ApplyOptions(serverOptions.GenericServerRunOptions). ApplyOptions(serverOptions.GenericServerRunOptions).
ApplyInsecureServingOptions(serverOptions.InsecureServing). ApplyInsecureServingOptions(serverOptions.InsecureServing)
ApplyAuthenticationOptions(serverOptions.Authentication).
ApplySecureServingOptions(serverOptions.SecureServing) if _, err := config.ApplySecureServingOptions(serverOptions.SecureServing); err != nil {
if err != nil {
return fmt.Errorf("failed to configure https: %s", err) return fmt.Errorf("failed to configure https: %s", err)
} }
config.ApplyAuthenticationOptions(serverOptions.Authentication)
config.Authorizer = authorizer.NewAlwaysAllowAuthorizer() config.Authorizer = authorizer.NewAlwaysAllowAuthorizer()
s, err := config.Complete().New() s, err := config.Complete().New()

View File

@ -78,14 +78,14 @@ func Run(s *options.ServerRunOptions) error {
} }
genericapiserver.DefaultAndValidateRunOptions(s.GenericServerRunOptions) genericapiserver.DefaultAndValidateRunOptions(s.GenericServerRunOptions)
genericConfig, err := genericapiserver.NewConfig(). // create the new config genericConfig := genericapiserver.NewConfig(). // create the new config
ApplyOptions(s.GenericServerRunOptions). // apply the options selected ApplyOptions(s.GenericServerRunOptions). // apply the options selected
ApplyInsecureServingOptions(s.InsecureServing). ApplyInsecureServingOptions(s.InsecureServing)
ApplyAuthenticationOptions(s.Authentication).
ApplySecureServingOptions(s.SecureServing) if _, err := genericConfig.ApplySecureServingOptions(s.SecureServing); err != nil {
if err != nil {
return fmt.Errorf("failed to configure https: %s", err) return fmt.Errorf("failed to configure https: %s", err)
} }
genericConfig.ApplyAuthenticationOptions(s.Authentication)
// TODO: register cluster federation resources here. // TODO: register cluster federation resources here.
resourceConfig := genericapiserver.NewResourceConfig() resourceConfig := genericapiserver.NewResourceConfig()

View File

@ -30,6 +30,7 @@ import (
authenticationclient "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5/typed/authentication/v1beta1" authenticationclient "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5/typed/authentication/v1beta1"
"k8s.io/kubernetes/pkg/util/cert" "k8s.io/kubernetes/pkg/util/cert"
"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/headerrequest"
unionauth "k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/union" unionauth "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"
webhooktoken "k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/webhook" webhooktoken "k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/webhook"
@ -47,12 +48,30 @@ type DelegatingAuthenticatorConfig struct {
// ClientCAFile is the CA bundle file used to authenticate client certificates // ClientCAFile is the CA bundle file used to authenticate client certificates
ClientCAFile string ClientCAFile string
RequestHeaderConfig *RequestHeaderConfig
} }
func (c DelegatingAuthenticatorConfig) New() (authenticator.Request, *spec.SecurityDefinitions, error) { func (c DelegatingAuthenticatorConfig) New() (authenticator.Request, *spec.SecurityDefinitions, error) {
authenticators := []authenticator.Request{} authenticators := []authenticator.Request{}
securityDefinitions := spec.SecurityDefinitions{} securityDefinitions := spec.SecurityDefinitions{}
// front-proxy first, then remote
// Add the front proxy authenticator if requested
if c.RequestHeaderConfig != nil {
requestHeaderAuthenticator, err := headerrequest.NewSecure(
c.RequestHeaderConfig.ClientCA,
c.RequestHeaderConfig.AllowedClientNames,
c.RequestHeaderConfig.UsernameHeaders,
c.RequestHeaderConfig.GroupHeaders,
c.RequestHeaderConfig.ExtraHeaderPrefixes,
)
if err != nil {
return nil, nil, err
}
authenticators = append(authenticators, requestHeaderAuthenticator)
}
// x509 client cert auth // x509 client cert auth
if len(c.ClientCAFile) > 0 { if len(c.ClientCAFile) > 0 {
clientCAs, err := cert.NewPool(c.ClientCAFile) clientCAs, err := cert.NewPool(c.ClientCAFile)
@ -93,5 +112,4 @@ func (c DelegatingAuthenticatorConfig) New() (authenticator.Request, *spec.Secur
authenticator = unionauth.NewFailOnError(authenticator, anonymous.NewAuthenticator()) authenticator = unionauth.NewFailOnError(authenticator, anonymous.NewAuthenticator())
} }
return authenticator, &securityDefinitions, nil return authenticator, &securityDefinitions, nil
} }

View File

@ -350,7 +350,8 @@ func (s *ClientCertAuthenticationOptions) AddFlags(fs *pflag.FlagSet) {
} }
// DelegatingAuthenticationOptions provides an easy way for composing API servers to delegate their authentication to // DelegatingAuthenticationOptions provides an easy way for composing API servers to delegate their authentication to
// the root kube API server // the root kube API server. The API federator will act as
// a front proxy and direction connections will be able to delegate to the core kube API server
type DelegatingAuthenticationOptions struct { type DelegatingAuthenticationOptions struct {
// RemoteKubeConfigFile is the file to use to connect to a "normal" kube API server which hosts the // RemoteKubeConfigFile is the file to use to connect to a "normal" kube API server which hosts the
// TokenAccessReview.authentication.k8s.io endpoint for checking tokens. // TokenAccessReview.authentication.k8s.io endpoint for checking tokens.
@ -358,11 +359,21 @@ type DelegatingAuthenticationOptions struct {
// CacheTTL is the length of time that a token authentication answer will be cached. // CacheTTL is the length of time that a token authentication answer will be cached.
CacheTTL time.Duration CacheTTL time.Duration
ClientCert ClientCertAuthenticationOptions
RequestHeader RequestHeaderAuthenticationOptions
} }
func NewDelegatingAuthenticationOptions() *DelegatingAuthenticationOptions { func NewDelegatingAuthenticationOptions() *DelegatingAuthenticationOptions {
return &DelegatingAuthenticationOptions{ return &DelegatingAuthenticationOptions{
CacheTTL: 5 * time.Minute, // very low for responsiveness, but high enough to handle storms
CacheTTL: 10 * time.Second,
ClientCert: ClientCertAuthenticationOptions{},
RequestHeader: RequestHeaderAuthenticationOptions{
UsernameHeaders: []string{"x-remote-user"},
GroupHeaders: []string{"x-remote-group"},
ExtraHeaderPrefixes: []string{"x-remote-extra-"},
},
} }
} }
@ -374,10 +385,16 @@ func (s *DelegatingAuthenticationOptions) Validate() []error {
func (s *DelegatingAuthenticationOptions) AddFlags(fs *pflag.FlagSet) { func (s *DelegatingAuthenticationOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.RemoteKubeConfigFile, "authentication-kubeconfig", s.RemoteKubeConfigFile, ""+ fs.StringVar(&s.RemoteKubeConfigFile, "authentication-kubeconfig", s.RemoteKubeConfigFile, ""+
"kubeconfig file pointing at the 'core' kubernetes server with enough rights to create "+ "kubeconfig file pointing at the 'core' kubernetes server with enough rights to create "+
" tokenaccessreviews.authentication.k8s.io.") "tokenaccessreviews.authentication.k8s.io.")
fs.DurationVar(&s.CacheTTL, "authentication-token-webhook-cache-ttl", s.CacheTTL,
"The duration to cache responses from the webhook token authenticator.")
s.ClientCert.AddFlags(fs)
s.RequestHeader.AddFlags(fs)
} }
func (s *DelegatingAuthenticationOptions) ToAuthenticationConfig(clientCAFile string) (authenticator.DelegatingAuthenticatorConfig, error) { func (s *DelegatingAuthenticationOptions) ToAuthenticationConfig() (authenticator.DelegatingAuthenticatorConfig, error) {
tokenClient, err := s.newTokenAccessReview() tokenClient, err := s.newTokenAccessReview()
if err != nil { if err != nil {
return authenticator.DelegatingAuthenticatorConfig{}, err return authenticator.DelegatingAuthenticatorConfig{}, err
@ -387,7 +404,8 @@ func (s *DelegatingAuthenticationOptions) ToAuthenticationConfig(clientCAFile st
Anonymous: true, Anonymous: true,
TokenAccessReviewClient: tokenClient, TokenAccessReviewClient: tokenClient,
CacheTTL: s.CacheTTL, CacheTTL: s.CacheTTL,
ClientCAFile: clientCAFile, ClientCAFile: s.ClientCert.ClientCA,
RequestHeaderConfig: s.RequestHeader.ToAuthenticationRequestHeaderConfig(),
} }
return ret, nil return ret, nil
} }