Skip to content

Commit

Permalink
Ignoring critical namespaces
Browse files Browse the repository at this point in the history
  • Loading branch information
eurogig committed Apr 14, 2022
1 parent 15d225e commit 5cd511c
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 11 deletions.
10 changes: 10 additions & 0 deletions admissioncontroller/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,13 @@ data:
output:
- json
```
## Ignoring critical namespaces
There is a second configMap called whorfconfig.yaml. Within this config you'll find a property called k8s.properties where the key value pair 'ignores-namespaces' is preconfigured with the kube-system namespace and the bridgecrew namespace. Add any other system critical namespaces to this configuration, reapply the configMap and restart Whorf to apply the new configMap settings.

_NOTE: The list does not currently accept wildcard entries such as kube-*._

E.g.
```
# kubernetes related config
k8s.properties: |
ignores-namespaces=kube-system,bridgecrew
4 changes: 4 additions & 0 deletions admissioncontroller/k8s/admissionconfiguration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ webhooks:
sideEffects: None
timeoutSeconds: 30
admissionReviewVersions: ["v1","v1beta1"]
namespaceSelector:
matchExpressions:
- key: whorf.ignore
operator: DoesNotExist
rules:
- apiGroups: ["*"]
resources:
Expand Down
22 changes: 17 additions & 5 deletions admissioncontroller/k8s/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ spec:
drop:
- ALL
- NET_RAW
image: bridgecrew/whorf@bridgecrew/whorf@sha256:8ef75a8ae4c4082f377af9f095385e7a5807f64355ead75f156d056158e9c4b8@bridgecrew/whorf@sha256:85a9636fbe49a3336aeda3b92db8bf2c1c189d84f94650ea1975957da35167d5
image: bridgecrew/whorf@sha256:84abccfea280bc1bdabcc6e26f668503a70d09669c6b2e89632b45c0576a0d93
imagePullPolicy: Always
resources:
limits:
Expand Down Expand Up @@ -60,7 +60,12 @@ spec:
- name: BC_SOURCE
value: admissionController
- name: CKV_GITHUB_CONFIG_FETCH_DATA
value: "False"
value: "False"
- name: DEBUG
valueFrom:
configMapKeyRef:
name: whorfconfig # The ConfigMap this value comes from.
key: debug # Are we in debug mode?
volumeMounts:
- name: bridgecrew-secret
readOnly: true
Expand All @@ -69,7 +74,7 @@ spec:
readOnly: true
mountPath: "/certs"
- name: "config"
mountPath: "/app/config"
mountPath: "/app/config"
- name: "apptmp"
mountPath: "/app/tmp"
- name: "tmp"
Expand All @@ -88,8 +93,15 @@ spec:
secret:
secretName: admission-tls
- name: "config"
configMap:
name: "checkovconfig"
projected:
sources:
- configMap:
name: "checkovconfig"
- configMap:
name: "whorfconfig"
items:
- key: "k8s.properties"
path: "k8s.properties"
- emptyDir: {}
name: apptmp
- emptyDir: {}
Expand Down
11 changes: 11 additions & 0 deletions admissioncontroller/k8s/whorfconfig.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: whorfconfig
namespace: bridgecrew
data:
# debug will save the parsed manifests to the file system for later inspection
debug: "no"
# kubernetes related config
k8s.properties: |
ignores-namespaces=kube-system,bridgecrew
5 changes: 4 additions & 1 deletion admissioncontroller/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,18 @@ deployment=https://raw.githubusercontent.com/bridgecrewio/checkov/master/admissi
configmap=https://raw.githubusercontent.com/bridgecrewio/checkov/master/admissioncontroller/k8s/checkovconfig.yaml
admissionregistration=https://raw.githubusercontent.com/bridgecrewio/checkov/master/admissioncontroller/k8s/admissionconfiguration.yaml
service=https://raw.githubusercontent.com/bridgecrewio/checkov/master/admissioncontroller/k8s/service.yaml
whorfconfigmap=https://raw.githubusercontent.com/bridgecrewio/checkov/master/admissioncontroller/k8s/whorfconfig.yaml

curl -o $k8sdir/deployment.yaml $deployment
curl -o $k8sdir/service.yaml $service
curl -o $k8sdir/whorfconfig.yaml $whorfconfigmap
# Pop these into the temp directory as we'll make some customisations pipe in into the k8s dir
curl -o $certdir/checkovconfig.yaml $configmap
curl -o $certdir/admissionconfiguration.yaml $admissionregistration

# the namespace
ns=bridgecrew
kubectl create ns $ns --dry-run=client -o yaml > $k8sdir/namespace.yaml
kubectl create ns $ns --dry-run=client -o yaml | sed '/^metadata:/p; s/^metadata:/ labels: {"whorf.ignore":"true"}/' > $k8sdir/namespace.yaml

# the cluster (repository name)
cluster=$1
Expand Down Expand Up @@ -59,6 +61,7 @@ kubectl apply -f $k8sdir/namespace.yaml
kubectl apply -f $k8sdir/secret-apikey.yaml
kubectl apply -f $k8sdir/secret.yaml
kubectl apply -f $k8sdir/checkovconfig.yaml
kubectl apply -f $k8sdir/whorfconfig.yaml
kubectl apply -f $k8sdir/service.yaml
kubectl apply -f $k8sdir/deployment.yaml
kubectl apply -f $k8sdir/admissionconfiguration.yaml
Expand Down
32 changes: 27 additions & 5 deletions admissioncontroller/whorf.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ def validating_webhook():
request_info = request.get_json()
uid = request_info["request"].get("uid")

checkovconfig = "config/.checkov.yaml"
configfile = "config/k8s.properties"

whorfconfig = getConfig(configfile)

# Process config variables

# a list of namespaces to ignore requests from
ignore_list = whorfconfig['ignores-namespaces']

# Check/Sanitise UID to make sure it's a k8s request and only a k8s request as it is used for filenaming
# UUID pattern match regex
pattern = r'\b[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}\b'
Expand All @@ -31,10 +41,16 @@ def validating_webhook():
webhook.logger.error('K8s UID failed security checks. Request rejected!')
return admission_response(False, uid, response)

# check we're not in the kube-system namespace
namespace = request_info["request"].get("namespace")
if namespace in ignore_list:
print("Namespace in ignore list. Ignoring validation")
response = 'Namespace in ignore list. Ignoring validation'
webhook.logger.error('Namespace in ignore list. Ignoring validation!')
return admission_response(True, uid, response)

jsonfile = "tmp/" + uid + "-req.json"
yamlfile = "tmp/" + uid + "-req.yaml"
configfile = "config/.checkov.yaml"


ff = open(jsonfile, 'w+')
Expand All @@ -43,7 +59,7 @@ def validating_webhook():
yaml.dump(todict(request_info["request"]["object"]),yf)

print("Running checkov")
cp = subprocess.run(["checkov","--config-file",configfile,"-f",yamlfile], universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
cp = subprocess.run(["checkov","--config-file",checkovconfig,"-f",yamlfile], universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

checkovresults = json.loads(cp.stdout)

Expand All @@ -57,9 +73,8 @@ def validating_webhook():

if cp.returncode != 0:


# open configfile to check for hard fail CKVs
with open(configfile, 'r') as config:
with open(checkovconfig, 'r') as config:
cf = yaml.safe_load(config)

response = ""
Expand Down Expand Up @@ -123,6 +138,13 @@ def admission_response(allowed, uid, message):
}
})


def getConfig(configfile):
cf = {}
with open(configfile) as myfile:
for line in myfile:
name, var = line.partition("=")[::2]
cf[name.strip()] = list(var.strip().split(','))
return cf

if __name__ == '__main__':
webhook.run(host='0.0.0.0', port=1701)

0 comments on commit 5cd511c

Please sign in to comment.