Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/stefanprodan/kubesec-webhook
Security risk analysis for Kubernetes resources
https://github.com/stefanprodan/kubesec-webhook
Last synced: 21 days ago
JSON representation
Security risk analysis for Kubernetes resources
- Host: GitHub
- URL: https://github.com/stefanprodan/kubesec-webhook
- Owner: controlplaneio
- License: mit
- Created: 2018-07-29T13:29:58.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2023-11-28T12:37:01.000Z (about 1 year ago)
- Last Synced: 2024-10-29T16:58:41.442Z (3 months ago)
- Language: Go
- Homepage: https://kubesec.io
- Size: 2.9 MB
- Stars: 74
- Watchers: 8
- Forks: 19
- Open Issues: 9
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# kubesec-webhook
[![Build Status](https://travis-ci.org/controlplaneio/kubesec-webhook.svg?branch=master)](https://travis-ci.org/controlplaneio/kubesec-webhook)
Kubesec.io admission controller for Kubernetes Pods, Deployments,
DaemonSets and StatefulSets.For the kubectl scan plugin see [kubectl-kubesec](https://github.com/controlplaneio/kubectl-kubesec)
## Install
Generate webhook configuration files with a new TLS certificate and CA Bundle:
```bash
make certs
```Deploy the admission controller and webhooks in the kubesec namespace (requires Kubernetes 1.20 or newer):
```bash
make deploy
```Enable Kubesec validation by adding this label:
```bash
kubectl label namespaces default kubesec-validation=enabled
```## Usage
Try to apply a privileged Deployment:
```bash
kubectl apply -f ./test/deployment.yamlError from server (InternalError): error when creating "./test/deployment.yaml":
Internal error occurred: admission webhook "deployment.admission.kubesec.io" denied the request:
deployment-test score is -30, deployment minimum accepted score is 0
Scan Result:
{
"error": "",
"score": -30,
"scoring": {
"critical": [
{
"selector": "containers[] .securityContext .privileged == true",
"reason": "Privileged containers can allow almost completely unrestricted host access",
"weight": 0
}
],
"advise": [
{
"selector": "containers[] .securityContext .runAsNonRoot == true",
"reason": "Force the running image to run as a non-root user to ensure least privilege"
},
{
"selector": "containers[] .securityContext .capabilities .drop",
"reason": "Reducing kernel capabilities available to a container limits its attack surface",
"href": "https://kubernetes.io/docs/tasks/configure-pod-container/security-context/"
},
{
"selector": "containers[] .securityContext .readOnlyRootFilesystem == true",
"reason": "An immutable root filesystem can prevent malicious binaries being added to
PATH and increase attack cost"
},
{
"selector": "containers[] .securityContext .runAsUser \u003e 10000",
"reason": "Run as a high-UID user to avoid conflicts with the host's user table"
},
{
"selector": "containers[] .securityContext .capabilities .drop | index(\"ALL\")",
"reason": "Drop all capabilities and add only those required to reduce syscall attack surface"
}
]
}
}
```Try to apply a privileged DaemonSet:
```bash
kubectl apply -f ./test/daemonset.yamlError from server (InternalError): error when creating "./test/daemonset.yaml":
Internal error occurred: admission webhook "daemonset.admission.kubesec.io" denied the request:
daemonset-test score is -30, daemonset minimum accepted score is 0
Scan Result:
{
"error": "",
"score": -30,
"scoring": {
"critical": [
{
"selector": "containers[] .securityContext .privileged == true",
"reason": "Privileged containers can allow almost completely unrestricted host access",
"weight": 0
}
],
"advise": [
{
"selector": "containers[] .securityContext .runAsNonRoot == true",
"reason": "Force the running image to run as a non-root user to ensure least privilege"
},
{
"selector": "containers[] .securityContext .capabilities .drop",
"reason": "Reducing kernel capabilities available to a container limits its attack surface",
"href": "https://kubernetes.io/docs/tasks/configure-pod-container/security-context/"
},
{
"selector": "containers[] .securityContext .readOnlyRootFilesystem == true",
"reason": "An immutable root filesystem can prevent malicious binaries being added to PATH and increase attack cost"
},
{
"selector": "containers[] .securityContext .runAsUser \u003e 10000",
"reason": "Run as a high-UID user to avoid conflicts with the host's user table"
},
{
"selector": "containers[] .securityContext .capabilities .drop | index(\"ALL\")",
"reason": "Drop all capabilities and add only those required to reduce syscall attack surface"
}
]
}
}
```Try to apply a privileged StatefulSet:
```bash
kubectl apply -f ./test/statefulset.yamlError from server (InternalError): error when creating "./test/statefulset.yaml":
Internal error occurred: admission webhook "statefulset.admission.kubesec.io" denied the request:
statefulset-test score is -30, statefulset minimum accepted score is 0
Scan Result:
{
"error": "",
"score": -30,
"scoring": {
"critical": [
{
"selector": "containers[] .securityContext .privileged == true",
"reason": "Privileged containers can allow almost completely unrestricted host access",
"weight": 0
}
],
"advise": [
{
"selector": ".spec .volumeClaimTemplates[] .spec .accessModes | index(\"ReadWriteOnce\")",
"reason": ""
},
{
"selector": "containers[] .securityContext .runAsNonRoot == true",
"reason": "Force the running image to run as a non-root user to ensure least privilege"
},
{
"selector": "containers[] .securityContext .capabilities .drop",
"reason": "Reducing kernel capabilities available to a container limits its attack surface",
"href": "https://kubernetes.io/docs/tasks/configure-pod-container/security-context/"
},
{
"selector": "containers[] .securityContext .readOnlyRootFilesystem == true",
"reason": "An immutable root filesystem can prevent malicious binaries being added to
PATH and increase attack cost"
},
{
"selector": "containers[] .securityContext .runAsUser \u003e 10000",
"reason": "Run as a high-UID user to avoid conflicts with the host's user table"
}
]
}
}
```## Configuration
You can set the minimum Kubesec.io score in `./deploy/webhook/yaml`:
```yaml
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: kubesec-webhook
labels:
app: kubesec-webhook
spec:
replicas: 1
template:
metadata:
labels:
app: kubesec-webhook
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8081"
spec:
containers:
- name: kubesec-webhook
image: controlplaneio/kubesec:0.1-dev
imagePullPolicy: Always
command:
- ./kubesec
args:
- -tls-cert-file=/etc/webhook/certs/cert.pem
- -tls-key-file=/etc/webhook/certs/key.pem
- -min-score=0
ports:
- containerPort: 8080
- containerPort: 8081
volumeMounts:
- name: webhook-certs
mountPath: /etc/webhook/certs
readOnly: true
volumes:
- name: webhook-certs
secret:
secretName: kubesec-webhook-certs
```## Monitoring
The admission controller exposes Prometheus RED metrics for each webhook a
Grafana dashboard is available [here](https://grafana.com/dashboards/7088).### Credits
Kudos to [Xabier](https://github.com/slok) for the awesome [kubewebhook library](https://github.com/slok/kubewebhook).