Merge pull request #55306 from hzxuzhonghu/audit

Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

Audit support resource wildcard matching

**What this PR does / why we need it**:

audit policy support "resource/subresources" wildcard matching "resource/*", "*/subresource","*"

**Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*:
Fixes #55305

**Special notes for your reviewer**:

**Release note**:

```release-note
[advanced audit] support subresources wildcard matching.
```

Kubernetes-commit: 10f2544ec80e176faad73c5025d7c16ffb8284b4
This commit is contained in:
Kubernetes Publisher 2018-02-13 05:38:25 -08:00
commit 4d11630801
7 changed files with 98 additions and 26 deletions

View File

@ -234,10 +234,19 @@ type GroupResources struct {
// The empty string represents the core API group.
// +optional
Group string
// Resources is a list of resources within the API group. Subresources are
// matched using a "/" to indicate the subresource. For example, "pods/log"
// would match request to the log subresource of pods. The top level resource
// does not match subresources, "pods" doesn't match "pods/log".
// Resources is a list of resources this rule applies to.
//
// For example:
// 'pods' matches pods.
// 'pods/log' matches the log subresource of pods.
// '*' matches all resources and their subresources.
// 'pods/*' matches all subresources of pods.
// '*/scale' matches all scale subresources.
//
// If wildcard is present, the validation rule will ensure resources do not
// overlap with each other.
//
// An empty list implies all resources and subresources in this API groups apply.
// +optional
Resources []string
// ResourceNames is a list of resource instance names that the policy matches.

View File

@ -122,10 +122,19 @@ message GroupResources {
// +optional
optional string group = 1;
// Resources is a list of resources within the API group. Subresources are
// matched using a "/" to indicate the subresource. For example, "pods/logs"
// would match request to the logs subresource of pods. The top level resource
// does not match subresources, "pods" doesn't match "pods/logs".
// Resources is a list of resources this rule applies to.
//
// For example:
// 'pods' matches pods.
// 'pods/log' matches the log subresource of pods.
// '*' matches all resources and their subresources.
// 'pods/*' matches all subresources of pods.
// '*/scale' matches all scale subresources.
//
// If wildcard is present, the validation rule will ensure resources do not
// overlap with each other.
//
// An empty list implies all resources and subresources in this API groups apply.
// +optional
repeated string resources = 2;

View File

@ -241,10 +241,19 @@ type GroupResources struct {
// The empty string represents the core API group.
// +optional
Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"`
// Resources is a list of resources within the API group. Subresources are
// matched using a "/" to indicate the subresource. For example, "pods/logs"
// would match request to the logs subresource of pods. The top level resource
// does not match subresources, "pods" doesn't match "pods/logs".
// Resources is a list of resources this rule applies to.
//
// For example:
// 'pods' matches pods.
// 'pods/log' matches the log subresource of pods.
// '*' matches all resources and their subresources.
// 'pods/*' matches all subresources of pods.
// '*/scale' matches all scale subresources.
//
// If wildcard is present, the validation rule will ensure resources do not
// overlap with each other.
//
// An empty list implies all resources and subresources in this API groups apply.
// +optional
Resources []string `json:"resources,omitempty" protobuf:"bytes,2,rep,name=resources"`
// ResourceNames is a list of resource instance names that the policy matches.

View File

@ -126,10 +126,19 @@ message GroupResources {
// +optional
optional string group = 1;
// Resources is a list of resources within the API group. Subresources are
// matched using a "/" to indicate the subresource. For example, "pods/log"
// would match request to the log subresource of pods. The top level resource
// does not match subresources, "pods" doesn't match "pods/log".
// Resources is a list of resources this rule applies to.
//
// For example:
// 'pods' matches pods.
// 'pods/log' matches the log subresource of pods.
// '*' matches all resources and their subresources.
// 'pods/*' matches all subresources of pods.
// '*/scale' matches all scale subresources.
//
// If wildcard is present, the validation rule will ensure resources do not
// overlap with each other.
//
// An empty list implies all resources and subresources in this API groups apply.
// +optional
repeated string resources = 2;

View File

@ -237,10 +237,19 @@ type GroupResources struct {
// The empty string represents the core API group.
// +optional
Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"`
// Resources is a list of resources within the API group. Subresources are
// matched using a "/" to indicate the subresource. For example, "pods/log"
// would match request to the log subresource of pods. The top level resource
// does not match subresources, "pods" doesn't match "pods/log".
// Resources is a list of resources this rule applies to.
//
// For example:
// 'pods' matches pods.
// 'pods/log' matches the log subresource of pods.
// '*' matches all resources and their subresources.
// 'pods/*' matches all subresources of pods.
// '*/scale' matches all scale subresources.
//
// If wildcard is present, the validation rule will ensure resources do not
// overlap with each other.
//
// An empty list implies all resources and subresources in this API groups apply.
// +optional
Resources []string `json:"resources,omitempty" protobuf:"bytes,2,rep,name=resources"`
// ResourceNames is a list of resource instance names that the policy matches.

View File

@ -160,11 +160,11 @@ func ruleMatchesResource(r *audit.PolicyRule, attrs authorizer.Attributes) bool
apiGroup := attrs.GetAPIGroup()
resource := attrs.GetResource()
subresource := attrs.GetSubresource()
combinedResource := resource
// If subresource, the resource in the policy must match "(resource)/(subresource)"
//
// TODO: consider adding options like "pods/*" to match all subresources.
if sr := attrs.GetSubresource(); sr != "" {
resource = resource + "/" + sr
if subresource != "" {
combinedResource = resource + "/" + subresource
}
name := attrs.GetName()
@ -175,8 +175,17 @@ func ruleMatchesResource(r *audit.PolicyRule, attrs authorizer.Attributes) bool
return true
}
for _, res := range gr.Resources {
if res == resource {
if len(gr.ResourceNames) == 0 || hasString(gr.ResourceNames, name) {
if len(gr.ResourceNames) == 0 || hasString(gr.ResourceNames, name) {
// match "*"
if res == combinedResource || res == "*" {
return true
}
// match "*/subresource"
if len(subresource) > 0 && strings.HasPrefix(res, "*/") && subresource == strings.TrimLeft(res, "*/") {
return true
}
// match "resource/*"
if strings.HasSuffix(res, "/*") && resource == strings.TrimRight(res, "/*") {
return true
}
}

View File

@ -105,6 +105,21 @@ var (
Verbs: []string{"get"},
Resources: []audit.GroupResources{{Resources: []string{"pods/log"}}},
},
"getPodWildcardMatching": {
Level: audit.LevelRequest,
Verbs: []string{"get"},
Resources: []audit.GroupResources{{Resources: []string{"*"}}},
},
"getPodResourceWildcardMatching": {
Level: audit.LevelRequest,
Verbs: []string{"get"},
Resources: []audit.GroupResources{{Resources: []string{"*/log"}}},
},
"getPodSubResourceWildcardMatching": {
Level: audit.LevelRequest,
Verbs: []string{"get"},
Resources: []audit.GroupResources{{Resources: []string{"pods/*"}}},
},
"getClusterRoles": {
Level: audit.LevelRequestResponse,
Verbs: []string{"get"},
@ -208,6 +223,9 @@ func testAuditLevel(t *testing.T, stages []audit.Stage) {
test(t, "nonResource", audit.LevelNone, stages, stages, "getPodLogs", "getPods")
test(t, "subresource", audit.LevelRequest, stages, stages, "getPodLogs", "getPods")
test(t, "subresource", audit.LevelRequest, stages, stages, "getPodWildcardMatching")
test(t, "subresource", audit.LevelRequest, stages, stages, "getPodResourceWildcardMatching")
test(t, "subresource", audit.LevelRequest, stages, stages, "getPodSubResourceWildcardMatching")
}