Skip to content

Commit

Permalink
Add: Admission controller for Checkov (bridgecrewio#2220)
Browse files Browse the repository at this point in the history
* to eliminate child duplicates on scan locally

* remove filter for cronjob edge case

* First commit of admission controller

* removed old test files

* added sanitisation of uid

* Improved README

* Delete license

* Added regex lib

Co-authored-by: Barak Schoster Goihman <[email protected]>

* Improved Title

Co-authored-by: Barak Schoster Goihman <[email protected]>

* Fixed linting errors

Co-authored-by: Barak Schoster Goihman <[email protected]>
  • Loading branch information
eurogig and schosterbarak authored Jan 24, 2022
1 parent 5537f1f commit a7a989c
Show file tree
Hide file tree
Showing 12 changed files with 633 additions and 0 deletions.
133 changes: 133 additions & 0 deletions admissioncontroller/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# certs
certs/
debug/

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
.python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/
17 changes: 17 additions & 0 deletions admissioncontroller/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM python:3.9.7-slim

RUN apt-get update -y && apt-get install -y python3-pip python-dev
WORKDIR /app
COPY requirements.txt /app/requirements.txt
RUN pip3 install -r /app/requirements.txt
COPY whorf.py /app
COPY wsgi.py /app

# create the app user
RUN addgroup --gid 11000 app && adduser --uid 11000 --ingroup app app
# chown all the files to the app user
RUN chown -R app:app /app
# change to the app user
USER app

CMD gunicorn --certfile=/certs/webhook.crt --keyfile=/certs/webhook.key --bind 0.0.0.0:8443 wsgi:webhook
72 changes: 72 additions & 0 deletions admissioncontroller/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Whorf - Checkov implementation of a Kubernetes admission controller
A K8s admission controller for security and operational best practices (Based on [Checkov](https://checkov.io))

Whorf is your last line of defence against deploying vulnerable or misconfigured kubernetes objects.

## Install
It is easily deployed by simply running the setup.sh script. This will download the default kubernetes objects into a local bridgecrew directory. It will customise to your local requirements and deploy into the kubernetes cluster currently in context

### Step 1:
```
curl –o setup.sh https://raw.githubusercontent.com/bridgecrewio/master/admissioncontroller/setup.sh
```

### Step 2:
```
chmod +x ./setup.sh
```
### Step 3:
Get an [API key](https://docs.bridgecrew.io/docs/get-api-token)
### Step 3:
```
./setup.sh <a unique cluster name> <bc-api-key>
```

## Uninstall
```
kubectl delete -f bridgecrew<timestamp>
```

## Customisation of Checks for Validation
After installation the check which would block a kubernetes object from being deployed are created and deployed as a kubernetes ConfigMap.

The default checks are only a small subset of the entire kubernetes range focusing only on root and privileged access and capabilities.

These can be found in the file checkovconfig.yaml. The default example is below where k8sac/cluster would be replaced with k8sac/'your cluster name'

```
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: null
name: checkovconfig
namespace: bridgecrew
data:
.checkov.yaml: |
branch: master
repo-id: k8sac/cluster
download-external-modules: false
evaluate-variables: true
external-modules-download-path: .external_modules
framework: kubernetes
hard-fail-on:
- CKV_K8S_1
- CKV_K8S_2
- CKV_K8S_3
- CKV_K8S_4
- CKV_K8S_5
- CKV_K8S_6
- CKV_K8S_7
- CKV_K8S_16
- CKV_K8S_17
- CKV_K8S_18
- CKV_K8S_19
- CKV_K8S_20
- CKV_K8S_21
- CKV_K8S_23
- CKV_K8S_27
- CKV_K8S_39
- CKV_K8S_49
output:
- json
```
29 changes: 29 additions & 0 deletions admissioncontroller/k8s/admissionconfiguration.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
namespace: bridgecrew
name: validating-webhook
webhooks:
- name: validate.bridgecrew.svc
failurePolicy: Fail
sideEffects: None
timeoutSeconds: 30
admissionReviewVersions: ["v1","v1beta1"]
rules:
- apiGroups: ["*"]
resources:
- "deployments"
- "pods"
- "clusteroles"
- "replicasets"
apiVersions:
- "*"
operations:
- CREATE
- UPDATE
clientConfig:
service:
name: validate
namespace: bridgecrew
path: /validate/
caBundle: ${CA_PEM_B64}
34 changes: 34 additions & 0 deletions admissioncontroller/k8s/checkovconfig.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
apiVersion: v1
kind: ConfigMap
metadata:
creationTimestamp: null
name: checkovconfig
namespace: bridgecrew
data:
.checkov.yaml: |
branch: master
repo-id: k8sac/cluster
download-external-modules: false
evaluate-variables: true
external-modules-download-path: .external_modules
framework: kubernetes
hard-fail-on:
- CKV_K8S_1
- CKV_K8S_2
- CKV_K8S_3
- CKV_K8S_4
- CKV_K8S_5
- CKV_K8S_6
- CKV_K8S_7
- CKV_K8S_16
- CKV_K8S_17
- CKV_K8S_18
- CKV_K8S_19
- CKV_K8S_20
- CKV_K8S_21
- CKV_K8S_23
- CKV_K8S_27
- CKV_K8S_39
- CKV_K8S_49
output:
- json
96 changes: 96 additions & 0 deletions admissioncontroller/k8s/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: validation-webhook
namespace: bridgecrew
labels:
app: validate
spec:
replicas: 2
selector:
matchLabels:
app: validate
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: validate
annotations:
seccomp.security.alpha.kubernetes.io/pod: "docker/default"
spec:
containers:
- name: webhook
securityContext:
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
- NET_RAW
image: eurogig/whorf@sha256:f568faed1d3e631b33bd488aa2689d702e50fe8b590d630a6b4a33c66f8d177c
imagePullPolicy: Always
resources:
limits:
cpu: "1"
memory: "500Mi"
requests:
cpu: "0.1"
memory: "100Mi"
readinessProbe:
initialDelaySeconds: 15
exec:
command:
- /bin/sh
- -c
- "pidof -x gunicorn"
livenessProbe:
initialDelaySeconds: 30
exec:
command:
- /bin/sh
- -c
- "pidof -x gunicorn"
ports:
- containerPort: 8443
env:
- name: BC_SOURCE
value: cli
- name: CKV_GITHUB_CONFIG_FETCH_DATA
value: "False"
volumeMounts:
- name: bridgecrew-secret
readOnly: true
mountPath: "/home/app/.bridgecrew"
- name: certs-volume
readOnly: true
mountPath: "/certs"
- name: "config"
mountPath: "/app/config"
- name: "apptmp"
mountPath: "/app/tmp"
- name: "tmp"
mountPath: "/tmp"
imagePullPolicy: Always
automountServiceAccountToken: false
securityContext:
runAsNonRoot: true
runAsUser: 11000
runAsGroup: 11000
volumes:
- name: bridgecrew-secret
secret:
secretName: bridgecrew-secret
- name: certs-volume
secret:
secretName: admission-tls
- name: "config"
configMap:
name: "checkovconfig"
- emptyDir: {}
name: apptmp
- emptyDir: {}
name: tmp
11 changes: 11 additions & 0 deletions admissioncontroller/k8s/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: v1
kind: Service
metadata:
namespace: bridgecrew
name: validate
spec:
selector:
app: validate
ports:
- port: 443
targetPort: 8443
Loading

0 comments on commit a7a989c

Please sign in to comment.