Skip to content

Commit

Permalink
feat: helm chart inside infrastracture/policies. infrastracture/polic…
Browse files Browse the repository at this point in the history
…ies/README.md updated with the applied policies.

Co-authored-by: Grazia D'Onghia <graziadonghia925@gmail.com>
  • Loading branch information
CosimoMichelagnoli and graziadonghia committed Jun 15, 2022
1 parent dc70807 commit c5734a1
Show file tree
Hide file tree
Showing 15 changed files with 446 additions and 2 deletions.
7 changes: 5 additions & 2 deletions deploy/crownlabs/Chart.lock
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,8 @@ dependencies:
- name: exam-agent
repository: file://../../operators/deploy/exam-agent
version: 0.1.0
digest: sha256:5e61e140806766e46aa2014b018ba66c40653756b213e3ff042782b0d662a6a8
generated: "2022-04-02T18:37:42.140831116+02:00"
- name: policies
repository: file://../../infrastructure/policies
version: 0.1.0
digest: sha256:d437e7bcf1d2e6fad4f108c8db5e46a6a03c3e4dc390a43a50a78614f20afd2c
generated: "2022-06-07T17:08:49.93116647+02:00"
5 changes: 5 additions & 0 deletions deploy/crownlabs/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,8 @@ dependencies:
version: "0.1.0"
repository: file://../../operators/deploy/exam-agent
condition: exam-agent.enabled

- name: policies
version: "0.1.0"
repository: file://../../infrastructure/policies
condition: policies.enabled
5 changes: 5 additions & 0 deletions deploy/crownlabs/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,8 @@ exam-agent:
image:
repository: crownlabs/exam-agent
pullPolicy: IfNotPresent

policies:
host: s??????.sandbox.crownlabs.polito.it
policiesLabels:
crownlabs.polito.it/type: sandbox
23 changes: 23 additions & 0 deletions infrastructure/policies/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
20 changes: 20 additions & 0 deletions infrastructure/policies/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
apiVersion: v2
name: policies
description: A set of policies for Sandbox namespace

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.0

icon: https://crownlabs.polito.it/images/logo.svg
39 changes: 39 additions & 0 deletions infrastructure/policies/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
## About Kyverno
[Kyverno](https://kyverno.io/) is a policy engine designed specifically for Kubernetes. With Kyverno, policies are managed as Kubernetes resources and no new language is required to write policies. This allows using familiar tools such as kubectl , git , and kustomize to manage policies.

## How Kyverno works
Kyverno runs as a dynamic admission controller in a Kubernetes cluster. Kyverno receives validating and mutating admission webhook HTTP callbacks from the kube-apiserver and applies matching policies to return results that enforce admission policies or reject requests.

### Installing the Chart
Before installing the chart, the Kyverno repository must be added to helm with the following command:

```bash
helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update
helm install kyverno kyverno/kyverno --namespace kyverno --create-namespace
```

# Kyverno policies for sandbox namespaces in CrownLabs
This folder contains a first version of the policy which aims to manage the security requirements in the Crownlabs cluster. This policies are restricted to the sandbox namespace. Three main security requirements, grouped by the “least privilege principle”:
- Avoid creation of privileged pods:
- privileged pods have the ability to reach out of namespace objects.
- Avoid creation of load balancer services (i.e avoid creation of routable IPs) and nodePort:
- if every student creates a load balancer then all IP addresses might be used.
- Force specific name for ingress hostname.

The above mentioned policies were mostly taken from [Kyverno Best Practices.](https://kyverno.io/policies/?policytypes=Best%2520Practices)

## Policies
A Kyverno policy is a collection of rules. Each rule consists of a match declaration, an optional exclude declaration, and one of a validate, mutate, generate, or verifyImages declaration. Each rule can contain only a single validate, mutate, generate, or verifyImages child declaration.
This initial set of policies is of the resources validation type. When a new resource is created by a user or process into the sandbox namespace,the properties of that resource are checked by Kyverno against the validate rule. If those properties are validated, meaning there is agreement, the resource is allowed to be created. If those properties are different, the creation is blocked.
### Avoid creation of privileged pods
Pods are configured to follow security best practices:
- `runAsNonRoot` is set to `true`
- `privileged` is set to `false`
- `allowPrivilegeEscalation` is set to `false`
### Avoid creation of load balancer and nodePort services
- **Disallow Service Type LoadBalancer**: This policy restricts use of the Service type LoadBalancer.
- **Disallow NodePort**: This policy validates that any new Services do not use the `NodePort` type.
### Force specific name for ingress hostname
- **Disallow empty Ingress host**: This policy ensures that there is a hostname for each rule defined.
- **Restrict Ingress host**: This policy ensures thatthe hostname has the required format.
52 changes: 52 additions & 0 deletions infrastructure/policies/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "policies.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "policies.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}

{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "policies.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Common labels
*/}}
{{- define "policies.labels" -}}
helm.sh/chart: {{ include "policies.chart" . }}
{{ include "policies.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{/*
Selector labels
*/}}
{{- define "policies.selectorLabels" -}}
app.kubernetes.io/name: {{ include "policies.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
36 changes: 36 additions & 0 deletions infrastructure/policies/templates/disallow_empty_host.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: {{ include "policies.fullname" . }}-disallow-empty-ingress-host
labels:
{{- include "policies.labels" . | nindent 4 }}
annotations:
policies.kyverno.io/title: Disallow empty Ingress host
policies.kyverno.io/category: Best Practices
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Ingress
policies.kyverno.io/description: >-
An ingress resource needs to define an actual host name
in order to be valid. This policy ensures that there is a
hostname for each rule defined.
spec:
validationFailureAction: enforce
background: false
rules:
- name: disallow-empty-ingress-host
match:
resources:
kinds:
- Ingress
namespaceSelector:
{{- with .Values.policiesLabels }}
matchLabels:
{{- toYaml . | nindent 14 }}
{{- end }}
validate:
message: "The Ingress host name must be defined, not empty."
deny:
conditions:
- key: "{{printf "{{request.object.spec.rules[].host || `[]` | length(@) }}"}}"
operator: NotEquals
value: "{{printf "{{ request.object.spec.rules[].http || `[]` | length(@) }}"}}"
36 changes: 36 additions & 0 deletions infrastructure/policies/templates/disallow_loadbalancer.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: {{ include "policies.fullname" . }}-no-loadbalancer
labels:
{{- include "policies.labels" . | nindent 4 }}
annotations:
policies.kyverno.io/title: Disallow Service Type LoadBalancer
policies.kyverno.io/category: Sample
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Service
policies.kyverno.io/description: >-
Especially in cloud provider environments, a Service having type LoadBalancer will cause the
provider to respond by creating a load balancer somewhere in the customer account. This adds
cost and complexity to a deployment. Without restricting this ability, users may easily
overrun established budgets and security practices set by the organization. This policy restricts
use of the Service type LoadBalancer.
spec:
validationFailureAction: enforce
background: true
rules:
- name: no-LoadBalancer
match:
resources:
kinds:
- Service
namespaceSelector:
{{- with .Values.policiesLabels }}
matchLabels:
{{- toYaml . | nindent 12 }}
{{- end }}
validate:
message: "Service of type LoadBalancer is not allowed."
pattern:
spec:
type: "!LoadBalancer"
36 changes: 36 additions & 0 deletions infrastructure/policies/templates/disallow_nodeport.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: {{ include "policies.fullname" . }}-no-nodeport
labels:
{{- include "policies.labels" . | nindent 4 }}
annotations:
policies.kyverno.io/title: Disallow NodePort
policies.kyverno.io/category: Best Practices
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Service
policies.kyverno.io/description: >-
A Kubernetes Service of type NodePort uses a host port to receive traffic from
any source. A NetworkPolicy 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. This policy validates that any new Services
do not use the `NodePort` type.
spec:
validationFailureAction: enforce
background: true
rules:
- name: no-Nodeport
match:
resources:
kinds:
- Service
namespaceSelector:
{{- with .Values.policiesLabels }}
matchLabels:
{{- toYaml . | nindent 12 }}
{{- end }}
validate:
message: "Services of type NodePort are not allowed."
pattern:
spec:
type: "!NodePort"
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: {{ include "policies.fullname" . }}-privilege-escalation
labels:
{{- include "policies.labels" . | nindent 4 }}
annotations:
policies.kyverno.io/title: Disallow Privilege Escalation
policies.kyverno.io/category: Pod Security Standards (Restricted)
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
kyverno.io/kyverno-version: 1.6.0
kyverno.io/kubernetes-version: "1.22-1.23"
policies.kyverno.io/description: >-
Privilege escalation, such as via set-user-ID or set-group-ID file mode, should not be allowed.
This policy ensures the `allowPrivilegeEscalation` field is set to `false`.
spec:
validationFailureAction: enforce
background: true
rules:
- name: privilege-escalation
match:
any:
- resources:
kinds:
- Pod
namespaceSelector:
{{- with .Values.policiesLabels }}
matchLabels:
{{- toYaml . | nindent 16 }}
{{- end }}
validate:
message: message: >-
Privilege escalation is disallowed. The fields
spec.containers[*].securityContext.allowPrivilegeEscalation,
spec.initContainers[*].securityContext.allowPrivilegeEscalation,
and spec.ephemeralContainers[*].securityContext.allowPrivilegeEscalation
must be set to `false`.
pattern:
spec:
=(ephemeralContainers):
- securityContext:
allowPrivilegeEscalation: "false"
=(initContainers):
- securityContext:
allowPrivilegeEscalation: "false"
containers:
- securityContext:
allowPrivilegeEscalation: "false"
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: {{ include "policies.fullname" . }}-privileged-containers
labels:
{{- include "policies.labels" . | nindent 4 }}
annotations:
policies.kyverno.io/title: Disallow Privileged Containers
policies.kyverno.io/category: Pod Security Standards (Baseline)
policies.kyverno.io/severity: medium
policies.kyverno.io/subject: Pod
kyverno.io/kyverno-version: 1.6.0
kyverno.io/kubernetes-version: "1.22-1.23"
policies.kyverno.io/description: >-
Privileged mode disables most security mechanisms and must not be allowed. This policy
ensures Pods do not call for privileged mode.
spec:
validationFailureAction: enforce
background: true
rules:
- name: privileged-containers
match:
any:
- resources:
kinds:
- Pod
namespaceSelector:
{{- with .Values.policiesLabels }}
matchLabels:
{{- toYaml . | nindent 16 }}
{{- end }}
validate:
message: >-
Privileged mode is disallowed. The fields spec.containers[*].securityContext.privileged
and spec.initContainers[*].securityContext.privileged must be unset or set to `false`.
pattern:
spec:
=(ephemeralContainers):
- =(securityContext):
=(privileged): "false"
=(initContainers):
- =(securityContext):
=(privileged): "false"
containers:
- =(securityContext):
=(privileged): "false"
Loading

0 comments on commit c5734a1

Please sign in to comment.