Skip to content

Commit

Permalink
feat: Add audit policy patch (#126)
Browse files Browse the repository at this point in the history
  • Loading branch information
jimmidyson authored Aug 31, 2023
1 parent a420f81 commit 3fecd1b
Show file tree
Hide file tree
Showing 12 changed files with 574 additions and 57 deletions.
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ repos:
name: License headers - YAML and Makefiles
stages: [commit]
files: (^Makefile|\.(ya?ml|mk))$
exclude: ^pkg/handlers/.+/embedded/.+\.ya?ml$
args:
- --license-filepath
- hack/license-header.txt
Expand Down
1 change: 1 addition & 0 deletions charts/capi-runtime-extensions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ A Helm chart for capi-runtime-extensions
| controllers.enableLeaderElection | bool | `false` | |
| deployment.replicas | int | `1` | |
| env | object | `{}` | |
| handlers.AuditPolicyPatch.enabled | bool | `true` | |
| handlers.CalicoCNI.defaultInstallationConfigMaps.DockerCluster.configMap.content | string | `""` | |
| handlers.CalicoCNI.defaultInstallationConfigMaps.DockerCluster.configMap.name | string | `"calico-cni-installation-dockercluster"` | |
| handlers.CalicoCNI.defaultInstallationConfigMaps.DockerCluster.create | bool | `true` | |
Expand Down
2 changes: 2 additions & 0 deletions charts/capi-runtime-extensions/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ handlers:
enabled: true
HTTPProxyPatch:
enabled: true
AuditPolicyPatch:
enabled: true

deployment:
replicas: 1
Expand Down
29 changes: 29 additions & 0 deletions docs/content/audit-policy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
title: "Audit policy"
---

Kubernetes auditing provides a security-relevant, chronological set of records documenting the sequence of actions in a
cluster. The cluster audits the activities generated by users, by applications that use the Kubernetes API, and by the
control plane itself. The `auditpolicypatch` external patch will generate appropriate configuration for the Kubernetes
control plane.

To enable the audit policy enable the `auditpolicypatch` external patch on `ClusterClass`.

```yaml
apiVersion: cluster.x-k8s.io/v1beta1
kind: ClusterClass
metadata:
name: <NAME>
spec:
patches:
- name: audit-policy
external:
generateExtension: "auditpolicypatch.<external-config-name>"
```
Applying this configuration will result in new bootstrap files on the `KubeadmControlPlaneTemplate`.

This hook is enabled by default, and can be explicitly disabled by omitting the `AuditPolicyPatch` hook from the
`--runtimehooks.enabled-handlers` flag.

If deploying via Helm, then this can be disabled by setting `handlers.AuditPolicyPatch.enabled=false`.
8 changes: 7 additions & 1 deletion internal/runtimehooks/webhooks/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,13 @@ func (s *Server) AddFlags(prefix string, fs *pflag.FlagSet) {
fs.StringSliceVar(
&s.enabledHandlers,
prefix+".enabled-handlers",
[]string{"ServiceLoadBalancerGC", "CalicoCNI", "HTTPProxyPatch", "HTTPProxyVars"},
[]string{
"ServiceLoadBalancerGC",
"CalicoCNI",
"HTTPProxyPatch",
"HTTPProxyVars",
"AuditPolicyPatch",
},
"list of all enabled handlers",
)

Expand Down
41 changes: 41 additions & 0 deletions pkg/capi/clustertopology/patches/generator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright 2023 D2iQ, Inc. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package patches

import (
"fmt"

"github.com/go-logr/logr"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apimachinery/pkg/runtime"
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1"

"github.com/d2iq-labs/capi-runtime-extensions/pkg/capi/clustertopology/patches/matchers"
)

func Generate[T runtime.Object](
obj runtime.Object,
vars map[string]apiextensionsv1.JSON,
holderRef *runtimehooksv1.HolderReference,
patchSelector clusterv1.PatchSelector,
log logr.Logger,
mutFn func(T) error,
) error {
typed, ok := obj.(T)
if !ok {
log.V(5).WithValues(
"objType", fmt.Sprintf("%T", obj),
"expectedType", fmt.Sprintf("%T", *new(T)),
).Info("not matching type")
return nil
}

if !matchers.MatchesSelector(patchSelector, obj, holderRef, vars) {
log.WithValues("selector", patchSelector).Info("not matching selector")
return nil
}

return mutFn(typed)
}
48 changes: 48 additions & 0 deletions pkg/capi/clustertopology/patches/selectors/selectors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2023 D2iQ, Inc. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package selectors

import (
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1"
controlplanev1 "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1beta1"
)

func ControlPlane() clusterv1.PatchSelector {
return clusterv1.PatchSelector{
APIVersion: controlplanev1.GroupVersion.String(),
Kind: "KubeadmControlPlaneTemplate",
MatchResources: clusterv1.PatchSelectorMatch{
ControlPlane: true,
},
}
}

func DefaultWorkerSelector() clusterv1.PatchSelector {
return clusterv1.PatchSelector{
APIVersion: bootstrapv1.GroupVersion.String(),
Kind: "KubeadmConfigTemplate",
MatchResources: clusterv1.PatchSelectorMatch{
MachineDeploymentClass: &clusterv1.PatchSelectorMatchMachineDeploymentClass{
Names: []string{
"default-worker",
},
},
},
}
}

func AllWorkersSelector() clusterv1.PatchSelector {
return clusterv1.PatchSelector{
APIVersion: bootstrapv1.GroupVersion.String(),
Kind: "KubeadmConfigTemplate",
MatchResources: clusterv1.PatchSelectorMatch{
MachineDeploymentClass: &clusterv1.PatchSelectorMatchMachineDeploymentClass{
Names: []string{
"*",
},
},
},
}
}
161 changes: 161 additions & 0 deletions pkg/handlers/auditpolicy/embedded/apiserver-audit-policy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
# Taken from https://github.com/kubernetes/kubernetes/blob/master/cluster/gce/gci/configure-helper.sh
# Recommended in Kubernetes docs
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
# The following requests were manually identified as high-volume and low-risk,
# so drop them.
- level: None
users: ["system:kube-proxy"]
verbs: ["watch"]
resources:
- group: "" # core
resources: ["endpoints", "services", "services/status"]
- level: None
# Ingress controller reads 'configmaps/ingress-uid' through the unsecured port.
# TODO(#46983): Change this to the ingress controller service account.
users: ["system:unsecured"]
namespaces: ["kube-system"]
verbs: ["get"]
resources:
- group: "" # core
resources: ["configmaps"]
- level: None
users: ["kubelet"] # legacy kubelet identity
verbs: ["get"]
resources:
- group: "" # core
resources: ["nodes", "nodes/status"]
- level: None
userGroups: ["system:nodes"]
verbs: ["get"]
resources:
- group: "" # core
resources: ["nodes", "nodes/status"]
- level: None
users:
- system:kube-controller-manager
- system:kube-scheduler
- system:serviceaccount:kube-system:endpoint-controller
verbs: ["get", "update"]
namespaces: ["kube-system"]
resources:
- group: "" # core
resources: ["endpoints"]
- level: None
users: ["system:apiserver"]
verbs: ["get"]
resources:
- group: "" # core
resources: ["namespaces", "namespaces/status", "namespaces/finalize"]
- level: None
users: ["cluster-autoscaler"]
verbs: ["get", "update"]
namespaces: ["kube-system"]
resources:
- group: "" # core
resources: ["configmaps", "endpoints"]
# Don't log HPA fetching metrics.
- level: None
users:
- system:kube-controller-manager
verbs: ["get", "list"]
resources:
- group: "metrics.k8s.io"
# Don't log these read-only URLs.
- level: None
nonResourceURLs:
- /healthz*
- /version
- /swagger*
# Don't log events requests.
- level: None
resources:
- group: "" # core
resources: ["events"]
# node and pod status calls from nodes are high-volume and can be large, don't log responses for expected updates from nodes
- level: Request
users: ["kubelet", "system:node-problem-detector", "system:serviceaccount:kube-system:node-problem-detector"]
verbs: ["update","patch"]
resources:
- group: "" # core
resources: ["nodes/status", "pods/status"]
omitStages:
- "RequestReceived"
- level: Request
userGroups: ["system:nodes"]
verbs: ["update","patch"]
resources:
- group: "" # core
resources: ["nodes/status", "pods/status"]
omitStages:
- "RequestReceived"
# deletecollection calls can be large, don't log responses for expected namespace deletions
- level: Request
users: ["system:serviceaccount:kube-system:namespace-controller"]
verbs: ["deletecollection"]
omitStages:
- "RequestReceived"
# Secrets, ConfigMaps, and TokenReviews can contain sensitive & binary data,
# so only log at the Metadata level.
- level: Metadata
resources:
- group: "" # core
resources: ["secrets", "configmaps"]
- group: authentication.k8s.io
resources: ["tokenreviews"]
omitStages:
- "RequestReceived"
# Get responses can be large; skip them.
- level: Request
verbs: ["get", "list", "watch"]
resources:
- group: "" # core
- group: "admissionregistration.k8s.io"
- group: "apiextensions.k8s.io"
- group: "apiregistration.k8s.io"
- group: "apps"
- group: "authentication.k8s.io"
- group: "authorization.k8s.io"
- group: "autoscaling"
- group: "batch"
- group: "certificates.k8s.io"
- group: "extensions"
- group: "metrics.k8s.io"
- group: "networking.k8s.io"
- group: "node.k8s.io"
- group: "policy"
- group: "rbac.authorization.k8s.io"
- group: "scheduling.k8s.io"
- group: "settings.k8s.io"
- group: "storage.k8s.io"
omitStages:
- "RequestReceived"
# Default level for known APIs
- level: RequestResponse
resources:
- group: "" # core
- group: "admissionregistration.k8s.io"
- group: "apiextensions.k8s.io"
- group: "apiregistration.k8s.io"
- group: "apps"
- group: "authentication.k8s.io"
- group: "authorization.k8s.io"
- group: "autoscaling"
- group: "batch"
- group: "certificates.k8s.io"
- group: "extensions"
- group: "metrics.k8s.io"
- group: "networking.k8s.io"
- group: "node.k8s.io"
- group: "policy"
- group: "rbac.authorization.k8s.io"
- group: "scheduling.k8s.io"
- group: "settings.k8s.io"
- group: "storage.k8s.io"
omitStages:
- "RequestReceived"
# Default level for all other requests.
- level: Metadata
omitStages:
- "RequestReceived"
Loading

0 comments on commit 3fecd1b

Please sign in to comment.