Avoid nil user special-casing in unsecured endpoint
This commit is contained in:
parent
d42d630d74
commit
5d839d0d0b
@ -13,6 +13,7 @@ go_library(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//vendor:github.com/golang/glog",
|
"//vendor:github.com/golang/glog",
|
||||||
|
"//vendor:k8s.io/apiserver/pkg/authentication/user",
|
||||||
"//vendor:k8s.io/apiserver/pkg/endpoints/filters",
|
"//vendor:k8s.io/apiserver/pkg/endpoints/filters",
|
||||||
"//vendor:k8s.io/apiserver/pkg/endpoints/request",
|
"//vendor:k8s.io/apiserver/pkg/endpoints/request",
|
||||||
"//vendor:k8s.io/apiserver/pkg/server",
|
"//vendor:k8s.io/apiserver/pkg/server",
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
|
||||||
|
"k8s.io/apiserver/pkg/authentication/user"
|
||||||
genericapifilters "k8s.io/apiserver/pkg/endpoints/filters"
|
genericapifilters "k8s.io/apiserver/pkg/endpoints/filters"
|
||||||
apirequest "k8s.io/apiserver/pkg/endpoints/request"
|
apirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||||
"k8s.io/apiserver/pkg/server"
|
"k8s.io/apiserver/pkg/server"
|
||||||
@ -35,6 +36,7 @@ import (
|
|||||||
|
|
||||||
func BuildInsecureHandlerChain(apiHandler http.Handler, c *server.Config) http.Handler {
|
func BuildInsecureHandlerChain(apiHandler http.Handler, c *server.Config) http.Handler {
|
||||||
handler := genericapifilters.WithAudit(apiHandler, c.RequestContextMapper, c.AuditWriter)
|
handler := genericapifilters.WithAudit(apiHandler, c.RequestContextMapper, c.AuditWriter)
|
||||||
|
handler = genericapifilters.WithAuthentication(handler, c.RequestContextMapper, insecureSuperuser{}, nil)
|
||||||
handler = genericfilters.WithCORS(handler, c.CorsAllowedOriginList, nil, nil, nil, "true")
|
handler = genericfilters.WithCORS(handler, c.CorsAllowedOriginList, nil, nil, nil, "true")
|
||||||
handler = genericfilters.WithPanicRecovery(handler, c.RequestContextMapper)
|
handler = genericfilters.WithPanicRecovery(handler, c.RequestContextMapper)
|
||||||
handler = genericfilters.WithTimeoutForNonLongRunningRequests(handler, c.RequestContextMapper, c.LongRunningFunc)
|
handler = genericfilters.WithTimeoutForNonLongRunningRequests(handler, c.RequestContextMapper, c.LongRunningFunc)
|
||||||
@ -111,3 +113,15 @@ func serveInsecurely(insecureServingInfo *InsecureServingInfo, insecureHandler h
|
|||||||
_, err = server.RunServer(insecureServer, insecureServingInfo.BindNetwork, stopCh)
|
_, err = server.RunServer(insecureServer, insecureServingInfo.BindNetwork, stopCh)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// insecureSuperuser implements authenticator.Request to always return a superuser.
|
||||||
|
// This is functionally equivalent to skipping authentication and authorization,
|
||||||
|
// but allows apiserver code to stop special-casing a nil user to skip authorization checks.
|
||||||
|
type insecureSuperuser struct{}
|
||||||
|
|
||||||
|
func (insecureSuperuser) AuthenticateRequest(req *http.Request) (user.Info, bool, error) {
|
||||||
|
return &user.DefaultInfo{
|
||||||
|
Name: "system:unsecured",
|
||||||
|
Groups: []string{user.SystemPrivilegedGroup, user.AllAuthenticated},
|
||||||
|
}, true, nil
|
||||||
|
}
|
||||||
|
@ -29,9 +29,7 @@ import (
|
|||||||
func EscalationAllowed(ctx genericapirequest.Context) bool {
|
func EscalationAllowed(ctx genericapirequest.Context) bool {
|
||||||
u, ok := genericapirequest.UserFrom(ctx)
|
u, ok := genericapirequest.UserFrom(ctx)
|
||||||
if !ok {
|
if !ok {
|
||||||
// the only way to be without a user is to either have no authenticators by explicitly saying that's your preference
|
return false
|
||||||
// or to be connecting via the insecure port, in which case this logically doesn't apply
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// system:masters is special because the API server uses it for privileged loopback connections
|
// system:masters is special because the API server uses it for privileged loopback connections
|
||||||
|
@ -288,8 +288,7 @@ func getMatchingPolicies(lister extensionslisters.PodSecurityPolicyLister, user
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, constraint := range list {
|
for _, constraint := range list {
|
||||||
// if no user info exists then the API is being hit via the unsecured port. In this case authorize the request.
|
if authorizedForPolicy(user, namespace, constraint, authz) || authorizedForPolicy(sa, namespace, constraint, authz) {
|
||||||
if user == nil || authorizedForPolicy(user, namespace, constraint, authz) || authorizedForPolicy(sa, namespace, constraint, authz) {
|
|
||||||
matchedPolicies = append(matchedPolicies, constraint)
|
matchedPolicies = append(matchedPolicies, constraint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1612,25 +1612,34 @@ func TestGetMatchingPolicies(t *testing.T) {
|
|||||||
},
|
},
|
||||||
expectedPolicies: sets.NewString("policy1", "policy2", "policy4", "policy5"),
|
expectedPolicies: sets.NewString("policy1", "policy2", "policy4", "policy5"),
|
||||||
},
|
},
|
||||||
"policies are allowed for nil user info": {
|
"policies are not allowed for nil user info": {
|
||||||
user: nil,
|
user: nil,
|
||||||
sa: &user.DefaultInfo{Name: "sa"},
|
sa: &user.DefaultInfo{Name: "sa"},
|
||||||
ns: "test",
|
ns: "test",
|
||||||
allowed: map[string]map[string]map[string]bool{}, // authorizer not consulted
|
allowed: map[string]map[string]map[string]bool{
|
||||||
|
"sa": {
|
||||||
|
"test": {"policy1": true},
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"test": {"policy2": true},
|
||||||
|
},
|
||||||
|
},
|
||||||
inPolicies: []*extensions.PodSecurityPolicy{
|
inPolicies: []*extensions.PodSecurityPolicy{
|
||||||
policyWithName("policy1"),
|
policyWithName("policy1"),
|
||||||
policyWithName("policy2"),
|
policyWithName("policy2"),
|
||||||
policyWithName("policy3"),
|
policyWithName("policy3"),
|
||||||
},
|
},
|
||||||
// all policies are allowed regardless of the permissions when user info is nil
|
// only the policies for the sa are allowed when user info is nil
|
||||||
// (ie. a request hitting the unsecure port)
|
expectedPolicies: sets.NewString("policy1"),
|
||||||
expectedPolicies: sets.NewString("policy1", "policy2", "policy3"),
|
|
||||||
},
|
},
|
||||||
"policies are not allowed for nil sa info": {
|
"policies are not allowed for nil sa info": {
|
||||||
user: &user.DefaultInfo{Name: "user"},
|
user: &user.DefaultInfo{Name: "user"},
|
||||||
sa: nil,
|
sa: nil,
|
||||||
ns: "test",
|
ns: "test",
|
||||||
allowed: map[string]map[string]map[string]bool{
|
allowed: map[string]map[string]map[string]bool{
|
||||||
|
"sa": {
|
||||||
|
"test": {"policy1": true},
|
||||||
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"test": {"policy2": true},
|
"test": {"policy2": true},
|
||||||
},
|
},
|
||||||
@ -1643,6 +1652,26 @@ func TestGetMatchingPolicies(t *testing.T) {
|
|||||||
// only the policies for the user are allowed when sa info is nil
|
// only the policies for the user are allowed when sa info is nil
|
||||||
expectedPolicies: sets.NewString("policy2"),
|
expectedPolicies: sets.NewString("policy2"),
|
||||||
},
|
},
|
||||||
|
"policies are not allowed for nil sa and user info": {
|
||||||
|
user: nil,
|
||||||
|
sa: nil,
|
||||||
|
ns: "test",
|
||||||
|
allowed: map[string]map[string]map[string]bool{
|
||||||
|
"sa": {
|
||||||
|
"test": {"policy1": true},
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"test": {"policy2": true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
inPolicies: []*extensions.PodSecurityPolicy{
|
||||||
|
policyWithName("policy1"),
|
||||||
|
policyWithName("policy2"),
|
||||||
|
policyWithName("policy3"),
|
||||||
|
},
|
||||||
|
// no policies are allowed if sa and user are both nil
|
||||||
|
expectedPolicies: sets.NewString(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for k, v := range tests {
|
for k, v := range tests {
|
||||||
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
|
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
|
||||||
|
Loading…
Reference in New Issue
Block a user