From 7a698633d7c7e10f8eb9cef19712fb692513205b Mon Sep 17 00:00:00 2001 From: bsctl Date: Fri, 16 Jul 2021 11:45:51 +0200 Subject: [PATCH] docs: additional test cases --- .../block-access-to-multitenant-resources.md | 3 +- docs/operator/mtb/block-add-capabilities.md | 118 ++++++++++++++++++ .../mtb/require-always-imagepullpolicy.md | 71 +++++++++++ docs/operator/mtb/sig-multitenancy-bench.md | 4 +- 4 files changed, 193 insertions(+), 3 deletions(-) create mode 100644 docs/operator/mtb/block-add-capabilities.md create mode 100644 docs/operator/mtb/require-always-imagepullpolicy.md diff --git a/docs/operator/mtb/block-access-to-multitenant-resources.md b/docs/operator/mtb/block-access-to-multitenant-resources.md index 6b7bc440..8e978e56 100644 --- a/docs/operator/mtb/block-access-to-multitenant-resources.md +++ b/docs/operator/mtb/block-access-to-multitenant-resources.md @@ -75,7 +75,8 @@ kubectl --kubeconfig alice delete networkpolicies capsule-oil-0 You should receive an error message denying the edit/delete request ```bash -Error from server (Forbidden): networkpolicies.networking.k8s.io "capsule-oil-0" is forbidden: User "oil" cannot delete resource "networkpolicies" in API group "networking.k8s.io" in the namespace "oil-production" +Error from server (Forbidden): networkpolicies.networking.k8s.io "capsule-oil-0" is forbidden: +User "oil" cannot delete resource "networkpolicies" in API group "networking.k8s.io" in the namespace "oil-production" ``` As tenant owner, you can create an additional networkpolicy inside the namespace diff --git a/docs/operator/mtb/block-add-capabilities.md b/docs/operator/mtb/block-add-capabilities.md new file mode 100644 index 00000000..cfb85293 --- /dev/null +++ b/docs/operator/mtb/block-add-capabilities.md @@ -0,0 +1,118 @@ +# Block add capabilities + +**Profile Applicability:** L1 + +**Type:** Behavioral Check + +**Category:** Control Plane Isolation + +**Description:** Control Linux capabilities. + +**Rationale:** Linux allows defining fine-grained permissions using capabilities. With Kubernetes, it is possible to add capabilities for pods that escalate the level of kernel access and allow other potentially dangerous behaviors. + +**Audit:** + +As cluster admin, define a `PodSecurityPolicy` with `allowedCapabilities` and map the policy to a tenant: + +```yaml +kubectl create -f - << EOF +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: tenant +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + # The default set of capabilities are implicitly allowed + # The empty set means that no additional capabilities may be added beyond the default set + allowedCapabilities: [] + runAsUser: + rule: RunAsAny + seLinux: + rule: RunAsAny + supplementalGroups: + rule: RunAsAny + fsGroup: + rule: RunAsAny +EOF +``` + +> Note: make sure `PodSecurityPolicy` Admission Control is enabled on the APIs server: `--enable-admission-plugins=PodSecurityPolicy` + +Then create a ClusterRole using or granting the said item + +```yaml +kubectl create -f - << EOF +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: tenant:psp +rules: +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + resourceNames: ['tenant'] + verbs: ['use'] +EOF +``` + +And assign it to the tenant + +```yaml +kubectl apply -f - << EOF +apiVersion: capsule.clastix.io/v1beta1 +kind: Tenant +metadata: + name: oil +spec: + owners: + - kind: User + name: alice + additionalRoleBindings: + - clusterRoleName: tenant:psp + subjects: + - kind: "Group" + apiGroup: "rbac.authorization.k8s.io" + name: "system:authenticated" +EOF + +./create-user.sh alice oil +``` + +As tenant owner, run the following command to create a namespace in the given tenant + +```bash +kubectl --kubeconfig alice create ns oil-production +kubectl --kubeconfig alice config set-context --current --namespace oil-production +``` + +As tenant owner, create a pod and see new capabilities cannot be added in the tenant namespaces + +```yaml +kubectl --kubeconfig alice apply -f - << EOF +apiVersion: v1 +kind: Pod +metadata: + name: pod-with-settime-cap + namespace: + labels: +spec: + containers: + - name: busybox + image: busybox:latest + command: ["/bin/sleep", "3600"] + securityContext: + capabilities: + add: + - SYS_TIME +EOF +``` + +You should have the pod blocked by PodSecurityPolicy. + +**Cleanup:** +As cluster admin, delete all the created resources + +```bash +kubectl --kubeconfig cluster-admin delete tenant oil +``` \ No newline at end of file diff --git a/docs/operator/mtb/require-always-imagepullpolicy.md b/docs/operator/mtb/require-always-imagepullpolicy.md new file mode 100644 index 00000000..f8c4a321 --- /dev/null +++ b/docs/operator/mtb/require-always-imagepullpolicy.md @@ -0,0 +1,71 @@ +# Require always imagePullPolicy + +**Profile Applicability:** L1 + +**Type:** Configuration Check + +**Category:** Data Isolation + +**Description:** Set the image pull policy to Always for tenant workloads. + +**Rationale:** Tenants have to be assured that their private images can only be used by those who have the credentials to pull them. + +**Audit:** + +As cluster admin, create a tenant + +```yaml +kubectl create -f - << EOF +apiVersion: capsule.clastix.io/v1beta1 +kind: Tenant +metadata: + name: oil +spec: + imagePullPolicies: + - Always + owners: + - kind: User + name: alice +EOF + +./create-user.sh alice oil +``` + +As tenant owner, run the following command to create a namespace in the given tenant + +```bash +kubectl --kubeconfig alice create ns oil-production +kubectl --kubeconfig alice config set-context --current --namespace oil-production +``` + +As tenant owner, creates a pod in the tenant namespace having `imagePullPolicies=IfNotPresent` + +```yaml +kubectl --kubeconfig alice apply -f - << EOF +apiVersion: v1 +kind: Pod +metadata: + name: nginx + namespace: oil-production +spec: + containers: + - name: nginx + image: nginx:latest + imagePullPolicy: IfNotPresent +EOF +``` + +You should receive an error message denying the request: + +``` +Error from server +(ImagePullPolicy IfNotPresent for container nginx is forbidden, use one of the followings: Always): error when creating "STDIN": admission webhook "pods.capsule.clastix.io" denied the request: +ImagePullPolicy IfNotPresent for container nginx is forbidden, use one of the followings: Always +``` + +**Cleanup:** +As cluster admin, delete all the created resources + +```bash +kubectl --kubeconfig cluster-admin delete tenant oil +``` \ No newline at end of file diff --git a/docs/operator/mtb/sig-multitenancy-bench.md b/docs/operator/mtb/sig-multitenancy-bench.md index 5bea8619..28331a30 100644 --- a/docs/operator/mtb/sig-multitenancy-bench.md +++ b/docs/operator/mtb/sig-multitenancy-bench.md @@ -8,8 +8,8 @@ Actually, there's no yet a real standard for the multi-tenancy model in Kubernet |[Block access to cluster resources](block-access-to-cluster-resources.md)|L1|v0.1.0|✓|---| |[Block access to multitenant resources](block-access-to-multitenant-resources.md)|L1|v0.1.0|✓|---| |[Block access to other tenant resources](block-access-to-other-tenant-resources.md)|L1|v0.1.0|✓|MTB draft| -|Block add capabilities|L1|v0.1.0|✓|---| -|Require always imagePullPolicy|L1|v0.1.0|✓|---| +|[Block add capabilities](block-add-capabilities.md)|L1|v0.1.0|✓|---| +|[Require always imagePullPolicy](require-always-imagepullpolicy.md)|L1|v0.1.0|✓|---| |Require run as non-root user|L1|v0.1.0|✓|---| |Block privileged containers|L1|v0.1.0|✓|---| |Block privilege escalation|L1|v0.1.0|✓|---|