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 14, 2022
1 parent dc70807 commit 7778f20
Show file tree
Hide file tree
Showing 15 changed files with 487 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
3 changes: 3 additions & 0 deletions deploy/crownlabs/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,6 @@ exam-agent:
image:
repository: crownlabs/exam-agent
pullPolicy: IfNotPresent

policies:
createSandbox: true
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 }}
31 changes: 31 additions & 0 deletions infrastructure/policies/templates/disallow_empty_host.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: {{ include "policies.fullname" . }}-disallow-empty-ingress-host
labels:
{{- include "policies.labels" . | nindent 4 }}
{{- with .Values.disallowEmptyHost.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
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: {{ .Values.disallowEmptyHost.message}}
deny:
conditions:
- key: "{{printf "{{request.object.spec.rules[].host || `[]` | length(@) }}"}}"
operator: NotEquals
value: "{{printf "{{ request.object.spec.rules[].http || `[]` | length(@) }}"}}"
29 changes: 29 additions & 0 deletions infrastructure/policies/templates/disallow_loadbalancer.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: {{ include "policies.fullname" . }}-no-loadbalancer
labels:
{{- include "policies.labels" . | nindent 4 }}
{{- with .Values.disallowLoadBalancer.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
validationFailureAction: enforce
background: true
rules:
- name: no-LoadBalancer
match:
resources:
kinds:
- Service
namespaceSelector:
{{- with .Values.policiesLabels }}
matchLabels:
{{- toYaml . | nindent 12 }}
{{- end }}
validate:
message: {{ .Values.disallowLoadBalancer.message }}
pattern:
spec:
type: "!LoadBalancer"
29 changes: 29 additions & 0 deletions infrastructure/policies/templates/disallow_nodeport.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: {{ include "policies.fullname" . }}-no-nodeport
labels:
{{- include "policies.labels" . | nindent 4 }}
{{- with .Values.disallowNodePort.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
validationFailureAction: enforce
background: true
rules:
- name: no-Nodeport
match:
resources:
kinds:
- Service
namespaceSelector:
{{- with .Values.policiesLabels }}
matchLabels:
{{- toYaml . | nindent 12 }}
{{- end }}
validate:
message: {{ .Values.disallowNodePort.message }}
pattern:
spec:
type: "!NodePort"
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: {{ include "policies.fullname" . }}-privilege-escalation
labels:
{{- include "policies.labels" . | nindent 4 }}
{{- with .Values.disallowPrivilegeEscalation.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
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: {{ .Values.disallowPrivilegeEscalation.message }}
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,39 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: {{ include "policies.fullname" . }}-privileged-containers
labels:
{{- include "policies.labels" . | nindent 4 }}
{{- with .Values.disallowPrivilegedContainers.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}

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: {{ .Values.disallowPrivilegedContainers.message }}
pattern:
spec:
=(ephemeralContainers):
- =(securityContext):
=(privileged): "false"
=(initContainers):
- =(securityContext):
=(privileged): "false"
containers:
- =(securityContext):
=(privileged): "false"
50 changes: 50 additions & 0 deletions infrastructure/policies/templates/require_pods_runAsNonRoot.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: {{ include "policies.fullname" . }}-run-as-non-root
labels:
{{- include "policies.labels" . | nindent 4 }}
{{- with .Values.requirePodsRunAsNonRoot.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
validationFailureAction: enforce
background: true
rules:
- name: run-as-non-root
match:
any:
- resources:
kinds:
- Pod
namespaceSelector:
{{- with .Values.policiesLabels }}
matchLabels:
{{- toYaml . | nindent 16 }}
{{- end }}
validate:
message: {{ .Values.requirePodsRunAsNonRoot.message }}
anyPattern:
- spec:
securityContext:
runAsNonRoot: true
=(ephemeralContainers):
- =(securityContext):
=(runAsNonRoot): true
=(initContainers):
- =(securityContext):
=(runAsNonRoot): true
containers:
- =(securityContext):
=(runAsNonRoot): true
- spec:
=(ephemeralContainers):
- securityContext:
runAsNonRoot: true
=(initContainers):
- securityContext:
runAsNonRoot: true
containers:
- securityContext:
runAsNonRoot: true
Loading

0 comments on commit 7778f20

Please sign in to comment.