mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 19:31:44 +00:00
wire up authenticating front proxy:
This commit is contained in:
parent
557e653785
commit
3f9a4d51d5
@ -232,6 +232,7 @@ func Run(s *options.APIServer) error {
|
||||
KeystoneURL: s.KeystoneURL,
|
||||
WebhookTokenAuthnConfigFile: s.WebhookTokenAuthnConfigFile,
|
||||
WebhookTokenAuthnCacheTTL: s.WebhookTokenAuthnCacheTTL,
|
||||
RequestHeaderConfig: s.AuthenticationRequestHeaderConfig(),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
@ -117,17 +117,18 @@ func Run(s *options.ServerRunOptions) error {
|
||||
}
|
||||
|
||||
apiAuthenticator, securityDefinitions, err := authenticator.New(authenticator.AuthenticatorConfig{
|
||||
Anonymous: s.AnonymousAuth,
|
||||
AnyToken: s.EnableAnyToken,
|
||||
BasicAuthFile: s.BasicAuthFile,
|
||||
ClientCAFile: s.ClientCAFile,
|
||||
TokenAuthFile: s.TokenAuthFile,
|
||||
OIDCIssuerURL: s.OIDCIssuerURL,
|
||||
OIDCClientID: s.OIDCClientID,
|
||||
OIDCCAFile: s.OIDCCAFile,
|
||||
OIDCUsernameClaim: s.OIDCUsernameClaim,
|
||||
OIDCGroupsClaim: s.OIDCGroupsClaim,
|
||||
KeystoneURL: s.KeystoneURL,
|
||||
Anonymous: s.AnonymousAuth,
|
||||
AnyToken: s.EnableAnyToken,
|
||||
BasicAuthFile: s.BasicAuthFile,
|
||||
ClientCAFile: s.ClientCAFile,
|
||||
TokenAuthFile: s.TokenAuthFile,
|
||||
OIDCIssuerURL: s.OIDCIssuerURL,
|
||||
OIDCClientID: s.OIDCClientID,
|
||||
OIDCCAFile: s.OIDCCAFile,
|
||||
OIDCUsernameClaim: s.OIDCUsernameClaim,
|
||||
OIDCGroupsClaim: s.OIDCGroupsClaim,
|
||||
KeystoneURL: s.KeystoneURL,
|
||||
RequestHeaderConfig: s.AuthenticationRequestHeaderConfig(),
|
||||
})
|
||||
if err != nil {
|
||||
glog.Fatalf("Invalid Authentication Config: %v", err)
|
||||
|
@ -464,6 +464,9 @@ replication-controller-lookup-cache-size
|
||||
repo-root
|
||||
report-dir
|
||||
report-prefix
|
||||
requestheader-allowed-names
|
||||
requestheader-client-ca-file
|
||||
requestheader-username-headers
|
||||
require-kubeconfig
|
||||
required-contexts
|
||||
resolv-conf
|
||||
|
@ -25,6 +25,7 @@ go_library(
|
||||
"//plugin/pkg/auth/authenticator/password/passwordfile: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/headerrequest: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/token/anytoken:go_default_library",
|
||||
|
@ -31,6 +31,7 @@ import (
|
||||
"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/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/x509"
|
||||
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/anytoken"
|
||||
@ -39,6 +40,15 @@ import (
|
||||
"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 {
|
||||
Anonymous bool
|
||||
AnyToken bool
|
||||
@ -56,6 +66,8 @@ type AuthenticatorConfig struct {
|
||||
KeystoneURL string
|
||||
WebhookTokenAuthnConfigFile string
|
||||
WebhookTokenAuthnCacheTTL time.Duration
|
||||
|
||||
RequestHeaderConfig *RequestHeaderConfig
|
||||
}
|
||||
|
||||
// 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
|
||||
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 {
|
||||
basicAuth, err := newAuthenticatorFromBasicAuthFile(config.BasicAuthFile)
|
||||
if err != nil {
|
||||
|
@ -13,6 +13,7 @@ load(
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"authenticator.go",
|
||||
"doc.go",
|
||||
"etcd_options.go",
|
||||
"server_run_options.go",
|
||||
@ -23,6 +24,7 @@ go_library(
|
||||
"//pkg/api:go_default_library",
|
||||
"//pkg/api/unversioned: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/restclient:go_default_library",
|
||||
"//pkg/storage/storagebackend:go_default_library",
|
||||
|
35
pkg/genericapiserver/options/authenticator.go
Normal file
35
pkg/genericapiserver/options/authenticator.go
Normal 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,
|
||||
}
|
||||
}
|
@ -67,46 +67,49 @@ type ServerRunOptions struct {
|
||||
AuthorizationWebhookCacheUnauthorizedTTL time.Duration
|
||||
AuthorizationRBACSuperUser string
|
||||
|
||||
AnonymousAuth bool
|
||||
BasicAuthFile string
|
||||
BindAddress net.IP
|
||||
CertDirectory string
|
||||
ClientCAFile string
|
||||
CloudConfigFile string
|
||||
CloudProvider string
|
||||
CorsAllowedOriginList []string
|
||||
DefaultStorageMediaType string
|
||||
DeleteCollectionWorkers int
|
||||
AuditLogPath string
|
||||
AuditLogMaxAge int
|
||||
AuditLogMaxBackups int
|
||||
AuditLogMaxSize int
|
||||
EnableGarbageCollection bool
|
||||
EnableProfiling bool
|
||||
EnableSwaggerUI bool
|
||||
EnableWatchCache bool
|
||||
EtcdServersOverrides []string
|
||||
StorageConfig storagebackend.Config
|
||||
ExternalHost string
|
||||
InsecureBindAddress net.IP
|
||||
InsecurePort int
|
||||
KeystoneURL string
|
||||
KubernetesServiceNodePort int
|
||||
LongRunningRequestRE string
|
||||
MasterCount int
|
||||
MasterServiceNamespace string
|
||||
MaxRequestsInFlight int
|
||||
MinRequestTimeout int
|
||||
OIDCCAFile string
|
||||
OIDCClientID string
|
||||
OIDCIssuerURL string
|
||||
OIDCUsernameClaim string
|
||||
OIDCGroupsClaim string
|
||||
RuntimeConfig config.ConfigurationMap
|
||||
SecurePort int
|
||||
ServiceClusterIPRange net.IPNet // TODO: make this a list
|
||||
ServiceNodePortRange utilnet.PortRange
|
||||
StorageVersions string
|
||||
AnonymousAuth bool
|
||||
BasicAuthFile string
|
||||
BindAddress net.IP
|
||||
CertDirectory string
|
||||
ClientCAFile string
|
||||
CloudConfigFile string
|
||||
CloudProvider string
|
||||
CorsAllowedOriginList []string
|
||||
DefaultStorageMediaType string
|
||||
DeleteCollectionWorkers int
|
||||
AuditLogPath string
|
||||
AuditLogMaxAge int
|
||||
AuditLogMaxBackups int
|
||||
AuditLogMaxSize int
|
||||
EnableGarbageCollection bool
|
||||
EnableProfiling bool
|
||||
EnableSwaggerUI bool
|
||||
EnableWatchCache bool
|
||||
EtcdServersOverrides []string
|
||||
StorageConfig storagebackend.Config
|
||||
ExternalHost string
|
||||
InsecureBindAddress net.IP
|
||||
InsecurePort int
|
||||
KeystoneURL string
|
||||
KubernetesServiceNodePort int
|
||||
LongRunningRequestRE string
|
||||
MasterCount int
|
||||
MasterServiceNamespace string
|
||||
MaxRequestsInFlight int
|
||||
MinRequestTimeout int
|
||||
OIDCCAFile string
|
||||
OIDCClientID string
|
||||
OIDCIssuerURL string
|
||||
OIDCUsernameClaim string
|
||||
OIDCGroupsClaim string
|
||||
RequestHeaderUsernameHeaders []string
|
||||
RequestHeaderClientCAFile string
|
||||
RequestHeaderAllowedNames []string
|
||||
RuntimeConfig config.ConfigurationMap
|
||||
SecurePort int
|
||||
ServiceClusterIPRange net.IPNet // TODO: make this a list
|
||||
ServiceNodePortRange utilnet.PortRange
|
||||
StorageVersions string
|
||||
// The default values for StorageVersions. StorageVersions overrides
|
||||
// these; you can change this if you want to change the defaults (e.g.,
|
||||
// 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, "+
|
||||
"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", ""+
|
||||
"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. "+
|
||||
|
32
plugin/pkg/auth/authenticator/request/headerrequest/BUILD
Normal file
32
plugin/pkg/auth/authenticator/request/headerrequest/BUILD
Normal 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"],
|
||||
)
|
@ -31,6 +31,7 @@ import (
|
||||
)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -18,8 +18,11 @@ go_library(
|
||||
],
|
||||
tags = ["automanaged"],
|
||||
deps = [
|
||||
"//pkg/auth/authenticator:go_default_library",
|
||||
"//pkg/auth/user: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/*"]),
|
||||
library = "go_default_library",
|
||||
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",
|
||||
],
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user