1/* 2Copyright 2016 The Kubernetes Authors. 3 4Licensed under the Apache License, Version 2.0 (the "License"); 5you may not use this file except in compliance with the License. 6You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10Unless required by applicable law or agreed to in writing, software 11distributed under the License is distributed on an "AS IS" BASIS, 12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13See the License for the specific language governing permissions and 14limitations under the License. 15*/ 16 17package authorizer 18 19import ( 20 "errors" 21 "fmt" 22 "time" 23 24 utilnet "k8s.io/apimachinery/pkg/util/net" 25 "k8s.io/apimachinery/pkg/util/wait" 26 "k8s.io/apiserver/pkg/authorization/authorizer" 27 "k8s.io/apiserver/pkg/authorization/authorizerfactory" 28 "k8s.io/apiserver/pkg/authorization/union" 29 "k8s.io/apiserver/plugin/pkg/authorizer/webhook" 30 versionedinformers "k8s.io/client-go/informers" 31 "k8s.io/kubernetes/pkg/auth/authorizer/abac" 32 "k8s.io/kubernetes/pkg/auth/nodeidentifier" 33 "k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes" 34 "k8s.io/kubernetes/plugin/pkg/auth/authorizer/node" 35 "k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac" 36 "k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy" 37) 38 39// Config contains the data on how to authorize a request to the Kube API Server 40type Config struct { 41 AuthorizationModes []string 42 43 // Options for ModeABAC 44 45 // Path to an ABAC policy file. 46 PolicyFile string 47 48 // Options for ModeWebhook 49 50 // Kubeconfig file for Webhook authorization plugin. 51 WebhookConfigFile string 52 // API version of subject access reviews to send to the webhook (e.g. "v1", "v1beta1") 53 WebhookVersion string 54 // TTL for caching of authorized responses from the webhook server. 55 WebhookCacheAuthorizedTTL time.Duration 56 // TTL for caching of unauthorized responses from the webhook server. 57 WebhookCacheUnauthorizedTTL time.Duration 58 // WebhookRetryBackoff specifies the backoff parameters for the authorization webhook retry logic. 59 // This allows us to configure the sleep time at each iteration and the maximum number of retries allowed 60 // before we fail the webhook call in order to limit the fan out that ensues when the system is degraded. 61 WebhookRetryBackoff *wait.Backoff 62 63 VersionedInformerFactory versionedinformers.SharedInformerFactory 64 65 // Optional field, custom dial function used to connect to webhook 66 CustomDial utilnet.DialFunc 67} 68 69// New returns the right sort of union of multiple authorizer.Authorizer objects 70// based on the authorizationMode or an error. 71func (config Config) New() (authorizer.Authorizer, authorizer.RuleResolver, error) { 72 if len(config.AuthorizationModes) == 0 { 73 return nil, nil, fmt.Errorf("at least one authorization mode must be passed") 74 } 75 76 var ( 77 authorizers []authorizer.Authorizer 78 ruleResolvers []authorizer.RuleResolver 79 ) 80 81 for _, authorizationMode := range config.AuthorizationModes { 82 // Keep cases in sync with constant list in k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes/modes.go. 83 switch authorizationMode { 84 case modes.ModeNode: 85 node.RegisterMetrics() 86 graph := node.NewGraph() 87 node.AddGraphEventHandlers( 88 graph, 89 config.VersionedInformerFactory.Core().V1().Nodes(), 90 config.VersionedInformerFactory.Core().V1().Pods(), 91 config.VersionedInformerFactory.Core().V1().PersistentVolumes(), 92 config.VersionedInformerFactory.Storage().V1().VolumeAttachments(), 93 ) 94 nodeAuthorizer := node.NewAuthorizer(graph, nodeidentifier.NewDefaultNodeIdentifier(), bootstrappolicy.NodeRules()) 95 authorizers = append(authorizers, nodeAuthorizer) 96 ruleResolvers = append(ruleResolvers, nodeAuthorizer) 97 98 case modes.ModeAlwaysAllow: 99 alwaysAllowAuthorizer := authorizerfactory.NewAlwaysAllowAuthorizer() 100 authorizers = append(authorizers, alwaysAllowAuthorizer) 101 ruleResolvers = append(ruleResolvers, alwaysAllowAuthorizer) 102 case modes.ModeAlwaysDeny: 103 alwaysDenyAuthorizer := authorizerfactory.NewAlwaysDenyAuthorizer() 104 authorizers = append(authorizers, alwaysDenyAuthorizer) 105 ruleResolvers = append(ruleResolvers, alwaysDenyAuthorizer) 106 case modes.ModeABAC: 107 abacAuthorizer, err := abac.NewFromFile(config.PolicyFile) 108 if err != nil { 109 return nil, nil, err 110 } 111 authorizers = append(authorizers, abacAuthorizer) 112 ruleResolvers = append(ruleResolvers, abacAuthorizer) 113 case modes.ModeWebhook: 114 if config.WebhookRetryBackoff == nil { 115 return nil, nil, errors.New("retry backoff parameters for authorization webhook has not been specified") 116 } 117 webhookAuthorizer, err := webhook.New(config.WebhookConfigFile, 118 config.WebhookVersion, 119 config.WebhookCacheAuthorizedTTL, 120 config.WebhookCacheUnauthorizedTTL, 121 *config.WebhookRetryBackoff, 122 config.CustomDial) 123 if err != nil { 124 return nil, nil, err 125 } 126 authorizers = append(authorizers, webhookAuthorizer) 127 ruleResolvers = append(ruleResolvers, webhookAuthorizer) 128 case modes.ModeRBAC: 129 rbacAuthorizer := rbac.New( 130 &rbac.RoleGetter{Lister: config.VersionedInformerFactory.Rbac().V1().Roles().Lister()}, 131 &rbac.RoleBindingLister{Lister: config.VersionedInformerFactory.Rbac().V1().RoleBindings().Lister()}, 132 &rbac.ClusterRoleGetter{Lister: config.VersionedInformerFactory.Rbac().V1().ClusterRoles().Lister()}, 133 &rbac.ClusterRoleBindingLister{Lister: config.VersionedInformerFactory.Rbac().V1().ClusterRoleBindings().Lister()}, 134 ) 135 authorizers = append(authorizers, rbacAuthorizer) 136 ruleResolvers = append(ruleResolvers, rbacAuthorizer) 137 default: 138 return nil, nil, fmt.Errorf("unknown authorization mode %s specified", authorizationMode) 139 } 140 } 141 142 return union.New(authorizers...), union.NewRuleResolvers(ruleResolvers...), nil 143} 144