diff --git a/docker/event-generator/Dockerfile b/docker/event-generator/Dockerfile index d543d846..50b1c6e2 100644 --- a/docker/event-generator/Dockerfile +++ b/docker/event-generator/Dockerfile @@ -1,7 +1,10 @@ FROM alpine:latest LABEL maintainer="opensource@sysdig.com" -RUN apk add --no-cache bash g++ +RUN apk add --no-cache bash g++ curl COPY ./event_generator.cpp /usr/local/bin +COPY ./docker-entrypoint.sh ./k8s_event_generator.sh / +COPY ./yaml /yaml RUN mkdir -p /var/lib/rpm RUN g++ --std=c++0x /usr/local/bin/event_generator.cpp -o /usr/local/bin/event_generator -CMD ["/usr/local/bin/event_generator"] +RUN curl -o /usr/local/bin/kubectl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl && chmod +x /usr/local/bin/kubectl +ENTRYPOINT ["/docker-entrypoint.sh"] diff --git a/docker/event-generator/docker-entrypoint.sh b/docker/event-generator/docker-entrypoint.sh new file mode 100755 index 00000000..ade40222 --- /dev/null +++ b/docker/event-generator/docker-entrypoint.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +CMD=${1:-syscall} + +shift + +set -euo pipefail + +if [[ "$CMD" == "syscall" ]]; then + /usr/local/bin/event_generator +elif [[ "$CMD" == "k8s_audit" ]]; then + . k8s_event_generator.sh +elif [[ "$CMD" == "bash" ]]; then + bash +else + echo "Unknown command. Can be one of" + echo " \"syscall\": generate falco syscall-related activity" + echo " \"k8s_audit\": generate falco k8s audit-related activity" + echo " \"bash\": spawn a shell" + exit 1 +fi diff --git a/docker/event-generator/k8s_event_generator.sh b/docker/event-generator/k8s_event_generator.sh new file mode 100644 index 00000000..79b406a0 --- /dev/null +++ b/docker/event-generator/k8s_event_generator.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +set -euo pipefail + +# You can pass a specific falco rule name and only yaml files matching +# that rule will be considered. The default is "all", meaning all yaml +# files will be applied. + +RULE=${1:-all} + +# Replace any '/' in RULES with a '.' and any space with a dash. (K8s +# label values can not contain slashes/spaces) +RULE=$(echo "$RULE" | tr '/ ' '.-') + +echo "***Testing kubectl configuration..." +kubectl version --short + +while true; do + + RET=$(kubectl get namespaces --output=name | grep falco-event-generator || true) + + if [[ "$RET" == *falco-event-generator* ]]; then + echo "***Deleting existing falco-event-generator namespace..." + kubectl delete namespace falco-event-generator + fi + + echo "***Creating falco-event-generator namespace..." + kubectl create namespace falco-event-generator + + for file in yaml/*.yaml; do + + MATCH=0 + if [[ "${RULE}" == "all" ]]; then + MATCH=1 + else + RET=$(grep -E "falco.rules:.*${RULE}" $file || true) + if [[ "$RET" != "" ]]; then + MATCH=1 + fi + fi + + if [[ $MATCH == 1 ]]; then + MESSAGES=$(grep -E 'message' $file | cut -d: -f2 | tr '\n' ',') + RULES=$(grep -E 'falco.rules' $file | cut -d: -f2 | tr '\n' ',') + + # The message uses dashes in place of spaces, convert them back to spaces + MESSAGES=$(echo "$MESSAGES" | tr '-' ' ' | sed -e 's/ *//' | sed -e 's/,$//') + RULES=$(echo "$RULES" | tr '-' ' '| tr '.' '/' | sed -e 's/ *//' | sed -e 's/,$//') + + echo "***$MESSAGES (Rule(s) $RULES)..." + kubectl apply -f $file + sleep 2 + fi + done + + sleep 10 +done diff --git a/docker/event-generator/yaml/configmap-private-creds.yaml b/docker/event-generator/yaml/configmap-private-creds.yaml new file mode 100644 index 00000000..4735798e --- /dev/null +++ b/docker/event-generator/yaml/configmap-private-creds.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: private-creds-configmap + namespace: falco-event-generator + labels: + app.kubernetes.io/name: private-creds-configmap + app.kubernetes.io/part-of: falco-event-generator + falco.rules: Create.Modify-Configmap-With-Private-Credentials + message: Creating-configmap-with-private-credentials +data: + ui.properties: | + color.good=purple + color.bad=yellow + allow.textmode=true + password=some_secret_password diff --git a/docker/event-generator/yaml/disallowed-pod-deployment.yaml b/docker/event-generator/yaml/disallowed-pod-deployment.yaml new file mode 100644 index 00000000..a12eb773 --- /dev/null +++ b/docker/event-generator/yaml/disallowed-pod-deployment.yaml @@ -0,0 +1,25 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: disallowed-pod-deployment + namespace: falco-event-generator + labels: + app.kubernetes.io/name: disallowed-pod-deployment + app.kubernetes.io/part-of: falco-event-generator + falco.rules: Create-Disallowed-Pod + message: Creating-pod-with-image-outside-of-allowed-images +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: disallowed-pod-busybox + template: + metadata: + labels: + app.kubernetes.io/name: disallowed-pod-busybox + app.kubernetes.io/part-of: falco-event-generator + spec: + containers: + - name: busybox + image: busybox + command: ["/bin/sh", "-c", "while true; do echo sleeping; sleep 3600; done"] diff --git a/docker/event-generator/yaml/hostnetwork-deployment.yaml b/docker/event-generator/yaml/hostnetwork-deployment.yaml new file mode 100644 index 00000000..1dc3f93d --- /dev/null +++ b/docker/event-generator/yaml/hostnetwork-deployment.yaml @@ -0,0 +1,26 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: hostnetwork-deployment + namespace: falco-event-generator + labels: + app.kubernetes.io/name: hostnetwork-deployment + app.kubernetes.io/part-of: falco-event-generator + falco.rules: Create-HostNetwork-Pod + message: Creating-deployment-with-hostNetwork-true-pod +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: hostnetwork-busybox + template: + metadata: + labels: + app.kubernetes.io/name: hostnetwork-busybox + app.kubernetes.io/part-of: falco-event-generator + spec: + hostNetwork: true + containers: + - name: busybox + image: busybox + command: ["/bin/sh", "-c", "while true; do echo sleeping; sleep 3600; done"] diff --git a/docker/event-generator/yaml/nodeport-service.yaml b/docker/event-generator/yaml/nodeport-service.yaml new file mode 100644 index 00000000..d6f83951 --- /dev/null +++ b/docker/event-generator/yaml/nodeport-service.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Service +metadata: + name: nodeport-service + namespace: falco-event-generator + labels: + app.kubernetes.io/name: nodeport-service + app.kubernetes.io/part-of: falco-event-generator + falco.rules: Create-NodePort-Service + message: Creating-service-of-type-NodePort +spec: + type: NodePort + ports: + - port: 80 + selector: + app: busybox diff --git a/docker/event-generator/yaml/privileged-deployment.yaml b/docker/event-generator/yaml/privileged-deployment.yaml new file mode 100644 index 00000000..de96279f --- /dev/null +++ b/docker/event-generator/yaml/privileged-deployment.yaml @@ -0,0 +1,27 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: privileged-deployment + namespace: falco-event-generator + labels: + app.kubernetes.io/name: privileged-deployment + app.kubernetes.io/part-of: falco-event-generator + falco.rules: Create-Privileged-Pod + message: Creating-deployment-with-privileged-true-pod +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: privileged-busybox + template: + metadata: + labels: + app.kubernetes.io/name: privileged-busybox + app.kubernetes.io/part-of: falco-event-generator + spec: + containers: + - securityContext: + privileged: true + name: busybox + image: busybox + command: ["/bin/sh", "-c", "while true; do echo sleeping; sleep 3600; done"] \ No newline at end of file diff --git a/docker/event-generator/yaml/role-pod-exec.yaml b/docker/event-generator/yaml/role-pod-exec.yaml new file mode 100644 index 00000000..626077f3 --- /dev/null +++ b/docker/event-generator/yaml/role-pod-exec.yaml @@ -0,0 +1,17 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: pod-exec-role + namespace: falco-event-generator + labels: + app.kubernetes.io/name: pod-exec-role + app.kubernetes.io/part-of: falco-event-generator + falco.rules: ClusterRole-With-Pod-Exec-Created + message: Creating-role-that-can-exec-to-pods +rules: +- apiGroups: + - "" + resources: + - "pods/exec" + verbs: + - get diff --git a/docker/event-generator/yaml/role-wildcard-resources.yaml b/docker/event-generator/yaml/role-wildcard-resources.yaml new file mode 100644 index 00000000..1344e990 --- /dev/null +++ b/docker/event-generator/yaml/role-wildcard-resources.yaml @@ -0,0 +1,17 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: wildcard-resources-role + namespace: falco-event-generator + labels: + app.kubernetes.io/name: wildcard-resources-role + app.kubernetes.io/part-of: falco-event-generator + falco.rules: ClusterRole-With-Write-Privileges-Created + message: Creating-role-with-wildcard-resources +rules: +- apiGroups: + - "" + resources: + - "*" + verbs: + - get diff --git a/docker/event-generator/yaml/role-write-privileges.yaml b/docker/event-generator/yaml/role-write-privileges.yaml new file mode 100644 index 00000000..e3065deb --- /dev/null +++ b/docker/event-generator/yaml/role-write-privileges.yaml @@ -0,0 +1,17 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: write-privileges-role + namespace: falco-event-generator + labels: + app.kubernetes.io/name: write-privileges-role + app.kubernetes.io/part-of: falco-event-generator + falco.rules: ClusterRole-With-Write-Privileges-Created + message: Creating-role-with-write-privileges +rules: +- apiGroups: + - "" + resources: + - "pods" + verbs: + - create diff --git a/docker/event-generator/yaml/sensitive-mount-deployment.yaml b/docker/event-generator/yaml/sensitive-mount-deployment.yaml new file mode 100644 index 00000000..ca7cbbfa --- /dev/null +++ b/docker/event-generator/yaml/sensitive-mount-deployment.yaml @@ -0,0 +1,32 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: sensitive-mount-deployment + namespace: falco-event-generator + labels: + app.kubernetes.io/name: sensitive-mount-deployment + app.kubernetes.io/part-of: falco-event-generator + falco.rules: Create-Sensitive-Mount-Pod + message: Creating-deployment-with-pod-mounting-sensitive-path-from-host +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: sensitive-mount-busybox + template: + metadata: + labels: + app.kubernetes.io/name: sensitive-mount-busybox + app.kubernetes.io/part-of: falco-event-generator + spec: + containers: + - name: busybox + image: busybox + command: ["/bin/sh", "-c", "while true; do echo sleeping; sleep 3600; done"] + volumeMounts: + - mountPath: /host/etc + name: etc + volumes: + - name: etc + hostPath: + path: /etc diff --git a/docker/event-generator/yaml/vanilla-configmap.yaml b/docker/event-generator/yaml/vanilla-configmap.yaml new file mode 100644 index 00000000..0dd9f45a --- /dev/null +++ b/docker/event-generator/yaml/vanilla-configmap.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: vanilla-configmap + namespace: falco-event-generator + labels: + app.kubernetes.io/name: vanilla-configmap + app.kubernetes.io/part-of: falco-event-generator + falco.rules: K8s-ConfigMap-Created + message: Creating-configmap +data: + ui.properties: | + color.good=purple + color.bad=yellow + allow.textmode=true \ No newline at end of file diff --git a/docker/event-generator/yaml/vanilla-deployment.yaml b/docker/event-generator/yaml/vanilla-deployment.yaml new file mode 100644 index 00000000..34f41c7e --- /dev/null +++ b/docker/event-generator/yaml/vanilla-deployment.yaml @@ -0,0 +1,25 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: vanilla-deployment + namespace: falco-event-generator + labels: + app.kubernetes.io/name: vanilla-deployment + app.kubernetes.io/part-of: falco-event-generator + falco.rules: K8s-Deployment-Created + message: Creating-deployment +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: vanilla-busybox + template: + metadata: + labels: + app.kubernetes.io/name: vanilla-busybox + app.kubernetes.io/part-of: falco-event-generator + spec: + containers: + - name: busybox + image: busybox + command: ["/bin/sh", "-c", "while true; do echo sleeping; sleep 3600; done"] diff --git a/docker/event-generator/yaml/vanilla-role-rolebinding-serviceaccount.yaml b/docker/event-generator/yaml/vanilla-role-rolebinding-serviceaccount.yaml new file mode 100644 index 00000000..580b4e8e --- /dev/null +++ b/docker/event-generator/yaml/vanilla-role-rolebinding-serviceaccount.yaml @@ -0,0 +1,46 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: vanilla-role + namespace: falco-event-generator + labels: + app.kubernetes.io/name: vanilla-role + app.kubernetes.io/part-of: falco-event-generator + falco.rules: K8s-Role.Clusterrole-Created + message: Creating-role +rules: +- apiGroups: + - "" + resources: + - "pods" + verbs: + - list +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: vanilla-role-binding + namespace: falco-event-generator + labels: + app.kubernetes.io/name: vanilla-role-binding + app.kubernetes.io/part-of: falco-event-generator + falco.rules: K8s-Role.Clusterrolebinding-Created + message: Creating-rolebinding +roleRef: + kind: Role + name: vanilla-role + apiGroup: rbac.authorization.k8s.io +subjects: + - kind: ServiceAccount + name: vanilla-service-account +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: vanilla-serviceaccount + namespace: falco-event-generator + labels: + app.kubernetes.io/name: vanilla-serviceaccount + app.kubernetes.io/part-of: falco-event-generator + falco.rules: K8s-Serviceaccount-Created + message: Creating-serviceaccount diff --git a/docker/event-generator/yaml/vanilla-service.yaml b/docker/event-generator/yaml/vanilla-service.yaml new file mode 100644 index 00000000..db91cdbe --- /dev/null +++ b/docker/event-generator/yaml/vanilla-service.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Service +metadata: + name: vanilla-service + namespace: falco-event-generator + labels: + app.kubernetes.io/name: vanilla-service + app.kubernetes.io/part-of: falco-event-generator + falco.rules: K8s-Service-Created + message: Creating-service +spec: + type: ClusterIP + ports: + - port: 80 + selector: + app: busybox \ No newline at end of file