mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-29 22:46:12 +00:00
add loopback auth defaulting to generic apiserver
This commit is contained in:
parent
6846855929
commit
ab9a842f3c
@ -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",
|
||||
|
@ -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,
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user