mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-06 16:06:56 +00:00
Merge commit '8541c37d011948765e99580989351c76bb6e572b' into 387_pv_enforce
This commit is contained in:
commit
d6eb1d3e86
20 changed files with 654 additions and 141 deletions
|
@ -119,6 +119,7 @@ To build Kyverno in a development environment see: https://github.com/nirmata/ky
|
|||
To run controller in this mode you should prepare TLS key/certificate pair for debug webhook, then start controller with kubeconfig and the server address.
|
||||
|
||||
1. Run scripts/deploy-controller-debug.sh --service=localhost --serverIP=<server_IP>, where <server_IP> is the IP address of the host where controller runs. This scripts will generate TLS certificate for debug webhook server and register this webhook in the cluster. Also it registers CustomResource Policy.
|
||||
|
||||
2. Start the controller using the following command: sudo kyverno --kubeconfig=~/.kube/config --serverIP=<server_IP>
|
||||
|
||||
# Try Kyverno without a Kubernetes cluster
|
||||
|
|
34
samples/AssignLinuxCapabilities.md
Normal file
34
samples/AssignLinuxCapabilities.md
Normal file
|
@ -0,0 +1,34 @@
|
|||
# Assign Linux capabilities
|
||||
|
||||
Linux divides the privileges traditionally associated with superuser into distinct units, known as capabilities, which can be independently enabled or disabled by listing them in `securityContext.capabilites`.
|
||||
|
||||
## Policy YAML
|
||||
|
||||
[policy_validate_container_capabilities.yaml](more/policy_validate_container_capabilities.yaml)
|
||||
|
||||
````yaml
|
||||
apiVersion: kyverno.io/v1alpha1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: validate-container-capablities
|
||||
spec:
|
||||
rules:
|
||||
- name: validate-container-capablities
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Pod
|
||||
validate:
|
||||
message: "Allow certain linux capability"
|
||||
pattern:
|
||||
spec:
|
||||
containers:
|
||||
- securityContext:
|
||||
capabilities:
|
||||
add: ["NET_ADMIN"]
|
||||
|
||||
````
|
||||
|
||||
## Additional Information
|
||||
|
||||
* [List of linux capabilities](https://github.com/torvalds/linux/blob/master/include/uapi/linux/capability.h)
|
53
samples/CheckUserGroup.md
Normal file
53
samples/CheckUserGroup.md
Normal file
|
@ -0,0 +1,53 @@
|
|||
# Check userID, groupIP & fsgroup
|
||||
|
||||
All processes inside the pod can be made to run with specific user and groupID by setting `runAsUser` and `runAsGroup` respectively. `fsGroup` can be specified to make sure any file created in the volume with have the specified groupID. These options can be used to validate the IDs used for user and group.
|
||||
|
||||
## Policy YAML
|
||||
|
||||
[policy_validate_user_group_fsgroup_id.yaml](more/policy_validate_user_group_fsgroup_id.yaml)
|
||||
|
||||
````yaml
|
||||
apiVersion: kyverno.io/v1alpha1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: validate-userid-groupid-fsgroup
|
||||
spec:
|
||||
rules:
|
||||
- name: validate-userid
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Pod
|
||||
validate:
|
||||
message: "User ID should be 1000"
|
||||
pattern:
|
||||
spec:
|
||||
securityContext:
|
||||
runAsUser: '1000'
|
||||
- name: validate-groupid
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Pod
|
||||
validate:
|
||||
message: "Group ID should be 3000"
|
||||
pattern:
|
||||
spec:
|
||||
securityContext:
|
||||
runAsGroup: '3000'
|
||||
- name: validate-fsgroup
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Pod
|
||||
validate:
|
||||
message: "fsgroup should be 2000"
|
||||
pattern:
|
||||
spec:
|
||||
securityContext:
|
||||
fsGroup: '2000'
|
||||
# Alls processes inside the pod can be made to run with specific user and groupID by setting runAsUser and runAsGroup respectively.
|
||||
# fsGroup can be specified to make sure any file created in the volume with have the specified groupID.
|
||||
# The above parameters can also be used in a validate policy to restrict user & group IDs.
|
||||
````
|
||||
|
34
samples/ConfigureKernelParmeters.md
Normal file
34
samples/ConfigureKernelParmeters.md
Normal file
|
@ -0,0 +1,34 @@
|
|||
# Configure kernel parameters
|
||||
|
||||
The Sysctl interface allows to modify kernel parameters at runtime and in the pod can be specified under `securityContext.sysctls`. If kernel parameters in the pod are to be modified, should be handled cautiously, and policy with rules restricting these options will be helpful. We can control minimum and maximum port that a network connection can use as its source(local) port by checking net.ipv4.ip_local_port_range
|
||||
|
||||
## Policy YAML
|
||||
|
||||
[policy_validate_sysctl_configs.yaml](more/policy_validate_sysctl_configs.yaml)
|
||||
|
||||
````yaml
|
||||
apiVersion: kyverno.io/v1alpha1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: validate-allow-portrange-with-sysctl
|
||||
spec:
|
||||
rules:
|
||||
- name: allow-portrange-with-sysctl
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Pod
|
||||
validate:
|
||||
message: "Allowed port range is from 1024 to 65535"
|
||||
pattern:
|
||||
spec:
|
||||
securityContext:
|
||||
sysctls:
|
||||
- name: net.ipv4.ip_local_port_range
|
||||
value: "1024 65535"
|
||||
````
|
||||
|
||||
|
||||
## Additional Information
|
||||
|
||||
* [List of supported namespaced sysctl interfaces](https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/)
|
33
samples/DefaultDenyAllIngress.md
Normal file
33
samples/DefaultDenyAllIngress.md
Normal file
|
@ -0,0 +1,33 @@
|
|||
# Default deny all ingress traffic
|
||||
|
||||
By default, Kubernetes allows all ingress and egress traffic to and from pods within a cluster.
|
||||
|
||||
A "default" `NetworkPolicy` should be configured for each namespace to default deny all ingress traffic to the pods in that namespace. Later, the application team can configure additional `NetworkPolicy` resources to allow desired traffic to application pods from select sources.
|
||||
|
||||
## Policy YAML
|
||||
|
||||
[require_default_network_policy.yaml](best_practices/require_default_network_policy.yaml)
|
||||
|
||||
````yaml
|
||||
apiVersion: kyverno.io/v1alpha1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: default-deny-ingress-networkpolicy
|
||||
spec:
|
||||
rules:
|
||||
- name: "default-deny-ingress"
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Namespace
|
||||
name: "*"
|
||||
generate:
|
||||
kind: NetworkPolicy
|
||||
name: default-deny-ingress
|
||||
data:
|
||||
spec:
|
||||
# select all pods in the namespace
|
||||
podSelector: {}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
````
|
36
samples/DisablePrivilegedContainers.md
Normal file
36
samples/DisablePrivilegedContainers.md
Normal file
|
@ -0,0 +1,36 @@
|
|||
# Disable privileged containers
|
||||
|
||||
Privileged containers are defined as any container where the container uid 0 is mapped to the host’s uid 0. A process within a privileged container can get unrestricted host access. With `securityContext.allowPrivilegeEscalation` enabled, a process can gain privileges from its parent.
|
||||
|
||||
To disallow privileged containers and the privilege escalation it is recommended to run pod containers with `securityContext.priveleged` set to `false` and `allowPrivilegeEscalation` set to `false`.
|
||||
|
||||
## Policy YAML
|
||||
|
||||
[disallow_priviledged_priviligedescalation.yaml](best_practices/disallow_priviledged_priviligedescalation.yaml)
|
||||
|
||||
````yaml
|
||||
apiVersion: kyverno.io/v1alpha1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: validate-deny-privileged-priviligedescalation
|
||||
spec:
|
||||
rules:
|
||||
- name: deny-privileged-priviligedescalation
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Pod
|
||||
validate:
|
||||
message: "Privileged mode is not allowed. Set allowPrivilegeEscalation and privileged to false"
|
||||
anyPattern:
|
||||
- spec:
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
privileged: false
|
||||
- spec:
|
||||
containers:
|
||||
- name: "*"
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
privileged: false
|
||||
````
|
30
samples/DisallowAutomountSACredentials.md
Normal file
30
samples/DisallowAutomountSACredentials.md
Normal file
|
@ -0,0 +1,30 @@
|
|||
# Disallow automount of Service Account credentials
|
||||
|
||||
Kubernetes automounts default service account credentials in each pod. To restrict access, opt out of automounting credentials by setting `automountServiceAccountToken` to `false`.
|
||||
|
||||
## Policy YAML
|
||||
|
||||
[disallow_automountingapicred.yaml](best_practices/disallow_automountingapicred.yaml)
|
||||
|
||||
````yaml
|
||||
apiVersion : kyverno.io/v1alpha1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: validate-disallow-automoutingapicred
|
||||
spec:
|
||||
rules:
|
||||
- name: disallow-automoutingapicred
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Pod
|
||||
validate:
|
||||
message: "Deny automounting API credentials"
|
||||
pattern:
|
||||
spec:
|
||||
=(serviceAccountName): "*"
|
||||
automountServiceAccountToken: false
|
||||
````
|
||||
|
||||
|
||||
|
36
samples/DisallowDefaultNamespace.md
Normal file
36
samples/DisallowDefaultNamespace.md
Normal file
|
@ -0,0 +1,36 @@
|
|||
# Disallow use of default namespace
|
||||
|
||||
Kubernetes namespaces provide a way to segment and isolate cluster resources across multiple applictaions and users. It is recommended that each workload be isolated in its own namespace and that use of the default namespace be not allowed.
|
||||
|
||||
## Policy YAML
|
||||
|
||||
[disallow_default_namespace.yaml](best_practices/disallow_default_namespace.yaml)
|
||||
|
||||
````yaml
|
||||
apiVersion: kyverno.io/v1alpha1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: validate-namespace
|
||||
spec:
|
||||
rules:
|
||||
- name: check-default-namespace
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Pod
|
||||
validate:
|
||||
message: "Using 'default' namespace is restricted"
|
||||
pattern:
|
||||
metadata:
|
||||
namespace: "!default"
|
||||
- name: check-namespace-exist
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Pod
|
||||
validate:
|
||||
message: "A namespace is required"
|
||||
pattern:
|
||||
metadata:
|
||||
namespace: "?*"
|
||||
````
|
27
samples/DisallowHostFS.md
Normal file
27
samples/DisallowHostFS.md
Normal file
|
@ -0,0 +1,27 @@
|
|||
# Disallow use of host filesystem
|
||||
|
||||
The volume of type `hostpath` allows pods to use host directories and volume mounted to a host path. This binds pods to a specific host, and data persisted in the volume is coupled to the life of the node. It is highly recommeded that applications are designed to be decoupled from the underlying infrstructure (in this case, nodes).
|
||||
|
||||
## Policy YAML
|
||||
|
||||
[disallow_host_filesystem.yaml](best_practices/disallow_host_filesystem.yaml)
|
||||
|
||||
````yaml
|
||||
apiVersion: "kyverno.io/v1alpha1"
|
||||
kind: "ClusterPolicy"
|
||||
metadata:
|
||||
name: "deny-use-of-host-fs"
|
||||
spec:
|
||||
rules:
|
||||
- name: "deny-use-of-host-fs"
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- "Pod"
|
||||
validate:
|
||||
message: "Host path is not allowed"
|
||||
pattern:
|
||||
spec:
|
||||
volumes:
|
||||
- X(hostPath): null
|
||||
````
|
32
samples/DisallowHostNetworkPort.md
Normal file
32
samples/DisallowHostNetworkPort.md
Normal file
|
@ -0,0 +1,32 @@
|
|||
|
||||
# Disallow `hostNetwork` and `hostPort`
|
||||
|
||||
Using `hostPort` and `hostNetwork` allows pods to share the host networking stack allowing potential snooping of network traffic across application pods.
|
||||
|
||||
## Policy YAML
|
||||
|
||||
[disallow_host_network_hostport.yaml](best_practices/disallow_host_network_hostport.yaml)
|
||||
|
||||
|
||||
````yaml
|
||||
apiVersion: kyverno.io/v1alpha1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: validate-host-network-hostport
|
||||
spec:
|
||||
rules:
|
||||
- name: validate-host-network-hostport
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Pod
|
||||
validate:
|
||||
message: "Defining hostNetwork and hostPort are not allowed."
|
||||
pattern:
|
||||
spec:
|
||||
(hostNetwork): false
|
||||
containers:
|
||||
- name: "*"
|
||||
ports:
|
||||
- hostPort: null
|
||||
````
|
29
samples/DisallowHostPIDIPC.md
Normal file
29
samples/DisallowHostPIDIPC.md
Normal file
|
@ -0,0 +1,29 @@
|
|||
# Disallow `hostPID` and `hostIPC`
|
||||
|
||||
Sharing the host's PID namespace allows an application pod to gain visibility of processes on the host, potentially exposing sensitive information. Sharing the host's IPC namespace also allows the container process to communicate with processes on the host.
|
||||
|
||||
To avoid pod container from having visibility to host process space, validate that `hostPID` and `hostIPC` are set to `false`.
|
||||
|
||||
## Policy YAML
|
||||
|
||||
[disallow_hostpid_hostipc.yaml](best_practices/disallow_hostpid_hostipc.yaml)
|
||||
|
||||
````yaml
|
||||
apiVersion: kyverno.io/v1alpha1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: validate-hostpid-hostipc
|
||||
spec:
|
||||
rules:
|
||||
- name: validate-hostpid-hostipc
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Pod
|
||||
validate:
|
||||
message: "Disallow use of host's pid namespace and host's ipc namespace"
|
||||
pattern:
|
||||
spec:
|
||||
(hostPID): "!true"
|
||||
hostIPC: false
|
||||
````
|
39
samples/DisallowLatestTag.md
Normal file
39
samples/DisallowLatestTag.md
Normal file
|
@ -0,0 +1,39 @@
|
|||
# Disallow latest image tag
|
||||
|
||||
The `:latest` tag is mutable and can lead to unexpected errors if the upstream image changes. A best practice is to use an immutable tag that maps to a specific and tested version of an application pod.
|
||||
|
||||
## Policy YAML
|
||||
|
||||
[require_image_tag_not_latest.yaml](best_practices/require_image_tag_not_latest.yaml)
|
||||
|
||||
|
||||
````yaml
|
||||
apiVersion : kyverno.io/v1alpha1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: validate-image-tag
|
||||
spec:
|
||||
rules:
|
||||
- name: image-tag-notspecified
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Pod
|
||||
validate:
|
||||
message: "Image tag not specified"
|
||||
pattern:
|
||||
spec:
|
||||
containers:
|
||||
- image: "*:*"
|
||||
- name: image-tag-not-latest
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Pod
|
||||
validate:
|
||||
message: "Using 'latest' image tag is restricted. Set image tag to a specific version"
|
||||
pattern:
|
||||
spec:
|
||||
containers:
|
||||
- image: "!*:latest"
|
||||
````
|
30
samples/DisallowUnknownRegistries.md
Normal file
30
samples/DisallowUnknownRegistries.md
Normal file
|
@ -0,0 +1,30 @@
|
|||
# Disallow unknown image registries
|
||||
|
||||
Images from unknown registries may not be scanned and secured. Requiring the use of trusted registries helps reduce threat exposure.
|
||||
|
||||
You can customize this policy to allow image registries that you trust.
|
||||
|
||||
## Policy YAML
|
||||
|
||||
[trusted_image_registries.yaml](best_practices/trusted_image_registries.yaml)
|
||||
|
||||
````yaml
|
||||
apiVersion : kyverno.io/v1alpha1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: trusted-registries
|
||||
spec:
|
||||
rules:
|
||||
- name: trusted-registries
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Pod
|
||||
validate:
|
||||
message: "Deny untrusted registries"
|
||||
pattern:
|
||||
spec:
|
||||
containers:
|
||||
- image: "k8s.gcr.io/* | gcr.io/*"
|
||||
|
||||
````
|
33
samples/LimitNodePort.md
Normal file
33
samples/LimitNodePort.md
Normal file
|
@ -0,0 +1,33 @@
|
|||
# Limit `NodePort` services
|
||||
|
||||
A Kubernetes service of type `NodePort` uses a host port (on every node in the cluster) to receive traffic from any source.
|
||||
|
||||
Kubernetes Network Policies cannot be used to control traffic to host ports.
|
||||
|
||||
Although NodePort services can be useful, their use should be limited to services with additional upstream security checks.
|
||||
|
||||
## Policy YAML
|
||||
|
||||
[disallow_node_port.yaml](best_practices/disallow_node_port.yaml)
|
||||
|
||||
````yaml
|
||||
|
||||
apiVersion: kyverno.io/v1alpha1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: disallow-node-port
|
||||
spec:
|
||||
rules:
|
||||
- name: disallow-node-port
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Service
|
||||
validate:
|
||||
message: "Disallow service of type NodePort"
|
||||
pattern:
|
||||
spec:
|
||||
type: "!NodePort"
|
||||
|
||||
````
|
||||
|
|
@ -1,157 +1,53 @@
|
|||
# Best Practice Policies
|
||||
# Sample Policies
|
||||
|
||||
Best practice policies are designed to be applied to your Kubernetes clusters with minimal changes. To import these policies [install Kyverno](../documentation/installation.md) and import the resources as follows:
|
||||
Sample policies are designed to be applied to your Kubernetes clusters with minimal changes. To apply these policies to your cluster, install Kyverno and import the policies as follows:
|
||||
|
||||
**Install Kyverno**
|
||||
|
||||
````sh
|
||||
kubectl create -f https://github.com/nirmata/kyverno/raw/master/definitions/install.yaml
|
||||
````
|
||||
<small>[(installation docs)](../documentation/installation.md)</small>
|
||||
|
||||
**Apply Kyverno Policies**
|
||||
|
||||
````bash
|
||||
|
||||
kubectl create -f https://github.com/nirmata/kyverno/raw/master/samples/best_practices/
|
||||
|
||||
kubectl create -f https://github.com/nirmata/kyverno/raw/master/samples/more/
|
||||
|
||||
````
|
||||
|
||||
More information on each best-practice policy is provided below:
|
||||
The policies are mostly validation rules in `audit` mode i.e. your existing workloads will not be impacted, but will be audited for policy complaince.
|
||||
|
||||
## Run as non-root user
|
||||
## Best Practice Policies
|
||||
|
||||
By default, processes in a container run as a root user (uid 0). To prevent potential compromise of container hosts, specify a least privileged user ID when building the container image and require that application containers run as non root users i.e. set `runAsNonRoot` to `true`.
|
||||
These policies are highly recommended.
|
||||
|
||||
***Policy YAML***: [deny_runasrootuser.yaml](best_practices/deny_runasrootuser.yaml)
|
||||
1. [Run as non-root user](RunAsNonRootUser.md)
|
||||
2. [Disable privileged containers and disallow privilege escalation](DisablePrivilegedContainers.md)
|
||||
3. [Require Read-only root filesystem](RequireReadOnlyFS.md)
|
||||
4. [Disallow use of host filesystem](DisallowHostFS.md)
|
||||
5. [Disallow `hostNetwork` and `hostPort`](DisallowHostNetworkPort.md)
|
||||
6. [Disallow `hostPID` and `hostIPC`](DisallowHostPIDIPC.md)
|
||||
7. [Disallow unknown image registries](DisallowUnknownRegistries.md)
|
||||
8. [Disallow latest image tag](DisallowLatestTag.md)
|
||||
9. [Disallow use of default namespace](DisallowDefaultNamespace.md)
|
||||
10. [Require namespace limits and quotas](RequireNSLimitsQuotas.md)
|
||||
11. [Require pod resource requests and limits](RequirePodRequestsLimits.md)
|
||||
12. [Require pod `livenessProbe` and `readinessProbe`](RequirePodProbes.md)
|
||||
13. [Default deny all ingress traffic](DefaultDenyAllIngress.md)
|
||||
|
||||
**Additional Information**
|
||||
* [Pod Security Context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
|
||||
|
||||
## Additional Policies
|
||||
|
||||
## Disallow automount of Service Account credentials
|
||||
The policies provide additional best practices and are worthy of close consideration. These policies may require workload specific changes.
|
||||
|
||||
Kubernetes automounts default service account credentials in each pod. To restrict access, opt out of automounting credentials by setting `automountServiceAccountToken` to `false`.
|
||||
14. [Limit use of `NodePort` services](LimitNodePort.md)
|
||||
15. [Limit automount of Service Account credentials](DisallowAutomountSACredentials.md)
|
||||
16. [Configure Linux Capabilities](AssignLinuxCapabilities.md)
|
||||
17. [Limit Kernel parameter access](ConfigureKernelParmeters.md)
|
||||
|
||||
***Policy YAML***: [disallow_automountingapicred.yaml](best_practices/disallow_automountingapicred.yaml)
|
||||
|
||||
|
||||
## Disallow use of default namespace
|
||||
|
||||
With many users spread across multiple teams, restricting use of the default namespace and subdividing the cluster by namesoace isolates workloads.
|
||||
|
||||
***Policy YAML***: [disallow_default_namespace.yaml](best_practices/disallow_default_namespace.yaml)
|
||||
|
||||
|
||||
## Disallow use of host filesystem
|
||||
|
||||
The volume of type `hostpath` binds pods to a specific host, and data persisted in the volume is dependent on the life of the node. In a shared cluster, it is recommeded that applications are independent of hosts.
|
||||
|
||||
***Policy YAML***: [disallow_host_filesystem.yaml](best_practices/disallow_host_filesystem.yaml)
|
||||
|
||||
|
||||
## Disallow `hostNetwork` and `hostPort`
|
||||
|
||||
Using `hostPort` and `hostNetwork` allows pods to share the host network stack, allowing potential snooping of network traffic from an application pod.
|
||||
|
||||
***Policy YAML***: [disallow_host_network_hostport.yaml](best_practices/disallow_host_network_hostport.yaml)
|
||||
|
||||
|
||||
## Disallow `hostPID` and `hostIPC`
|
||||
|
||||
Sharing the host's PID namespace allows visibility of process on the host, potentially exposing process information.
|
||||
Sharing the host's IPC namespace allows the container process to communicate with processes on the host. To avoid pod container from having visibility to host process space, validate that `hostPID` and `hostIPC` are set to `false`.
|
||||
|
||||
***Policy YAML***: [disallow_hostpid_hostipc.yaml](best_practices/disallow_hostpid_hostipc.yaml)
|
||||
|
||||
|
||||
## Restrict service type `NodePort`
|
||||
|
||||
A Kubernetes service of type NodePort uses a host port to receive traffic from any source. A `NetworkPolicy` resource cannot be used to control traffic to host ports. Although `NodePort` services can be useful, their use must be limited to services with additional upstream security checks.
|
||||
|
||||
***Policy YAML***: [disallow_node_port.yaml](best_practices/disallow_node_port.yaml)
|
||||
|
||||
|
||||
## Disable privileged containers
|
||||
|
||||
Privileged containers are defined as any container where the container uid 0 is mapped to the host’s uid 0. A process within privileged containers can get unrestricted host access. With `securityContext.allowPrivilegeEscalation` enabled a process can gain privileges from its parent.
|
||||
To disallow privileged containers and the escalation of privileges it is recommended to run pod containers with `securityContext.priveleged` as `false` and `allowPrivilegeEscalation` as `false`.
|
||||
|
||||
***Policy YAML***: [disallow_priviledged_priviligedescalation.yaml](best_practices/disallow_priviledged_priviligedescalation.yaml)
|
||||
|
||||
## Default deny all ingress traffic
|
||||
|
||||
By default, Kubernetes allows all ingress and egress traffic to and from pods within a cluster. A "default" `NetworkPolicy` resource for a namespace should be used to deny all ingress traffic to the pods in that namespace. Additional `NetworkPolicy` resources can then be configured to allow desired traffic to application pods.
|
||||
|
||||
***Policy YAML***: [require_default_network_policy.yaml](best_practices/require_default_network_policy.yaml)
|
||||
|
||||
|
||||
## Disallow latest image tag
|
||||
|
||||
The `:latest` tag is mutable and can lead to unexpected errors if the image changes. A best practice is to use an immutable tag that maps to a specific version of an application pod.
|
||||
|
||||
***Policy YAML***: [require_image_tag_not_latest.yaml](best_practices/require_image_tag_not_latest.yaml)
|
||||
|
||||
## Configure namespace limits and quotas
|
||||
|
||||
To limit the number of objects, as well as the total amount of compute that may be consumed by an application, it is important to create resource limits and quotas for each namespace.
|
||||
|
||||
***Policy YAML***: [require_namespace_quota.yaml](best_practices/require_namespace_quota.yaml)
|
||||
|
||||
**Additional Information**
|
||||
* [Resource Quota](https://kubernetes.io/docs/concepts/policy/resource-quotas/)
|
||||
|
||||
|
||||
## Require pod resource requests and limits
|
||||
|
||||
As application workloads share cluster resources, it is important to limit resources requested and consumed by each pod. It is recommended to require `resources.requests` and `resources.limits` per pod. If a namespace level request or limit is specified, defaults will automatically be applied to each pod based on the `LimitRange` configuration.
|
||||
|
||||
***Policy YAML***: [require_pod_requests_limits.yaml](best_practices/require_pod_requests_limits.yaml)
|
||||
|
||||
|
||||
## Require `livenessProbe` and `readinessProbe`
|
||||
|
||||
For each pod, a `livenessProbe` is carried out by the kubelet to determine when to restart a container. A `readinessProbe` is used by services and deployments to determine if the pod is ready to recieve network traffic.
|
||||
Both liveness and readiness probes need to be configured to manage the pod lifecycle during restarts and upgrades.
|
||||
|
||||
***Policy YAML***: [require_probes.yaml](best_practices/require_probes.yaml)
|
||||
|
||||
|
||||
## Read-only root filesystem
|
||||
|
||||
A read-only root file system helps to enforce an immutable infrastructure strategy; the container only needs to write on the mounted volume that persists the state. An immutable root filesystem can also prevent malicious binaries from writing to the host system.
|
||||
|
||||
***Policy YAML***: [require_readonly_rootfilesystem.yaml](best_practices/require_readonly_rootfilesystem.yaml)
|
||||
|
||||
|
||||
## Disallow unknown image registries
|
||||
|
||||
Images from unknown registries may not be scanned and secured. Requiring use of known registries helps reduce threat exposure. You can customize this policy to allow image registries that you trust.
|
||||
|
||||
***Policy YAML***: [trusted_image_registries.yaml](best_practices/trusted_image_registries.yaml)
|
||||
|
||||
|
||||
# More Policies
|
||||
|
||||
The policies listed here provide additional best practices that should be considered for production use. These policies may require workload specific configutration.
|
||||
|
||||
## Assign Linux capabilities inside Pod
|
||||
|
||||
Linux divides the privileges traditionally associated with superuser into distinct units, known as capabilities, which can be independently enabled or disabled by listing them in `securityContext.capabilites`.
|
||||
|
||||
***Policy YAML***: [policy_validate_container_capabilities.yaml](more/policy_validate_container_capabilities.yaml)
|
||||
|
||||
**Additional Information**
|
||||
* [List of linux capabilities](https://github.com/torvalds/linux/blob/master/include/uapi/linux/capability.h)
|
||||
|
||||
|
||||
## Check userID, groupIP & fsgroup used inside a Pod
|
||||
All processes inside the pod can be made to run with specific user and groupID by setting `runAsUser` and `runAsGroup` respectively. `fsGroup` can be specified to make sure any file created in the volume with have the specified groupID. These options can be used to validate the IDs used for user and group.
|
||||
|
||||
***Policy YAML***: [policy_validate_user_group_fsgroup_id.yaml](more/policy_validate_user_group_fsgroup_id.yaml)
|
||||
|
||||
|
||||
## Configure kernel parameters inside pod
|
||||
|
||||
The Sysctl interface allows to modify kernel parameters at runtime and in the pod can be specified under `securityContext.sysctls`. If kernel parameters in the pod are to be modified, should be handled cautiously, and policy with rules restricting these options will be helpful. We can control minimum and maximum port that a network connection can use as its source(local) port by checking net.ipv4.ip_local_port_range
|
||||
|
||||
***Policy YAML***: [policy_validate_sysctl_configs.yaml](more/policy_validate_sysctl_configs.yaml)
|
||||
|
||||
**Additional Information**
|
||||
* [List of supported namespaced sysctl interfaces](https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/)
|
||||
|
||||
|
||||
## Check userID, groupIP & fsgroup used inside a Pod
|
||||
|
||||
All processes inside the pod can be made to run with specific user and groupID by setting `runAsUser` and `runAsGroup` respectively. `fsGroup` can be specified to make sure any file created in the volume with have the specified groupID. These options can be used to validate the IDs used for user and group.
|
||||
|
||||
***Policy YAML***: [policy_validate_user_group_fsgroup_id.yaml](more/policy_validate_user_group_fsgroup_id.yaml)
|
||||
|
|
35
samples/RequireNSLimitsQuotas.md
Normal file
35
samples/RequireNSLimitsQuotas.md
Normal file
|
@ -0,0 +1,35 @@
|
|||
# Configure namespace limits and quotas
|
||||
|
||||
To limit the number of resources like CPU and memory, as well as objects that may be consumed by workloads in a namespace, it is important to configure resource limits and quotas for each namespace.
|
||||
|
||||
## Additional Information
|
||||
|
||||
* [Resource Quota](https://kubernetes.io/docs/concepts/policy/resource-quotas/)
|
||||
|
||||
## Policy YAML
|
||||
|
||||
[require_namespace_quota.yaml](best_practices/require_namespace_quota.yaml)
|
||||
|
||||
````yaml
|
||||
apiVersion: kyverno.io/v1alpha1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: validate-namespace-quota
|
||||
spec:
|
||||
rules:
|
||||
- name: validate-namespace-quota
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Namespace
|
||||
generate:
|
||||
kind: ResourceQuota
|
||||
name: "defaultresourcequota"
|
||||
spec:
|
||||
hard:
|
||||
requests.cpu: "*"
|
||||
requests.memory: "*"
|
||||
limits.cpu: "*"
|
||||
limits.memory: "*"
|
||||
````
|
||||
|
34
samples/RequirePodProbes.md
Normal file
34
samples/RequirePodProbes.md
Normal file
|
@ -0,0 +1,34 @@
|
|||
# Require `livenessProbe` and `readinessProbe`
|
||||
|
||||
For each pod, a `livenessProbe` is carried out by the kubelet to determine if containers are running and when to restart the pod. A `readinessProbe` is used by services and deployments to determine if the pod is ready to recieve network traffic.
|
||||
|
||||
Both liveness and readiness probes need to be configured to manage the pod lifecycle during restarts and upgrades.
|
||||
|
||||
## Policy YAML
|
||||
|
||||
[require_probes.yaml](best_practices/require_probes.yaml)
|
||||
|
||||
````yaml
|
||||
apiVersion: kyverno.io/v1alpha1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: validate-probes
|
||||
spec:
|
||||
rules:
|
||||
- name: check-probes
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Pod
|
||||
validate:
|
||||
message: "Liveness and readiness probes are required"
|
||||
pattern:
|
||||
spec:
|
||||
containers:
|
||||
- livenessProbe:
|
||||
periodSeconds: ">0"
|
||||
readinessProbe:
|
||||
periodSeconds: ">0"
|
||||
|
||||
````
|
||||
|
36
samples/RequirePodRequestsLimits.md
Normal file
36
samples/RequirePodRequestsLimits.md
Normal file
|
@ -0,0 +1,36 @@
|
|||
# Require pod resource requests and limits
|
||||
|
||||
Application workloads share cluster resources. Hence, it is important to manage resources assigned for each pod. It is recommended that `resources.requests` and `resources.limits` are configured per pod and include CPU and memory resources. Other resources such as, GPUs, may also be specified as needed.
|
||||
|
||||
If a namespace level request or limit is specified, defaults will automatically be applied to each pod based on the `LimitRange` configuration.
|
||||
|
||||
## Policy YAML
|
||||
|
||||
[require_pod_requests_limits.yaml](best_practices/require_pod_requests_limits.yaml)
|
||||
|
||||
````yaml
|
||||
apiVersion: kyverno.io/v1alpha1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: check-resource
|
||||
spec:
|
||||
validationFailureAction: "audit"
|
||||
rules:
|
||||
- name: check-resource-request-limit
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Pod
|
||||
validate:
|
||||
message: "CPU and memory resource requests and limits are required"
|
||||
pattern:
|
||||
spec:
|
||||
containers:
|
||||
- resources:
|
||||
requests:
|
||||
memory: "?*"
|
||||
cpu: "?*"
|
||||
limits:
|
||||
memory: "?*"
|
||||
cpu: "?*"
|
||||
````
|
29
samples/RequireReadOnlyFS.md
Normal file
29
samples/RequireReadOnlyFS.md
Normal file
|
@ -0,0 +1,29 @@
|
|||
# Require Read-only root filesystem
|
||||
|
||||
A read-only root file system helps to enforce an immutable infrastructure strategy; the container only needs to write on mounted volumes that can persist state even if the container exits. An immutable root filesystem can also prevent malicious binaries from writing to the host system.
|
||||
|
||||
## Policy YAML
|
||||
|
||||
[require_readonly_rootfilesystem.yaml](best_practices/require_readonly_rootfilesystem.yaml)
|
||||
|
||||
|
||||
````yaml
|
||||
apiVersion: kyverno.io/v1alpha1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: validate-readonly-rootfilesystem
|
||||
spec:
|
||||
rules:
|
||||
- name: validate-readonly-rootfilesystem
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Pod
|
||||
validate:
|
||||
message: "Container require read-only rootfilesystem"
|
||||
pattern:
|
||||
spec:
|
||||
containers:
|
||||
- securityContext:
|
||||
readOnlyRootFilesystem: true
|
||||
````
|
36
samples/RunAsNonRootUser.md
Normal file
36
samples/RunAsNonRootUser.md
Normal file
|
@ -0,0 +1,36 @@
|
|||
# Run as non-root user
|
||||
|
||||
By default, all processes in a container run as the root user (uid 0). To prevent potential compromise of container hosts, specify a non-root and least privileged user ID when building the container image and require that application containers run as non root users i.e. set `runAsNonRoot` to `true`.
|
||||
|
||||
## Additional Information
|
||||
|
||||
* [Pod Security Context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/)
|
||||
|
||||
## Policy YAML
|
||||
|
||||
[deny_runasrootuser.yaml](best_practices/deny_runasrootuser.yaml)
|
||||
|
||||
````yaml
|
||||
apiVersion: kyverno.io/v1alpha1
|
||||
kind: ClusterPolicy
|
||||
metadata:
|
||||
name: validate-deny-runasrootuser
|
||||
spec:
|
||||
rules:
|
||||
- name: deny-runasrootuser
|
||||
match:
|
||||
resources:
|
||||
kinds:
|
||||
- Pod
|
||||
validate:
|
||||
message: "Root user is not allowed. Set runAsNonRoot to true."
|
||||
anyPattern:
|
||||
- spec:
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
- spec:
|
||||
containers:
|
||||
- name: "*"
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
````
|
Loading…
Add table
Reference in a new issue