Commit d3dbbfad authored by Darren Shepherd's avatar Darren Shepherd

Remove RequestHeader and ClientCerts auth

parent 7b622843
...@@ -264,27 +264,9 @@ func CreateKubeAPIServerConfig( ...@@ -264,27 +264,9 @@ func CreateKubeAPIServerConfig(
return return
} }
clientCA, lastErr := readCAorNil(s.Authentication.ClientCert.ClientCA)
if lastErr != nil {
return
}
requestHeaderProxyCA, lastErr := readCAorNil(s.Authentication.RequestHeader.ClientCAFile)
if lastErr != nil {
return
}
config = &master.Config{ config = &master.Config{
GenericConfig: genericConfig, GenericConfig: genericConfig,
ExtraConfig: master.ExtraConfig{ ExtraConfig: master.ExtraConfig{
ClientCARegistrationHook: master.ClientCARegistrationHook{
ClientCA: clientCA,
RequestHeaderUsernameHeaders: s.Authentication.RequestHeader.UsernameHeaders,
RequestHeaderGroupHeaders: s.Authentication.RequestHeader.GroupHeaders,
RequestHeaderExtraHeaderPrefixes: s.Authentication.RequestHeader.ExtraHeaderPrefixes,
RequestHeaderCA: requestHeaderProxyCA,
RequestHeaderAllowedNames: s.Authentication.RequestHeader.AllowedNames,
},
APIResourceConfigSource: storageFactory.APIResourceConfigSource, APIResourceConfigSource: storageFactory.APIResourceConfigSource,
StorageFactory: storageFactory, StorageFactory: storageFactory,
EventTTL: s.EventTTL, EventTTL: s.EventTTL,
......
...@@ -20,11 +20,9 @@ import ( ...@@ -20,11 +20,9 @@ import (
"time" "time"
"k8s.io/apiserver/pkg/authentication/authenticator" "k8s.io/apiserver/pkg/authentication/authenticator"
"k8s.io/apiserver/pkg/authentication/authenticatorfactory"
"k8s.io/apiserver/pkg/authentication/group" "k8s.io/apiserver/pkg/authentication/group"
"k8s.io/apiserver/pkg/authentication/request/anonymous" "k8s.io/apiserver/pkg/authentication/request/anonymous"
"k8s.io/apiserver/pkg/authentication/request/bearertoken" "k8s.io/apiserver/pkg/authentication/request/bearertoken"
"k8s.io/apiserver/pkg/authentication/request/headerrequest"
"k8s.io/apiserver/pkg/authentication/request/union" "k8s.io/apiserver/pkg/authentication/request/union"
"k8s.io/apiserver/pkg/authentication/request/websocket" "k8s.io/apiserver/pkg/authentication/request/websocket"
"k8s.io/apiserver/pkg/authentication/request/x509" "k8s.io/apiserver/pkg/authentication/request/x509"
...@@ -58,8 +56,6 @@ type Config struct { ...@@ -58,8 +56,6 @@ type Config struct {
TokenSuccessCacheTTL time.Duration TokenSuccessCacheTTL time.Duration
TokenFailureCacheTTL time.Duration TokenFailureCacheTTL time.Duration
RequestHeaderConfig *authenticatorfactory.RequestHeaderConfig
// TODO, this is the only non-serializable part of the entire config. Factor it out into a clientconfig // TODO, this is the only non-serializable part of the entire config. Factor it out into a clientconfig
ServiceAccountTokenGetter serviceaccount.ServiceAccountTokenGetter ServiceAccountTokenGetter serviceaccount.ServiceAccountTokenGetter
} }
...@@ -70,22 +66,6 @@ func (config Config) New() (authenticator.Request, error) { ...@@ -70,22 +66,6 @@ func (config Config) New() (authenticator.Request, error) {
var authenticators []authenticator.Request var authenticators []authenticator.Request
var tokenAuthenticators []authenticator.Token var tokenAuthenticators []authenticator.Token
// 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,
config.RequestHeaderConfig.GroupHeaders,
config.RequestHeaderConfig.ExtraHeaderPrefixes,
)
if err != nil {
return nil, err
}
authenticators = append(authenticators, authenticator.WrapAudienceAgnosticRequest(config.APIAudiences, requestHeaderAuthenticator))
}
// basic auth // basic auth
if len(config.BasicAuthFile) > 0 { if len(config.BasicAuthFile) > 0 {
basicAuth, err := newAuthenticatorFromBasicAuthFile(config.BasicAuthFile) basicAuth, err := newAuthenticatorFromBasicAuthFile(config.BasicAuthFile)
......
...@@ -28,7 +28,6 @@ import ( ...@@ -28,7 +28,6 @@ import (
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/authentication/authenticator" "k8s.io/apiserver/pkg/authentication/authenticator"
genericapiserver "k8s.io/apiserver/pkg/server" genericapiserver "k8s.io/apiserver/pkg/server"
genericoptions "k8s.io/apiserver/pkg/server/options"
kubeauthenticator "k8s.io/kubernetes/pkg/kubeapiserver/authenticator" kubeauthenticator "k8s.io/kubernetes/pkg/kubeapiserver/authenticator"
authzmodes "k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes" authzmodes "k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
) )
...@@ -36,9 +35,7 @@ import ( ...@@ -36,9 +35,7 @@ import (
type BuiltInAuthenticationOptions struct { type BuiltInAuthenticationOptions struct {
APIAudiences []string APIAudiences []string
Anonymous *AnonymousAuthenticationOptions Anonymous *AnonymousAuthenticationOptions
ClientCert *genericoptions.ClientCertAuthenticationOptions
PasswordFile *PasswordFileAuthenticationOptions PasswordFile *PasswordFileAuthenticationOptions
RequestHeader *genericoptions.RequestHeaderAuthenticationOptions
ServiceAccounts *ServiceAccountAuthenticationOptions ServiceAccounts *ServiceAccountAuthenticationOptions
TokenFile *TokenFileAuthenticationOptions TokenFile *TokenFileAuthenticationOptions
WebHook *WebHookAuthenticationOptions WebHook *WebHookAuthenticationOptions
...@@ -81,9 +78,7 @@ func NewBuiltInAuthenticationOptions() *BuiltInAuthenticationOptions { ...@@ -81,9 +78,7 @@ func NewBuiltInAuthenticationOptions() *BuiltInAuthenticationOptions {
func (s *BuiltInAuthenticationOptions) WithAll() *BuiltInAuthenticationOptions { func (s *BuiltInAuthenticationOptions) WithAll() *BuiltInAuthenticationOptions {
return s. return s.
WithAnonymous(). WithAnonymous().
WithClientCert().
WithPasswordFile(). WithPasswordFile().
WithRequestHeader().
WithServiceAccounts(). WithServiceAccounts().
WithTokenFile(). WithTokenFile().
WithWebHook() WithWebHook()
...@@ -94,21 +89,11 @@ func (s *BuiltInAuthenticationOptions) WithAnonymous() *BuiltInAuthenticationOpt ...@@ -94,21 +89,11 @@ func (s *BuiltInAuthenticationOptions) WithAnonymous() *BuiltInAuthenticationOpt
return s return s
} }
func (s *BuiltInAuthenticationOptions) WithClientCert() *BuiltInAuthenticationOptions {
s.ClientCert = &genericoptions.ClientCertAuthenticationOptions{}
return s
}
func (s *BuiltInAuthenticationOptions) WithPasswordFile() *BuiltInAuthenticationOptions { func (s *BuiltInAuthenticationOptions) WithPasswordFile() *BuiltInAuthenticationOptions {
s.PasswordFile = &PasswordFileAuthenticationOptions{} s.PasswordFile = &PasswordFileAuthenticationOptions{}
return s return s
} }
func (s *BuiltInAuthenticationOptions) WithRequestHeader() *BuiltInAuthenticationOptions {
s.RequestHeader = &genericoptions.RequestHeaderAuthenticationOptions{}
return s
}
func (s *BuiltInAuthenticationOptions) WithServiceAccounts() *BuiltInAuthenticationOptions { func (s *BuiltInAuthenticationOptions) WithServiceAccounts() *BuiltInAuthenticationOptions {
s.ServiceAccounts = &ServiceAccountAuthenticationOptions{Lookup: true} s.ServiceAccounts = &ServiceAccountAuthenticationOptions{Lookup: true}
return s return s
...@@ -153,20 +138,12 @@ func (s *BuiltInAuthenticationOptions) AddFlags(fs *pflag.FlagSet) { ...@@ -153,20 +138,12 @@ func (s *BuiltInAuthenticationOptions) AddFlags(fs *pflag.FlagSet) {
"Anonymous requests have a username of system:anonymous, and a group name of system:unauthenticated.") "Anonymous requests have a username of system:anonymous, and a group name of system:unauthenticated.")
} }
if s.ClientCert != nil {
s.ClientCert.AddFlags(fs)
}
if s.PasswordFile != nil { if s.PasswordFile != nil {
fs.StringVar(&s.PasswordFile.BasicAuthFile, "basic-auth-file", s.PasswordFile.BasicAuthFile, ""+ fs.StringVar(&s.PasswordFile.BasicAuthFile, "basic-auth-file", s.PasswordFile.BasicAuthFile, ""+
"If set, the file that will be used to admit requests to the secure port of the API server "+ "If set, the file that will be used to admit requests to the secure port of the API server "+
"via http basic authentication.") "via http basic authentication.")
} }
if s.RequestHeader != nil {
s.RequestHeader.AddFlags(fs)
}
if s.ServiceAccounts != nil { if s.ServiceAccounts != nil {
fs.StringArrayVar(&s.ServiceAccounts.KeyFiles, "service-account-key-file", s.ServiceAccounts.KeyFiles, ""+ fs.StringArrayVar(&s.ServiceAccounts.KeyFiles, "service-account-key-file", s.ServiceAccounts.KeyFiles, ""+
"File containing PEM-encoded x509 RSA or ECDSA private or public keys, used to verify "+ "File containing PEM-encoded x509 RSA or ECDSA private or public keys, used to verify "+
...@@ -219,19 +196,12 @@ func (s *BuiltInAuthenticationOptions) ToAuthenticationConfig() kubeauthenticato ...@@ -219,19 +196,12 @@ func (s *BuiltInAuthenticationOptions) ToAuthenticationConfig() kubeauthenticato
ret.Anonymous = s.Anonymous.Allow ret.Anonymous = s.Anonymous.Allow
} }
if s.ClientCert != nil {
ret.ClientCAFile = s.ClientCert.ClientCA
}
if s.PasswordFile != nil { if s.PasswordFile != nil {
ret.BasicAuthFile = s.PasswordFile.BasicAuthFile ret.BasicAuthFile = s.PasswordFile.BasicAuthFile
} }
if s.RequestHeader != nil {
ret.RequestHeaderConfig = s.RequestHeader.ToAuthenticationRequestHeaderConfig()
}
ret.APIAudiences = s.APIAudiences ret.APIAudiences = s.APIAudiences
if s.ServiceAccounts != nil { if s.ServiceAccounts != nil {
if s.ServiceAccounts.Issuer != "" && len(s.APIAudiences) == 0 { if s.ServiceAccounts.Issuer != "" && len(s.APIAudiences) == 0 {
ret.APIAudiences = authenticator.Audiences{s.ServiceAccounts.Issuer} ret.APIAudiences = authenticator.Audiences{s.ServiceAccounts.Issuer}
...@@ -267,18 +237,6 @@ func (o *BuiltInAuthenticationOptions) ApplyTo(c *genericapiserver.Config) error ...@@ -267,18 +237,6 @@ func (o *BuiltInAuthenticationOptions) ApplyTo(c *genericapiserver.Config) error
return nil return nil
} }
var err error
if o.ClientCert != nil {
if err = c.Authentication.ApplyClientCert(o.ClientCert.ClientCA, c.SecureServing); err != nil {
return fmt.Errorf("unable to load client CA file: %v", err)
}
}
if o.RequestHeader != nil {
if err = c.Authentication.ApplyClientCert(o.RequestHeader.ClientCAFile, c.SecureServing); err != nil {
return fmt.Errorf("unable to load client CA file: %v", err)
}
}
c.Authentication.SupportsBasicAuth = o.PasswordFile != nil && len(o.PasswordFile.BasicAuthFile) > 0 c.Authentication.SupportsBasicAuth = o.PasswordFile != nil && len(o.PasswordFile.BasicAuthFile) > 0
c.Authentication.APIAudiences = o.APIAudiences c.Authentication.APIAudiences = o.APIAudiences
......
/*
Copyright 2017 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 master
import (
"encoding/json"
"fmt"
"reflect"
"time"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/apimachinery/pkg/util/wait"
genericapiserver "k8s.io/apiserver/pkg/server"
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
)
type ClientCARegistrationHook struct {
ClientCA []byte
RequestHeaderUsernameHeaders []string
RequestHeaderGroupHeaders []string
RequestHeaderExtraHeaderPrefixes []string
RequestHeaderCA []byte
RequestHeaderAllowedNames []string
}
func (h ClientCARegistrationHook) PostStartHook(hookContext genericapiserver.PostStartHookContext) error {
// initializing CAs is important so that aggregated API servers can come up with "normal" config.
// We've seen lagging etcd before, so we want to retry this a few times before we decide to crashloop
// the API server on it.
err := wait.Poll(1*time.Second, 30*time.Second, func() (done bool, err error) {
// retry building the config since sometimes the server can be in an in-between state which caused
// some kind of auto detection failure as I recall from other post start hooks.
// TODO see if this is still true and fix the RBAC one too if it isn't.
client, err := corev1client.NewForConfig(hookContext.LoopbackClientConfig)
if err != nil {
utilruntime.HandleError(err)
return false, nil
}
return h.tryToWriteClientCAs(client)
})
// if we're never able to make it through initialization, kill the API server
if err != nil {
return fmt.Errorf("unable to initialize client CA configmap: %v", err)
}
return nil
}
// tryToWriteClientCAs is here for unit testing with a fake client. This is a wait.ConditionFunc so the bool
// indicates if the condition was met. True when its finished, false when it should retry.
func (h ClientCARegistrationHook) tryToWriteClientCAs(client corev1client.CoreV1Interface) (bool, error) {
if err := createNamespaceIfNeeded(client, metav1.NamespaceSystem); err != nil {
utilruntime.HandleError(err)
return false, nil
}
data := map[string]string{}
if len(h.ClientCA) > 0 {
data["client-ca-file"] = string(h.ClientCA)
}
if len(h.RequestHeaderCA) > 0 {
var err error
// encoding errors aren't going to get better, so just fail on them.
data["requestheader-username-headers"], err = jsonSerializeStringSlice(h.RequestHeaderUsernameHeaders)
if err != nil {
return false, err
}
data["requestheader-group-headers"], err = jsonSerializeStringSlice(h.RequestHeaderGroupHeaders)
if err != nil {
return false, err
}
data["requestheader-extra-headers-prefix"], err = jsonSerializeStringSlice(h.RequestHeaderExtraHeaderPrefixes)
if err != nil {
return false, err
}
data["requestheader-client-ca-file"] = string(h.RequestHeaderCA)
data["requestheader-allowed-names"], err = jsonSerializeStringSlice(h.RequestHeaderAllowedNames)
if err != nil {
return false, err
}
}
// write errors may work next time if we retry, so queue for retry
if err := writeConfigMap(client, "extension-apiserver-authentication", data); err != nil {
utilruntime.HandleError(err)
return false, nil
}
return true, nil
}
func jsonSerializeStringSlice(in []string) (string, error) {
out, err := json.Marshal(in)
if err != nil {
return "", err
}
return string(out), err
}
func writeConfigMap(client corev1client.ConfigMapsGetter, name string, data map[string]string) error {
existing, err := client.ConfigMaps(metav1.NamespaceSystem).Get(name, metav1.GetOptions{})
if apierrors.IsNotFound(err) {
_, err := client.ConfigMaps(metav1.NamespaceSystem).Create(&corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{Namespace: metav1.NamespaceSystem, Name: name},
Data: data,
})
return err
}
if err != nil {
return err
}
if !reflect.DeepEqual(existing.Data, data) {
existing.Data = data
_, err = client.ConfigMaps(metav1.NamespaceSystem).Update(existing)
}
return err
}
...@@ -90,8 +90,6 @@ const ( ...@@ -90,8 +90,6 @@ const (
) )
type ExtraConfig struct { type ExtraConfig struct {
ClientCARegistrationHook ClientCARegistrationHook
APIResourceConfigSource serverstorage.APIResourceConfigSource APIResourceConfigSource serverstorage.APIResourceConfigSource
StorageFactory serverstorage.StorageFactory StorageFactory serverstorage.StorageFactory
EndpointReconcilerConfig EndpointReconcilerConfig EndpointReconcilerConfig EndpointReconcilerConfig
...@@ -176,8 +174,6 @@ type EndpointReconcilerConfig struct { ...@@ -176,8 +174,6 @@ type EndpointReconcilerConfig struct {
// Master contains state for a Kubernetes cluster master/api server. // Master contains state for a Kubernetes cluster master/api server.
type Master struct { type Master struct {
GenericAPIServer *genericapiserver.GenericAPIServer GenericAPIServer *genericapiserver.GenericAPIServer
ClientCARegistrationHook ClientCARegistrationHook
} }
func (c *Config) createMasterCountReconciler() reconcilers.EndpointReconciler { func (c *Config) createMasterCountReconciler() reconcilers.EndpointReconciler {
...@@ -332,8 +328,6 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget) ...@@ -332,8 +328,6 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
} }
m.InstallAPIs(c.ExtraConfig.APIResourceConfigSource, c.GenericConfig.RESTOptionsGetter, restStorageProviders...) m.InstallAPIs(c.ExtraConfig.APIResourceConfigSource, c.GenericConfig.RESTOptionsGetter, restStorageProviders...)
m.GenericAPIServer.AddPostStartHookOrDie("ca-registration", c.ExtraConfig.ClientCARegistrationHook.PostStartHook)
return m, nil return m, nil
} }
......
...@@ -58,8 +58,6 @@ import ( ...@@ -58,8 +58,6 @@ import (
"k8s.io/apiserver/pkg/util/logs" "k8s.io/apiserver/pkg/util/logs"
"k8s.io/client-go/informers" "k8s.io/client-go/informers"
restclient "k8s.io/client-go/rest" restclient "k8s.io/client-go/rest"
certutil "k8s.io/client-go/util/cert"
// install apis // install apis
_ "k8s.io/apiserver/pkg/apis/apiserver/install" _ "k8s.io/apiserver/pkg/apis/apiserver/install"
) )
...@@ -284,25 +282,6 @@ func NewRecommendedConfig(codecs serializer.CodecFactory) *RecommendedConfig { ...@@ -284,25 +282,6 @@ func NewRecommendedConfig(codecs serializer.CodecFactory) *RecommendedConfig {
} }
} }
func (c *AuthenticationInfo) ApplyClientCert(clientCAFile string, servingInfo *SecureServingInfo) error {
if servingInfo != nil {
if len(clientCAFile) > 0 {
clientCAs, err := certutil.CertsFromFile(clientCAFile)
if err != nil {
return fmt.Errorf("unable to load client CA file: %v", err)
}
if servingInfo.ClientCA == nil {
servingInfo.ClientCA = x509.NewCertPool()
}
for _, cert := range clientCAs {
servingInfo.ClientCA.AddCert(cert)
}
}
}
return nil
}
type completedConfig struct { type completedConfig struct {
*Config *Config
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment