mirror of
https://github.com/projectcapsule/capsule.git
synced 2026-08-25 16:07:24 +00:00
docs: add further test cases
This commit is contained in:
committed by
Dario Tranchitella
parent
dcb8b784d5
commit
651c62ff4a
@@ -0,0 +1,77 @@
|
||||
# Allow self-service management of Network Policies
|
||||
|
||||
**Profile Applicability:** L2
|
||||
|
||||
**Type:** Behavioral
|
||||
|
||||
**Category:** Self-Service Operations
|
||||
|
||||
**Description:** Tenants should be able to perform self-service operations by creating own network policies in their namespaces.
|
||||
|
||||
**Rationale:** Enables self-service management of network-policies.
|
||||
|
||||
**Audit:**
|
||||
|
||||
As cluster admin, create a tenant
|
||||
|
||||
```yaml
|
||||
kubectl create -f - <<EOF
|
||||
apiVersion: capsule.clastix.io/v1beta1
|
||||
kind: Tenant
|
||||
metadata:
|
||||
name: oil
|
||||
spec:
|
||||
owners:
|
||||
- kind: User
|
||||
name: alice
|
||||
networkPolicies:
|
||||
items:
|
||||
ingress:
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
capsule.clastix.io/tenant: oil
|
||||
podSelector: {}
|
||||
policyTypes:
|
||||
- Egress
|
||||
- Ingress
|
||||
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, retrieve the networkpolicies resources in the tenant namespace
|
||||
|
||||
```bash
|
||||
kubectl --kubeconfig alice get networkpolicies
|
||||
NAME POD-SELECTOR AGE
|
||||
capsule-oil-0 <none> 7m5s
|
||||
```
|
||||
|
||||
As tenant owner check for permissions to manage networkpolicy for each verb
|
||||
|
||||
```bash
|
||||
kubectl --kubeconfig alice auth can-i get networkpolicies
|
||||
kubectl --kubeconfig alice auth can-i create networkpolicies
|
||||
kubectl --kubeconfig alice auth can-i update networkpolicies
|
||||
kubectl --kubeconfig alice auth can-i patch networkpolicies
|
||||
kubectl --kubeconfig alice auth can-i delete networkpolicies
|
||||
kubectl --kubeconfig alice auth can-i deletecollection networkpolicies
|
||||
```
|
||||
|
||||
Each command must return 'yes'
|
||||
|
||||
**Cleanup:**
|
||||
As cluster admin, delete all the created resources
|
||||
|
||||
```bash
|
||||
kubectl --kubeconfig cluster-admin delete tenant oil
|
||||
```
|
||||
@@ -0,0 +1,58 @@
|
||||
# Allow self-service management of Role Bindings
|
||||
|
||||
**Profile Applicability:** L2
|
||||
|
||||
**Type:** Behavioral
|
||||
|
||||
**Category:** Self-Service Operations
|
||||
|
||||
**Description:** Tenants should be able to perform self-service operations by creating own rolebindings in their namespaces.
|
||||
|
||||
**Rationale:** Enables self-service management of roles.
|
||||
|
||||
**Audit:**
|
||||
|
||||
As cluster admin, create a tenant
|
||||
|
||||
```yaml
|
||||
kubectl create -f - <<EOF
|
||||
apiVersion: capsule.clastix.io/v1beta1
|
||||
kind: Tenant
|
||||
metadata:
|
||||
name: oil
|
||||
spec:
|
||||
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 check for permissions to manage rolebindings for each verb
|
||||
|
||||
```bash
|
||||
kubectl --kubeconfig alice auth can-i get rolebindings
|
||||
kubectl --kubeconfig alice auth can-i create rolebindings
|
||||
kubectl --kubeconfig alice auth can-i update rolebindings
|
||||
kubectl --kubeconfig alice auth can-i patch rolebindings
|
||||
kubectl --kubeconfig alice auth can-i delete rolebindings
|
||||
kubectl --kubeconfig alice auth can-i deletecollection rolebindings
|
||||
```
|
||||
|
||||
Each command must return 'yes'
|
||||
|
||||
**Cleanup:**
|
||||
As cluster admin, delete all the created resources
|
||||
|
||||
```bash
|
||||
kubectl --kubeconfig cluster-admin delete tenant oil
|
||||
```
|
||||
@@ -0,0 +1,58 @@
|
||||
# Allow self-service management of Roles
|
||||
|
||||
**Profile Applicability:** L2
|
||||
|
||||
**Type:** Behavioral
|
||||
|
||||
**Category:** Self-Service Operations
|
||||
|
||||
**Description:** Tenants should be able to perform self-service operations by creating own roles in their namespaces.
|
||||
|
||||
**Rationale:** Enables self-service management of roles.
|
||||
|
||||
**Audit:**
|
||||
|
||||
As cluster admin, create a tenant
|
||||
|
||||
```yaml
|
||||
kubectl create -f - <<EOF
|
||||
apiVersion: capsule.clastix.io/v1beta1
|
||||
kind: Tenant
|
||||
metadata:
|
||||
name: oil
|
||||
spec:
|
||||
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 check for permissions to manage roles for each verb
|
||||
|
||||
```bash
|
||||
kubectl --kubeconfig alice auth can-i get roles
|
||||
kubectl --kubeconfig alice auth can-i create roles
|
||||
kubectl --kubeconfig alice auth can-i update roles
|
||||
kubectl --kubeconfig alice auth can-i patch roles
|
||||
kubectl --kubeconfig alice auth can-i delete roles
|
||||
kubectl --kubeconfig alice auth can-i deletecollection roles
|
||||
```
|
||||
|
||||
Each command must return 'yes'
|
||||
|
||||
**Cleanup:**
|
||||
As cluster admin, delete all the created resources
|
||||
|
||||
```bash
|
||||
kubectl --kubeconfig cluster-admin delete tenant oil
|
||||
```
|
||||
@@ -116,7 +116,7 @@ As tenant owner, try to change/delete the rolebindings in order to escalate per
|
||||
kubectl --kubeconfig alice edit/delete rolebinding namespace:admin
|
||||
```
|
||||
|
||||
You should receive an error message:
|
||||
You must receive an error message:
|
||||
|
||||
```
|
||||
error: rolebindings.rbac.authorization.k8s.io "namespace:admin" could not be patched:
|
||||
|
||||
@@ -69,7 +69,7 @@ As `oil` tenant owner, try to retrieve the resources in the `gas` tenant namespa
|
||||
kubectl --kubeconfig alice get serviceaccounts --namespace gas-production
|
||||
```
|
||||
|
||||
You should receive an eror message:
|
||||
You must receive an eror message:
|
||||
|
||||
```
|
||||
Error from server (Forbidden): serviceaccounts is forbidden:
|
||||
@@ -82,7 +82,7 @@ As `gas` tenant owner, try to retrieve the resources in the `oil` tenant namespa
|
||||
kubectl --kubeconfig joe get serviceaccounts --namespace oil-production
|
||||
```
|
||||
|
||||
You should receive an eror message:
|
||||
You must receive an eror message:
|
||||
|
||||
```
|
||||
Error from server (Forbidden): serviceaccounts is forbidden:
|
||||
|
||||
@@ -109,7 +109,7 @@ spec:
|
||||
EOF
|
||||
```
|
||||
|
||||
You should have the pod blocked by PodSecurityPolicy.
|
||||
You must have the pod blocked by PodSecurityPolicy.
|
||||
|
||||
**Cleanup:**
|
||||
As cluster admin, delete all the created resources
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
# Block access to multitenant resources
|
||||
|
||||
**Profile Applicability:** L1
|
||||
|
||||
**Type:** Behavioral
|
||||
|
||||
**Category:** Tenant Isolation
|
||||
|
||||
**Description:** Block network traffic among namespaces from different tenants.
|
||||
|
||||
**Rationale:** Tenants cannot access services and pods in another tenant's namespaces.
|
||||
|
||||
**Audit:**
|
||||
|
||||
As cluster admin, create a couple of tenants
|
||||
|
||||
```yaml
|
||||
kubectl create -f - <<EOF
|
||||
apiVersion: capsule.clastix.io/v1beta1
|
||||
kind: Tenant
|
||||
metadata:
|
||||
name: oil
|
||||
spec:
|
||||
owners:
|
||||
- kind: User
|
||||
name: alice
|
||||
networkPolicies:
|
||||
items:
|
||||
- ingress:
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
capsule.clastix.io/tenant: oil
|
||||
podSelector: {}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
EOF
|
||||
|
||||
./create-user.sh alice oil
|
||||
```
|
||||
|
||||
and
|
||||
|
||||
```yaml
|
||||
kubectl create -f - <<EOF
|
||||
apiVersion: capsule.clastix.io/v1beta1
|
||||
kind: Tenant
|
||||
metadata:
|
||||
name: gas
|
||||
spec:
|
||||
owners:
|
||||
- kind: User
|
||||
name: joe
|
||||
networkPolicies:
|
||||
items:
|
||||
- ingress:
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
capsule.clastix.io/tenant: gas
|
||||
podSelector: {}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
EOF
|
||||
|
||||
./create-user.sh joe gas
|
||||
```
|
||||
|
||||
As `oil` tenant owner, run the following commands to create a namespace and resources in the given tenant
|
||||
|
||||
```bash
|
||||
kubectl --kubeconfig alice create ns oil-production
|
||||
kubectl --kubeconfig alice config set-context --current --namespace oil-production
|
||||
kubectl --kubeconfig alice run webserver --image nginx:latest
|
||||
kubectl --kubeconfig alice expose pod webserver --port 80
|
||||
```
|
||||
|
||||
As `gas` tenant owner, run the following commands to create a namespace and resources in the given tenant
|
||||
|
||||
```bash
|
||||
kubectl --kubeconfig joe create ns gas-production
|
||||
kubectl --kubeconfig joe config set-context --current --namespace gas-production
|
||||
kubectl --kubeconfig joe run webserver --image nginx:latest
|
||||
kubectl --kubeconfig joe expose pod webserver --port 80
|
||||
```
|
||||
|
||||
As `oil` tenant owner, verify you can access the service in `oil` tenant namespace but not in the `gas` tenant namespace
|
||||
|
||||
```bash
|
||||
kubectl --kubeconfig alice exec webserver -- curl http://webserver.oil-production.svc.cluster.local
|
||||
kubectl --kubeconfig alice exec webserver -- curl http://webserver.gas-production.svc.cluster.local
|
||||
```
|
||||
|
||||
Viceversa, as `gas` tenant owner, verify you can access the service in `gas` tenant namespace but not in the `oil` tenant namespace
|
||||
|
||||
```bash
|
||||
kubectl --kubeconfig alice exec webserver -- curl http://webserver.oil-production.svc.cluster.local
|
||||
kubectl --kubeconfig alice exec webserver -- curl http://webserver.gas-production.svc.cluster.local
|
||||
```
|
||||
|
||||
|
||||
**Cleanup:**
|
||||
As cluster admin, delete all the created resources
|
||||
|
||||
```bash
|
||||
kubectl --kubeconfig cluster-admin delete tenants oil gas
|
||||
```
|
||||
@@ -103,7 +103,7 @@ spec:
|
||||
EOF
|
||||
```
|
||||
|
||||
You should have the pod blocked by `PodSecurityPolicy`.
|
||||
You must have the pod blocked by `PodSecurityPolicy`.
|
||||
|
||||
**Cleanup:**
|
||||
As cluster admin, delete all the created resources
|
||||
|
||||
@@ -104,7 +104,7 @@ spec:
|
||||
EOF
|
||||
```
|
||||
|
||||
You should have the pod blocked by `PodSecurityPolicy`.
|
||||
You must have the pod blocked by `PodSecurityPolicy`.
|
||||
|
||||
**Cleanup:**
|
||||
As cluster admin, delete all the created resources
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
# Block use of existing PVs
|
||||
|
||||
**Profile Applicability:** L1
|
||||
|
||||
**Type:** Configuration Check
|
||||
|
||||
**Category:** Data Isolation
|
||||
|
||||
**Description:** Avoid a tenant to mount existing volumes`.
|
||||
|
||||
**Rationale:** Tenants have to be assured that their Persisten Volumes cannot be reclaimed by other tenants.
|
||||
|
||||
**Audit:**
|
||||
|
||||
As cluster admin, create a tenant
|
||||
|
||||
```yaml
|
||||
kubectl create -f - << EOF
|
||||
apiVersion: capsule.clastix.io/v1beta1
|
||||
kind: Tenant
|
||||
metadata:
|
||||
name: oil
|
||||
spec:
|
||||
owners:
|
||||
- kind: User
|
||||
name: alice
|
||||
EOF
|
||||
|
||||
./create-user.sh alice oil
|
||||
```
|
||||
|
||||
As tenant owner, check if you can access the persistent volumes
|
||||
|
||||
```bash
|
||||
kubectl --kubeconfig alice auth can-i get persistentvolumes
|
||||
kubectl --kubeconfig alice auth can-i list persistentvolumes
|
||||
kubectl --kubeconfig alice auth can-i watch persistentvolumes
|
||||
```
|
||||
|
||||
You must receive for all the requests 'no'.
|
||||
@@ -0,0 +1,115 @@
|
||||
# Block use of host IPC
|
||||
|
||||
**Profile Applicability:** L1
|
||||
|
||||
**Type:** Behavioral Check
|
||||
|
||||
**Category:** Host Isolation
|
||||
|
||||
**Description:** Tenants should not be allowed to share the host's inter-process communication (IPC) namespace.
|
||||
|
||||
**Rationale:** The `hostIPC` setting allows pods to share the host's inter-process communication (IPC) namespace allowing potential access to host processes or processes belonging to other tenants.
|
||||
|
||||
**Audit:**
|
||||
|
||||
As cluster admin, define a `PodSecurityPolicy` that restricts `hostIPC` usage 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
|
||||
hostIPC: false
|
||||
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
|
||||
namespace: oil-production
|
||||
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 mounting the host IPC namespace.
|
||||
|
||||
```yaml
|
||||
kubectl --kubeconfig alice apply -f - << EOF
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: pod-with-host-ipc
|
||||
namespace: oil-production
|
||||
spec:
|
||||
hostIPC: true
|
||||
containers:
|
||||
- name: busybox
|
||||
image: busybox:latest
|
||||
command: ["/bin/sleep", "3600"]
|
||||
EOF
|
||||
```
|
||||
|
||||
You must have the pod blocked by `PodSecurityPolicy`.
|
||||
|
||||
**Cleanup:**
|
||||
As cluster admin, delete all the created resources
|
||||
|
||||
```bash
|
||||
kubectl --kubeconfig cluster-admin delete tenant oil
|
||||
kubectl --kubeconfig cluster-admin delete PodSecurityPolicy tenant
|
||||
kubectl --kubeconfig cluster-admin delete ClusterRole tenant:psp
|
||||
```
|
||||
@@ -22,6 +22,8 @@ metadata:
|
||||
name: tenant
|
||||
spec:
|
||||
privileged: false
|
||||
# Required to prevent escalations to root.
|
||||
allowPrivilegeEscalation: false
|
||||
hostNetwork: false
|
||||
hostPorts: [] # empty means no allowed host ports
|
||||
runAsUser:
|
||||
@@ -122,7 +124,7 @@ spec:
|
||||
EOF
|
||||
```
|
||||
|
||||
In both the cases, you should have the pod blocked by `PodSecurityPolicy`.
|
||||
In both the cases above, you must have the pod blocked by `PodSecurityPolicy`.
|
||||
|
||||
**Cleanup:**
|
||||
As cluster admin, delete all the created resources
|
||||
|
||||
@@ -22,6 +22,8 @@ metadata:
|
||||
name: tenant
|
||||
spec:
|
||||
privileged: false
|
||||
# Required to prevent escalations to root.
|
||||
allowPrivilegeEscalation: false
|
||||
volumes: # hostPath is not permitted
|
||||
- 'configMap'
|
||||
- 'emptyDir'
|
||||
@@ -115,7 +117,7 @@ spec:
|
||||
EOF
|
||||
```
|
||||
|
||||
You should have the pod blocked by `PodSecurityPolicy`.
|
||||
You must have the pod blocked by `PodSecurityPolicy`.
|
||||
|
||||
**Cleanup:**
|
||||
As cluster admin, delete all the created resources
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
# Block use of host PID
|
||||
|
||||
**Profile Applicability:** L1
|
||||
|
||||
**Type:** Behavioral Check
|
||||
|
||||
**Category:** Host Isolation
|
||||
|
||||
**Description:** Tenants should not be allowed to share the host process ID (PID) namespace.
|
||||
|
||||
**Rationale:** The `hostPID` setting allows pods to share the host process ID namespace allowing potential privilege escalation. Tenant pods should not be allowed to share the host PID namespace.
|
||||
|
||||
**Audit:**
|
||||
|
||||
As cluster admin, define a `PodSecurityPolicy` that restricts `hostPID` usage 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
|
||||
hostPID: false
|
||||
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
|
||||
namespace: oil-production
|
||||
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 mounting the host PID namespace.
|
||||
|
||||
```yaml
|
||||
kubectl --kubeconfig alice apply -f - << EOF
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: pod-with-host-pid
|
||||
namespace: oil-production
|
||||
spec:
|
||||
hostPID: true
|
||||
containers:
|
||||
- name: busybox
|
||||
image: busybox:latest
|
||||
command: ["/bin/sleep", "3600"]
|
||||
EOF
|
||||
```
|
||||
|
||||
You must have the pod blocked by `PodSecurityPolicy`.
|
||||
|
||||
**Cleanup:**
|
||||
As cluster admin, delete all the created resources
|
||||
|
||||
```bash
|
||||
kubectl --kubeconfig cluster-admin delete tenant oil
|
||||
kubectl --kubeconfig cluster-admin delete PodSecurityPolicy tenant
|
||||
kubectl --kubeconfig cluster-admin delete ClusterRole tenant:psp
|
||||
```
|
||||
@@ -0,0 +1,75 @@
|
||||
# Block use of NodePort services
|
||||
|
||||
**Profile Applicability:** L1
|
||||
|
||||
**Type:** Behavioral Check
|
||||
|
||||
**Category:** Host Isolation
|
||||
|
||||
**Description:** Tenants should not be able to create services of type NodePort.
|
||||
|
||||
**Rationale:** the service type `NodePorts` configures host ports that cannot be secured using Kubernetes network policies and require upstream firewalls. Also, multiple tenants cannot use the same host port numbers.
|
||||
|
||||
**Audit:**
|
||||
|
||||
As cluster admin, create a tenant
|
||||
|
||||
```yaml
|
||||
kubectl create -f - << EOF
|
||||
apiVersion: capsule.clastix.io/v1beta1
|
||||
kind: Tenant
|
||||
metadata:
|
||||
name: oil
|
||||
spec:
|
||||
enableNodePorts: false
|
||||
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 service in the tenant namespace having service type of `NodePort`
|
||||
|
||||
```yaml
|
||||
kubectl --kubeconfig alice apply -f - << EOF
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: nginx
|
||||
labels:
|
||||
namespace: oil-production
|
||||
spec:
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 8080
|
||||
targetPort: 80
|
||||
selector:
|
||||
run: nginx
|
||||
type: NodePort
|
||||
EOF
|
||||
```
|
||||
|
||||
You must receive an error message denying the request:
|
||||
|
||||
```
|
||||
Error from server
|
||||
Error from server (NodePort service types are forbidden for the tenant:
|
||||
error when creating "STDIN": admission webhook "services.capsule.clastix.io" denied the request:
|
||||
NodePort service types are forbidden for the tenant: please, reach out to the system administrators
|
||||
```
|
||||
|
||||
**Cleanup:**
|
||||
As cluster admin, delete all the created resources
|
||||
|
||||
```bash
|
||||
kubectl --kubeconfig cluster-admin delete tenant oil
|
||||
```
|
||||
@@ -55,7 +55,7 @@ spec:
|
||||
EOF
|
||||
```
|
||||
|
||||
You should receive an error message denying the request:
|
||||
You must receive an error message denying the request:
|
||||
|
||||
```
|
||||
Error from server
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
# Require PersistentVolumeClaim for storage
|
||||
|
||||
**Profile Applicability:** L1
|
||||
|
||||
**Type:** Behavioral Check
|
||||
|
||||
**Category:** na
|
||||
|
||||
**Description:** Tenants should not be able to use all volume types except `PersistentVolumeClaims`.
|
||||
|
||||
**Rationale:** In some scenarios, it would be required to disallow usage of any core volume types except PVCs.
|
||||
|
||||
**Audit:**
|
||||
|
||||
As cluster admin, define a `PodSecurityPolicy` allowing only `PersistentVolumeClaim` volumes 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
|
||||
volumes:
|
||||
- 'persistentVolumeClaim'
|
||||
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
|
||||
namespace: oil-production
|
||||
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 defining a volume of any of the core type except `PersistentVolumeClaim`. For example:
|
||||
|
||||
```yaml
|
||||
kubectl --kubeconfig alice apply -f - << EOF
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: pod-with-hostpath-volume
|
||||
namespace: oil-production
|
||||
spec:
|
||||
containers:
|
||||
- name: busybox
|
||||
image: busybox:latest
|
||||
command: ["/bin/sleep", "3600"]
|
||||
volumeMounts:
|
||||
- mountPath: /tmp
|
||||
name: volume
|
||||
volumes:
|
||||
- name: volume
|
||||
hostPath:
|
||||
# directory location on host
|
||||
path: /data
|
||||
type: Directory
|
||||
EOF
|
||||
```
|
||||
|
||||
You must have the pod blocked by `PodSecurityPolicy`.
|
||||
|
||||
**Cleanup:**
|
||||
As cluster admin, delete all the created resources
|
||||
|
||||
```bash
|
||||
kubectl --kubeconfig cluster-admin delete tenant oil
|
||||
kubectl --kubeconfig cluster-admin delete PodSecurityPolicy tenant
|
||||
kubectl --kubeconfig cluster-admin delete ClusterRole tenant:psp
|
||||
```
|
||||
@@ -0,0 +1,87 @@
|
||||
# Require PV reclaim policy of delete
|
||||
|
||||
**Profile Applicability:** L1
|
||||
|
||||
**Type:** Configuration Check
|
||||
|
||||
**Category:** Data Isolation
|
||||
|
||||
**Description:** Force a tenant to use a Storage Class with `reclaimPolicy=Delete`.
|
||||
|
||||
**Rationale:** Tenants have to be assured that their Persisten Volumes cannot be reclaimed by other tenants.
|
||||
|
||||
**Audit:**
|
||||
|
||||
As cluster admin, create a Storage Class with `reclaimPolicy=Delete`
|
||||
|
||||
```yaml
|
||||
kubectl create -f - << EOF
|
||||
apiVersion: storage.k8s.io/v1
|
||||
kind: StorageClass
|
||||
metadata:
|
||||
name: delete-policy
|
||||
reclaimPolicy: Delete
|
||||
provisioner: clastix.io/nfs
|
||||
EOF
|
||||
```
|
||||
|
||||
As cluster admin, create a tenant and assign the above Storage Class
|
||||
|
||||
```yaml
|
||||
kubectl create -f - << EOF
|
||||
apiVersion: capsule.clastix.io/v1beta1
|
||||
kind: Tenant
|
||||
metadata:
|
||||
name: oil
|
||||
spec:
|
||||
owners:
|
||||
- kind: User
|
||||
name: alice
|
||||
storageClasses:
|
||||
allowed:
|
||||
- delete-policy
|
||||
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 Persistent Volum Claim in the tenant namespace missing the Storage Class or using any other Storage Class:
|
||||
|
||||
```yaml
|
||||
kubectl --kubeconfig alice apply -f - << EOF
|
||||
kind: PersistentVolumeClaim
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: pvc
|
||||
namespace: oil-production
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 12Gi
|
||||
EOF
|
||||
```
|
||||
|
||||
You must receive an error message denying the request:
|
||||
|
||||
```
|
||||
Error from server (A valid Storage Class must be used, one of the following (delete-policy)):
|
||||
error when creating "STDIN": admission webhook "pvc.capsule.clastix.io" denied the request:
|
||||
A valid Storage Class must be used, one of the following (delete-policy)
|
||||
```
|
||||
|
||||
**Cleanup:**
|
||||
As cluster admin, delete all the created resources
|
||||
|
||||
```bash
|
||||
kubectl --kubeconfig cluster-admin delete tenant oil
|
||||
kubectl --kubeconfig cluster-admin delete storageclass delete-policy
|
||||
```
|
||||
@@ -107,7 +107,7 @@ spec:
|
||||
EOF
|
||||
```
|
||||
|
||||
You should have the pod blocked by `PodSecurityPolicy`.
|
||||
You must have the pod blocked by `PodSecurityPolicy`.
|
||||
|
||||
**Cleanup:**
|
||||
As cluster admin, delete all the created resources
|
||||
|
||||
@@ -18,13 +18,13 @@ Actually, there's no yet a real standard for the multi-tenancy model in Kubernet
|
||||
|[Configure namespace object limits](configure-namespace-object-limits.md)|L1|v0.1.0|✓|---|
|
||||
|[Block use of host path volumes](block-use-of-host-path-volumes.md)|L1|v0.1.0|✓|---|
|
||||
|[Block use of host networking and ports](block-use-of-host-networking-and-ports.md)|L1|v0.1.0|✓|---|
|
||||
|Block use of host PID|L1|v0.1.0|✓|---|
|
||||
|Block use of host IPC|L1|v0.1.0|✓|---|
|
||||
|Block use of NodePort services|L1|v0.1.0|✓|---|
|
||||
|Require PersistentVolumeClaim for storage|L1|v0.1.0|✓|MTB draft|
|
||||
|Require PV reclaim policy of delete|L1|v0.1.0|✓|MTB draft|
|
||||
|Block use of existing PVs|L1|v0.1.0|✓|MTB draft|
|
||||
|Block network access across tenant namespaces|L1|v0.1.0|✓|MTB draft|
|
||||
|Allow self-service management of Network PoliciesL2|v0.1.0|✓|---|
|
||||
|Allow self-service management of RolesL2|v0.1.0|✓|MTB draft|
|
||||
|Allow self-service management of Roles Bindings|L2|v0.1.0|✓|MTB draft|
|
||||
|[Block use of host PID](block-use-of-host-pid.md)|L1|v0.1.0|✓|---|
|
||||
|[Block use of host IPC](block-use-of-host-ipc.md)|L1|v0.1.0|✓|---|
|
||||
|[Block use of NodePort services](block-use-of-nodeport-services.md)|L1|v0.1.0|✓|---|
|
||||
|[Require PersistentVolumeClaim for storage](require-persistentvolumeclaim-for-storage.md)|L1|v0.1.0|✓|MTB draft|
|
||||
|[Require PV reclaim policy of delete](require-reclaim-policy-of-delete.md)|L1|v0.1.0|✓|MTB draft|
|
||||
|[Block use of existing PVs](block-use-of-existing-persistent-volumes.md)|L1|v0.1.0|✓|MTB draft|
|
||||
|[Block network access across tenant namespaces](block-network-access-across-tenant-namespaces.md)|L1|v0.1.0|✓|MTB draft|
|
||||
|[Allow self-service management of Network Policies](allow-self-service-management-of-network-policies.md)|L2|v0.1.0|✓|---|
|
||||
|[Allow self-service management of Roles](allow-self-service-management-of-roles.md)|L2|v0.1.0|✓|MTB draft|
|
||||
|[Allow self-service management of Role Bindings](allow-self-service-management-of-rolebindings.md)|L2|v0.1.0|✓|MTB draft|
|
||||
|
||||
Reference in New Issue
Block a user