Skip to content
Open
34 changes: 34 additions & 0 deletions job-eks.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
apiVersion: batch/v1
kind: Job
metadata:
name: kube-bench
namespace: kube-system
spec:
template:
spec:
hostPID: true
containers:
- name: kube-bench
image: aquasec/kube-bench:latest
command: ["kube-bench", "node", "--benchmark", "eks-1.0"]
volumeMounts:
- name: var-lib-kubelet
mountPath: /var/lib/kubelet
readOnly: true
- name: etc-systemd
mountPath: /etc/systemd
readOnly: true
- name: etc-kubernetes
mountPath: /etc/kubernetes
readOnly: true
restartPolicy: Never
volumes:
- name: var-lib-kubelet
hostPath:
path: "/var/lib/kubelet"
- name: etc-systemd
hostPath:
path: "/etc/systemd"
- name: etc-kubernetes
hostPath:
path: "/etc/kubernetes"
10 changes: 10 additions & 0 deletions kube-bench/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
These are the kube-bench jobs and cronjob yaml files to check for CIS benchmark of your k8 cluster.
To run the cronjob, you need to setup a slack webhook secret first.

Use this command:

`kubectl create secret generic slack-webhook-secret --from-literal=slack_webhook-url=https://hooks.slack.com/services/<your-webhook> -n default`

then apply the cronjob in your cluster.

`kubectl apply -f kube-bench_cronjob-minikube.yaml`
42 changes: 42 additions & 0 deletions kube-bench/kube-bench-job.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
apiVersion: batch/v1
kind: Job
metadata:
name: kube-bench
spec:
template:
spec:
hostPID: true
containers:
- name: kube-bench
image: docker.io/aquasec/kube-bench:latest
command:
[
"kube-bench",
"run",
"--targets",
"node",
"--benchmark",
"eks-1.2.0",
]
volumeMounts:
- name: var-lib-kubelet
mountPath: /var/lib/kubelet
readOnly: true
- name: etc-systemd
mountPath: /etc/systemd
readOnly: true
- name: etc-kubernetes
mountPath: /etc/kubernetes
readOnly: true
restartPolicy: Never
volumes:
- name: var-lib-kubelet
hostPath:
path: "/var/lib/kubelet"
- name: etc-systemd
hostPath:
path: "/etc/systemd"
- name: etc-kubernetes
hostPath:
path: "/etc/kubernetes"
43 changes: 43 additions & 0 deletions kube-bench/kube-bench_cronjob-minikube.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
apiVersion: batch/v1
kind: CronJob
metadata:
name: kube-bench-cron
namespace: default
spec:
schedule: "*/1 * * * *" # Runs every 1 minute
jobTemplate:
spec:
template:
spec:
hostPID: true
containers:
- name: kube-bench
image: aquasec/kube-bench:latest
command: ["sh", "-c", "apk add --no-cache curl && kube-bench | jq -R -s '{\"text\": .}' | curl -X POST -H 'Content-type: application/json' --data @- $(WEBHOOK_URL)"]
env:
- name: WEBHOOK_URL
valueFrom:
secretKeyRef:
name: slack-webhook-secret
key: webhook-url
volumeMounts:
- name: var-lib-kubelet
mountPath: /var/lib/kubelet
readOnly: true
- name: etc-systemd
mountPath: /etc/systemd
readOnly: true
- name: etc-kubernetes
mountPath: /etc/kubernetes
readOnly: true
restartPolicy: Never
volumes:
- name: var-lib-kubelet
hostPath:
path: "/var/lib/kubelet"
- name: etc-systemd
hostPath:
path: "/etc/systemd"
- name: etc-kubernetes
hostPath:
path: "/etc/kubernetes"
34 changes: 34 additions & 0 deletions kube-bench/kube-bench_job-minikube.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
apiVersion: batch/v1
kind: Job
metadata:
name: kube-bench
namespace: default
spec:
template:
spec:
hostPID: true
containers:
- name: kube-bench
image: aquasec/kube-bench:latest
command: ["kube-bench"]
volumeMounts:
- name: var-lib-kubelet
mountPath: /var/lib/kubelet
readOnly: true
- name: etc-systemd
mountPath: /etc/systemd
readOnly: true
- name: etc-kubernetes
mountPath: /etc/kubernetes
readOnly: true
restartPolicy: Never
volumes:
- name: var-lib-kubelet
hostPath:
path: "/var/lib/kubelet"
- name: etc-systemd
hostPath:
path: "/etc/systemd"
- name: etc-kubernetes
hostPath:
path: "/etc/kubernetes"
18 changes: 11 additions & 7 deletions src/main/java/com/javatechie/k8s/SpringbootK8sDemoApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@
@RestController
public class SpringbootK8sDemoApplication {

@GetMapping("/message")
public String welcome(){
return "Congratulation you successfully deployed your application to kubernetes !!";
}
public static void main(String[] args) {
SpringApplication.run(SpringbootK8sDemoApplication.class, args);
}

public static void main(String[] args) {
SpringApplication.run(SpringbootK8sDemoApplication.class, args);
}
@GetMapping("/message")
public String welcome() {
return "Congratulations! You have successfully deployed your application to Kubernetes!";
}

@GetMapping("/")
public String home() {
return "Home! Congratulations! You have successfully deployed your application to Kubernetes!";
}
}
12 changes: 12 additions & 0 deletions trivy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Create secret before running these jobs/cronjobs

```
kubectl create secret generic slack-webhook-secret --from-literal=slack_webhook-url=https://hooks.slack.com/services/<your-webhook-url> -n default
kubectl create secret generic slack-security-secret --from-literal=SLACK-TOKEN=xoxb-<your-bot-auth-tokeb> -n default
```

Make sure that your bot token have permission to upload file in your channel. And you must need to integrate your bot in your slack channel.


Then apply these jobs:
`kubectl apply -f <jobs/cronjobs>.yaml`
72 changes: 72 additions & 0 deletions trivy/cronjob-trivy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
apiVersion: batch/v1
kind: CronJob
metadata:
name: trivy-k8s-scan
namespace: default
spec:
schedule: "37 20 * * *"
jobTemplate:
spec:
template:
spec:
serviceAccountName: trivy-sa
containers:
- name: trivy-k8s
image: aquasec/trivy:latest
command:
- /bin/sh
- -c
- |
apk add --no-cache curl &&
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" &&
chmod +x kubectl &&
mv kubectl /usr/local/bin/ &&
echo "kubectl installed successfully" &&
TOTAL_NS=$(kubectl get ns -o jsonpath='{.items[*].metadata.name}' | wc -w) &&
curl -X POST https://slack.com/api/chat.postMessage \
-H "Authorization: Bearer $(cat /var/secrets/SLACK-TOKEN)" \
-H "Content-Type: application/json" \
-d '{
"channel": "#security-aws-eks",
"text": "Total number of namespaces are '"$TOTAL_NS"'. Running Trivy in each namespace"
}' &&
for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do
DATE_TIME=$(date +%Y-%m-%d_%H-%M-%S) &&
FILENAME="/tmp/trivy_${ns}_${DATE_TIME}.txt" &&
RESOURCE_COUNT=$(kubectl get all -n $ns --no-headers 2>/dev/null | wc -l) &&
if [ "$RESOURCE_COUNT" -eq 0 ]; then
curl -X POST https://slack.com/api/chat.postMessage \
-H "Authorization: Bearer $(cat /var/secrets/SLACK-TOKEN)" \
-H "Content-Type: application/json" \
-d '{
"channel": "#security-aws-eks",
"text": "There are no resources in namespace '"$ns"' to scan."
}';
else
echo "Scanning namespace: $ns" &&
trivy k8s --include-namespaces $ns --report all --severity CRITICAL --format table > $FILENAME &&
if [ -f $FILENAME ]; then
curl -F file=@$FILENAME \
-F "channels=#security-aws-eks" \
-F "initial_comment=Trivy scan results for namespace: $ns" \
-F "token=$(cat /var/secrets/SLACK-TOKEN)" \
https://slack.com/api/files.upload;
else
curl -X POST https://slack.com/api/chat.postMessage \
-H "Authorization: Bearer $(cat /var/secrets/SLACK-TOKEN)" \
-H "Content-Type: application/json" \
-d '{
"channel": "#security-aws-eks",
"text": "Trivy scan failed for namespace '"$ns"'."
}';
fi;
fi;
done;
volumeMounts:
- name: slack-secret
mountPath: /var/secrets
restartPolicy: OnFailure
volumes:
- name: slack-secret
secret:
secretName: slack-security-secret
12 changes: 12 additions & 0 deletions trivy/trivy-rbac.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: trivy-cluster-admin-binding
subjects:
- kind: ServiceAccount
name: trivy-sa
namespace: default
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
5 changes: 5 additions & 0 deletions trivy/trivy-serviceaccount.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: trivy-sa
namespace: default
69 changes: 69 additions & 0 deletions trivy/trivy_job_eks_dev_all_ns.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
apiVersion: batch/v1
kind: Job
metadata:
name: trivy-k8s-scan
namespace: default
spec:
template:
spec:
serviceAccountName: trivy-sa
containers:
- name: trivy-k8s
image: aquasec/trivy:latest
command:
- /bin/sh
- -c
- |
apk add --no-cache curl &&
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" &&
chmod +x kubectl &&
mv kubectl /usr/local/bin/ &&
echo "kubectl installed successfully" &&
TOTAL_NS=$(kubectl get ns -o jsonpath='{.items[*].metadata.name}' | wc -w) &&
curl -X POST https://slack.com/api/chat.postMessage \
-H "Authorization: Bearer $(cat /var/secrets/SLACK-TOKEN)" \
-H "Content-Type: application/json" \
-d '{
"channel": "#my-automation",
"text": "Total number of namespaces are '"$TOTAL_NS"'. Running Trivy in each namespace"
}' &&
for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do
DATE_TIME=$(date +%Y-%m-%d_%H-%M-%S) &&
FILENAME="/tmp/trivy_${ns}_${DATE_TIME}.txt" &&
RESOURCE_COUNT=$(kubectl get all -n $ns --no-headers 2>/dev/null | wc -l) &&
if [ "$RESOURCE_COUNT" -eq 0 ]; then
curl -X POST https://slack.com/api/chat.postMessage \
-H "Authorization: Bearer $(cat /var/secrets/SLACK-TOKEN)" \
-H "Content-Type: application/json" \
-d '{
"channel": "#my-automation",
"text": "There are no resources in namespace '"$ns"' to scan."
}';
else
echo "Scanning namespace: $ns" &&
trivy k8s --include-namespaces $ns --report all --severity CRITICAL --format table > $FILENAME &&
if [ -f $FILENAME ]; then
curl -F file=@$FILENAME \
-F "channels=#my-automation" \
-F "initial_comment=Trivy scan results for namespace: $ns" \
-F "token=$(cat /var/secrets/SLACK-TOKEN)" \
https://slack.com/api/files.upload;
else
curl -X POST https://slack.com/api/chat.postMessage \
-H "Authorization: Bearer $(cat /var/secrets/SLACK-TOKEN)" \
-H "Content-Type: application/json" \
-d '{
"channel": "#my-automation",
"text": "Trivy scan failed for namespace '"$ns"'."
}';
fi;
fi;
done;
volumeMounts:
- name: slack-secret
mountPath: /var/secrets
restartPolicy: OnFailure
volumes:
- name: slack-secret
secret:
secretName: slack-security-secret
Loading