add loopback auth defaulting to generic apiserver

This commit is contained in:
deads2k 2016-11-10 14:42:00 -05:00
parent 6846855929
commit ab9a842f3c
9 changed files with 56 additions and 68 deletions

View File

@ -26,8 +26,6 @@ go_library(
"//pkg/apis/extensions:go_default_library",
"//pkg/apiserver:go_default_library",
"//pkg/apiserver/authenticator:go_default_library",
"//pkg/auth/authorizer/union:go_default_library",
"//pkg/auth/user:go_default_library",
"//pkg/capabilities:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/cloudprovider:go_default_library",
@ -64,7 +62,6 @@ go_library(
"//plugin/pkg/admission/securitycontext/scdeny:go_default_library",
"//plugin/pkg/admission/serviceaccount:go_default_library",
"//plugin/pkg/admission/storageclass/default:go_default_library",
"//plugin/pkg/auth/authenticator/request/union:go_default_library",
"//vendor:github.com/golang/glog",
"//vendor:github.com/pborman/uuid",
"//vendor:github.com/spf13/cobra",

View File

@ -41,8 +41,6 @@ import (
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/apiserver"
"k8s.io/kubernetes/pkg/apiserver/authenticator"
authorizerunion "k8s.io/kubernetes/pkg/auth/authorizer/union"
"k8s.io/kubernetes/pkg/auth/user"
"k8s.io/kubernetes/pkg/capabilities"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/cloudprovider"
@ -59,7 +57,6 @@ import (
utilnet "k8s.io/kubernetes/pkg/util/net"
"k8s.io/kubernetes/pkg/util/wait"
"k8s.io/kubernetes/pkg/version"
authenticatorunion "k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/union"
)
// NewAPIServerCommand creates a *cobra.Command object with default parameters
@ -94,8 +91,7 @@ func Run(s *options.ServerRunOptions) error {
ApplySecureServingOptions(s.SecureServing).
ApplyInsecureServingOptions(s.InsecureServing).
ApplyAuthenticationOptions(s.Authentication).
ApplyRBACSuperUser(s.Authorization.RBACSuperUser).
Complete() // set default values based on the known values
ApplyRBACSuperUser(s.Authorization.RBACSuperUser)
serviceIPRange, apiServerServiceIP, err := genericapiserver.DefaultServiceIPRange(s.GenericServerRunOptions.ServiceClusterIPRange)
if err != nil {
@ -253,26 +249,7 @@ func Run(s *options.ServerRunOptions) error {
}
admissionControlPluginNames := strings.Split(s.GenericServerRunOptions.AdmissionControl, ",")
// TODO(dims): We probably need to add an option "EnableLoopbackToken"
if apiAuthenticator != nil {
var uid = uuid.NewRandom().String()
tokens := make(map[string]*user.DefaultInfo)
tokens[privilegedLoopbackToken] = &user.DefaultInfo{
Name: user.APIServerUser,
UID: uid,
Groups: []string{user.SystemPrivilegedGroup},
}
tokenAuthenticator := authenticator.NewAuthenticatorFromTokens(tokens)
apiAuthenticator = authenticatorunion.New(tokenAuthenticator, apiAuthenticator)
tokenAuthorizer := authorizer.NewPrivilegedGroups(user.SystemPrivilegedGroup)
apiAuthorizer = authorizerunion.New(tokenAuthorizer, apiAuthorizer)
}
pluginInitializer := admission.NewPluginInitializer(sharedInformers, apiAuthorizer)
admissionController, err := admission.NewFromPlugins(client, admissionControlPluginNames, s.GenericServerRunOptions.AdmissionControlConfigFile, pluginInitializer)
if err != nil {
glog.Fatalf("Failed to initialize plugins: %v", err)
@ -297,7 +274,7 @@ func Run(s *options.ServerRunOptions) error {
genericConfig.OpenAPIConfig.SecurityDefinitions = securityDefinitions
config := &master.Config{
GenericConfig: genericConfig.Config,
GenericConfig: genericConfig,
StorageFactory: storageFactory,
EnableWatchCache: s.GenericServerRunOptions.EnableWatchCache,

View File

@ -36,8 +36,6 @@ go_library(
"//pkg/apis/extensions:go_default_library",
"//pkg/apis/extensions/install:go_default_library",
"//pkg/apiserver/authenticator:go_default_library",
"//pkg/auth/authorizer/union:go_default_library",
"//pkg/auth/user:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/cloudprovider/providers:go_default_library",
"//pkg/controller/informers:go_default_library",
@ -66,7 +64,6 @@ go_library(
"//plugin/pkg/admission/deny:go_default_library",
"//plugin/pkg/admission/gc:go_default_library",
"//plugin/pkg/admission/namespace/lifecycle:go_default_library",
"//plugin/pkg/auth/authenticator/request/union:go_default_library",
"//vendor:github.com/golang/glog",
"//vendor:github.com/pborman/uuid",
"//vendor:github.com/spf13/cobra",

View File

@ -32,8 +32,6 @@ import (
"k8s.io/kubernetes/pkg/admission"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apiserver/authenticator"
authorizerunion "k8s.io/kubernetes/pkg/auth/authorizer/union"
"k8s.io/kubernetes/pkg/auth/user"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/controller/informers"
"k8s.io/kubernetes/pkg/generated/openapi"
@ -48,7 +46,6 @@ import (
utilerrors "k8s.io/kubernetes/pkg/util/errors"
"k8s.io/kubernetes/pkg/util/wait"
"k8s.io/kubernetes/pkg/version"
authenticatorunion "k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/union"
)
// NewAPIServerCommand creates a *cobra.Command object with default parameters
@ -82,8 +79,7 @@ func Run(s *options.ServerRunOptions) error {
ApplySecureServingOptions(s.SecureServing).
ApplyInsecureServingOptions(s.InsecureServing).
ApplyAuthenticationOptions(s.Authentication).
ApplyRBACSuperUser(s.Authorization.RBACSuperUser).
Complete() // set default values based on the known values
ApplyRBACSuperUser(s.Authorization.RBACSuperUser)
if err := genericConfig.MaybeGenerateServingCerts(); err != nil {
glog.Fatalf("Failed to generate service certificate: %v", err)
@ -151,26 +147,7 @@ func Run(s *options.ServerRunOptions) error {
}
admissionControlPluginNames := strings.Split(s.GenericServerRunOptions.AdmissionControl, ",")
// TODO(dims): We probably need to add an option "EnableLoopbackToken"
if apiAuthenticator != nil {
var uid = uuid.NewRandom().String()
tokens := make(map[string]*user.DefaultInfo)
tokens[privilegedLoopbackToken] = &user.DefaultInfo{
Name: user.APIServerUser,
UID: uid,
Groups: []string{user.SystemPrivilegedGroup},
}
tokenAuthenticator := authenticator.NewAuthenticatorFromTokens(tokens)
apiAuthenticator = authenticatorunion.New(tokenAuthenticator, apiAuthenticator)
tokenAuthorizer := authorizer.NewPrivilegedGroups(user.SystemPrivilegedGroup)
apiAuthorizer = authorizerunion.New(tokenAuthorizer, apiAuthorizer)
}
pluginInitializer := admission.NewPluginInitializer(sharedInformers, apiAuthorizer)
admissionController, err := admission.NewFromPlugins(client, admissionControlPluginNames, s.GenericServerRunOptions.AdmissionControlConfigFile, pluginInitializer)
if err != nil {
glog.Fatalf("Failed to initialize plugins: %v", err)
@ -193,7 +170,7 @@ func Run(s *options.ServerRunOptions) error {
cachesize.SetWatchCacheSizes(s.GenericServerRunOptions.WatchCacheSizes)
}
m, err := genericConfig.New()
m, err := genericConfig.Complete().New()
if err != nil {
return err
}

View File

@ -38,14 +38,18 @@ go_library(
"//pkg/apimachinery:go_default_library",
"//pkg/apimachinery/registered:go_default_library",
"//pkg/apiserver:go_default_library",
"//pkg/apiserver/authenticator:go_default_library",
"//pkg/apiserver/filters:go_default_library",
"//pkg/apiserver/openapi:go_default_library",
"//pkg/apiserver/request:go_default_library",
"//pkg/auth/authenticator:go_default_library",
"//pkg/auth/authorizer:go_default_library",
"//pkg/auth/authorizer/union:go_default_library",
"//pkg/auth/handlers:go_default_library",
"//pkg/auth/user:go_default_library",
"//pkg/client/restclient:go_default_library",
"//pkg/cloudprovider:go_default_library",
"//pkg/genericapiserver/authorizer:go_default_library",
"//pkg/genericapiserver/filters:go_default_library",
"//pkg/genericapiserver/mux:go_default_library",
"//pkg/genericapiserver/openapi/common:go_default_library",
@ -70,10 +74,12 @@ go_library(
"//pkg/util/validation:go_default_library",
"//pkg/util/wait:go_default_library",
"//pkg/version:go_default_library",
"//plugin/pkg/auth/authenticator/request/union:go_default_library",
"//vendor:github.com/coreos/go-systemd/daemon",
"//vendor:github.com/emicklei/go-restful",
"//vendor:github.com/go-openapi/spec",
"//vendor:github.com/golang/glog",
"//vendor:github.com/pborman/uuid",
"//vendor:github.com/pkg/errors",
"//vendor:github.com/prometheus/client_golang/prometheus",
"//vendor:gopkg.in/natefinch/lumberjack.v2",

View File

@ -25,7 +25,7 @@ import (
)
// DelegatingAuthorizerConfig is the minimal configuration needed to create an authenticator
// built to delegate authentication to a kube API server
// built to delegate authorization to a kube API server
type DelegatingAuthorizerConfig struct {
SubjectAccessReviewClient authorizationclient.SubjectAccessReviewInterface

View File

@ -32,20 +32,25 @@ import (
"github.com/go-openapi/spec"
"github.com/golang/glog"
"github.com/pborman/uuid"
"gopkg.in/natefinch/lumberjack.v2"
"k8s.io/kubernetes/pkg/admission"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/v1"
apiserverauthenticator "k8s.io/kubernetes/pkg/apiserver/authenticator"
apiserverfilters "k8s.io/kubernetes/pkg/apiserver/filters"
apiserveropenapi "k8s.io/kubernetes/pkg/apiserver/openapi"
"k8s.io/kubernetes/pkg/apiserver/request"
"k8s.io/kubernetes/pkg/auth/authenticator"
"k8s.io/kubernetes/pkg/auth/authorizer"
authorizerunion "k8s.io/kubernetes/pkg/auth/authorizer/union"
authhandlers "k8s.io/kubernetes/pkg/auth/handlers"
"k8s.io/kubernetes/pkg/auth/user"
"k8s.io/kubernetes/pkg/client/restclient"
"k8s.io/kubernetes/pkg/cloudprovider"
apiserverauthorizer "k8s.io/kubernetes/pkg/genericapiserver/authorizer"
genericfilters "k8s.io/kubernetes/pkg/genericapiserver/filters"
"k8s.io/kubernetes/pkg/genericapiserver/mux"
"k8s.io/kubernetes/pkg/genericapiserver/openapi/common"
@ -56,6 +61,7 @@ import (
certutil "k8s.io/kubernetes/pkg/util/cert"
"k8s.io/kubernetes/pkg/util/sets"
"k8s.io/kubernetes/pkg/version"
authenticatorunion "k8s.io/kubernetes/plugin/pkg/auth/authenticator/request/union"
)
const (
@ -360,6 +366,25 @@ func (c *Config) Complete() completedConfig {
c.DiscoveryAddresses = DefaultDiscoveryAddresses{DefaultAddress: c.ExternalAddress}
}
// If the loopbackclientconfig is specified AND it has a token for use against the API server
// wrap the authenticator and authorizer in loopback authentication logic
if c.Authenticator != nil && c.Authorizer != nil && c.LoopbackClientConfig != nil && len(c.LoopbackClientConfig.BearerToken) > 0 {
privilegedLoopbackToken := c.LoopbackClientConfig.BearerToken
var uid = uuid.NewRandom().String()
tokens := make(map[string]*user.DefaultInfo)
tokens[privilegedLoopbackToken] = &user.DefaultInfo{
Name: user.APIServerUser,
UID: uid,
Groups: []string{user.SystemPrivilegedGroup},
}
tokenAuthenticator := apiserverauthenticator.NewAuthenticatorFromTokens(tokens)
c.Authenticator = authenticatorunion.New(tokenAuthenticator, c.Authenticator)
tokenAuthorizer := apiserverauthorizer.NewPrivilegedGroups(user.SystemPrivilegedGroup)
c.Authorizer = authorizerunion.New(tokenAuthorizer, c.Authorizer)
}
return completedConfig{c}
}
@ -428,7 +453,7 @@ func (c completedConfig) New() (*GenericAPIServer, error) {
}
// MaybeGenerateServingCerts generates serving certificates if requested and needed.
func (c completedConfig) MaybeGenerateServingCerts(alternateIPs ...net.IP) error {
func (c *Config) MaybeGenerateServingCerts(alternateIPs ...net.IP) error {
// It would be nice to set a fqdn subject alt name, but only the kubelets know, the apiserver is clueless
// alternateDNS = append(alternateDNS, "kubernetes.default.svc.CLUSTER.DNS.NAME")
if c.SecureServingInfo != nil && c.SecureServingInfo.ServerCert.Generate && !certutil.CanReadCertOrKey(c.SecureServingInfo.ServerCert.CertFile, c.SecureServingInfo.ServerCert.KeyFile) {

View File

@ -313,7 +313,7 @@ func (s *RequestHeaderAuthenticationOptions) AuthenticationRequestHeaderConfig()
// the root kube API server
type DelegatingAuthenticationOptions struct {
// RemoteKubeConfigFile is the file to use to connect to a "normal" kube API server which hosts the
// TokenAcessReview.authentication.k8s.io endpoint for checking tokens.
// TokenAccessReview.authentication.k8s.io endpoint for checking tokens.
RemoteKubeConfigFile string
// CacheTTL is the length of time that a token authentication answer will be cached.
@ -334,7 +334,7 @@ func (s *DelegatingAuthenticationOptions) Validate() []error {
func (s *DelegatingAuthenticationOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.RemoteKubeConfigFile, "authentication-kubeconfig", s.RemoteKubeConfigFile, ""+
"kubeconfig file pointing at the 'core' kubernetes server with enough rights to create "+
" tokenaccessreviews.authencation.k8s.io.")
" tokenaccessreviews.authentication.k8s.io.")
}
func (s *DelegatingAuthenticationOptions) ToAuthenticationConfig(clientCAFile string) (authenticator.DelegatingAuthenticatorConfig, error) {
@ -357,14 +357,16 @@ func (s *DelegatingAuthenticationOptions) newTokenAccessReview() (authentication
return nil, nil
}
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
loadingRules.ExplicitPath = s.RemoteKubeConfigFile
loadingRules := &clientcmd.ClientConfigLoadingRules{ExplicitPath: s.RemoteKubeConfigFile}
loader := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &clientcmd.ConfigOverrides{})
clientConfig, err := loader.ClientConfig()
if err != nil {
return nil, err
}
// set high qps/burst limits since this will effectively limit API server responsiveness
clientConfig.QPS = 200
clientConfig.Burst = 400
client, err := authenticationclient.NewForConfig(clientConfig)
if err != nil {

View File

@ -79,8 +79,13 @@ func (s *BuiltInAuthorizationOptions) AddFlags(fs *pflag.FlagSet) {
}
func (s *BuiltInAuthorizationOptions) ToAuthorizationConfig(informerFactory informers.SharedInformerFactory) authorizer.AuthorizationConfig {
modes := []string{}
if len(s.Mode) > 0 {
modes = strings.Split(s.Mode, ",")
}
return authorizer.AuthorizationConfig{
AuthorizationModes: strings.Split(s.Mode, ","),
AuthorizationModes: modes,
PolicyFile: s.PolicyFile,
WebhookConfigFile: s.WebhookConfigFile,
WebhookCacheAuthorizedTTL: s.WebhookCacheAuthorizedTTL,
@ -94,7 +99,7 @@ func (s *BuiltInAuthorizationOptions) ToAuthorizationConfig(informerFactory info
// the root kube API server
type DelegatingAuthorizationOptions struct {
// RemoteKubeConfigFile is the file to use to connect to a "normal" kube API server which hosts the
// TokenAcessReview.authentication.k8s.io endpoint for checking tokens.
// SubjectAccessReview.authorization.k8s.io endpoint for checking tokens.
RemoteKubeConfigFile string
// AllowCacheTTL is the length of time that a successful authorization response will be cached
@ -124,13 +129,13 @@ func (s *DelegatingAuthorizationOptions) AddFlags(fs *pflag.FlagSet) {
}
func (s *DelegatingAuthorizationOptions) ToAuthorizationConfig() (authorizer.DelegatingAuthorizerConfig, error) {
tokenClient, err := s.newSubjectAccessReview()
sarClient, err := s.newSubjectAccessReview()
if err != nil {
return authorizer.DelegatingAuthorizerConfig{}, err
}
ret := authorizer.DelegatingAuthorizerConfig{
SubjectAccessReviewClient: tokenClient,
SubjectAccessReviewClient: sarClient,
AllowCacheTTL: s.AllowCacheTTL,
DenyCacheTTL: s.DenyCacheTTL,
}
@ -142,14 +147,16 @@ func (s *DelegatingAuthorizationOptions) newSubjectAccessReview() (authorization
return nil, nil
}
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
loadingRules.ExplicitPath = s.RemoteKubeConfigFile
loadingRules := &clientcmd.ClientConfigLoadingRules{ExplicitPath: s.RemoteKubeConfigFile}
loader := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &clientcmd.ConfigOverrides{})
clientConfig, err := loader.ClientConfig()
if err != nil {
return nil, err
}
// set high qps/burst limits since this will effectively limit API server responsiveness
clientConfig.QPS = 200
clientConfig.Burst = 400
client, err := authorizationclient.NewForConfig(clientConfig)
if err != nil {