- Create the
audit-policy.yaml
.
cat << EOF > audit-policy.yaml
apiVersion: audit.k8s.io/v1 # This is required.
kind: Policy
# Don't generate audit events for all requests in RequestReceived stage.
omitStages:
- "RequestReceived"
rules:
# Log pod changes at RequestResponse level
- level: RequestResponse
resources:
- group: ""
# Resource "pods" doesn't match requests to any subresource of pods,
# which is consistent with the RBAC policy.
resources: ["pods", "deployments"]
- level: RequestResponse
resources:
- group: "rbac.authorization.k8s.io"
# Resource "pods" doesn't match requests to any subresource of pods,
# which is consistent with the RBAC policy.
resources: ["clusterroles", "clusterrolebindings"]
# Log "pods/log", "pods/status" at Metadata level
- level: Metadata
resources:
- group: ""
resources: ["pods/log", "pods/status"]
# Don't log requests to a configmap called "controller-leader"
- level: None
resources:
- group: ""
resources: ["configmaps"]
resourceNames: ["controller-leader"]
# Don't log watch requests by the "system:kube-proxy" on endpoints or services
- level: None
users: ["system:kube-proxy"]
verbs: ["watch"]
resources:
- group: "" # core API group
resources: ["endpoints", "services"]
# Don't log authenticated requests to certain non-resource URL paths.
- level: None
userGroups: ["system:authenticated"]
nonResourceURLs:
- "/api*" # Wildcard matching.
- "/version"
# Log the request body of configmap changes in kube-system.
- level: Request
resources:
- group: "" # core API group
resources: ["configmaps"]
# This rule only applies to resources in the "kube-system" namespace.
# The empty string "" can be used to select non-namespaced resources.
namespaces: ["kube-system"]
# Log configmap changes in all other namespaces at the RequestResponse level.
- level: RequestResponse
resources:
- group: "" # core API group
resources: ["configmaps"]
# Log secret changes in all other namespaces at the Metadata level.
- level: Metadata
resources:
- group: "" # core API group
resources: ["secrets"]
# Log all other resources in core and extensions at the Request level.
- level: Request
resources:
- group: "" # core API group
- group: "extensions" # Version of group should NOT be included.
# A catch-all rule to log all other requests at the Metadata level.
- level: Metadata
# Long-running requests like watches that fall under this rule will not
# generate an audit event in RequestReceived.
omitStages:
- "RequestReceived"
EOF
- Create the
webhook-config.yaml
:
cat << EOF > webhook-config.yaml
apiVersion: v1
kind: Config
clusters:
- name: falco
cluster:
server: http://localhost:30007/k8s-audit
contexts:
- context:
cluster: falco
user: ""
name: default-context
current-context: default-context
preferences: {}
users: []
EOF
- Create the
kind-config.yaml
:
cat << EOF > kind-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
kubeadmConfigPatches:
- |
kind: ClusterConfiguration
apiServer:
# enable auditing flags on the API server
extraArgs:
audit-webhook-config-file: /etc/kubernetes/policies/webhook-config.yaml
audit-policy-file: /etc/kubernetes/policies/audit-policy.yaml
# mount new files / directories on the control plane
extraVolumes:
- name: audit-policies
hostPath: /etc/kubernetes/policies
mountPath: /etc/kubernetes/policies
readOnly: true
pathType: "DirectoryOrCreate"
extraMounts:
# Allow Falco to use devices provided by the kernel module
- hostPath: /dev
containerPath: /dev
# allow Falco to use the Docker unix socket
- hostPath: /var/run/docker.sock
containerPath: /var/run/docker.sock
# mount config files for kind
- hostPath: ./webhook-config.yaml
containerPath: /etc/kubernetes/policies/webhook-config.yaml
readOnly: true
- hostPath: ./audit-policy.yaml
containerPath: /etc/kubernetes/policies/audit-policy.yaml
readOnly: true
EOF
kind create cluster -n falco --config kind-config.yaml
- Create the
values.yaml
for falco:
cat << EOF > values.yaml
driver:
enabled: false
kind: module
collectors:
enabled: false
controller:
kind: deployment
deployment:
replicas: 1
falcoctl:
artifact:
install:
enabled: true
follow:
enabled: true
config:
artifact:
install:
resolveDeps: false
refs: [k8saudit-rules:0]
follow:
refs: [k8saudit-rules:0]
services:
- name: k8saudit-webhook
type: NodePort
ports:
- port: 9765 # See plugin open_params
nodePort: 30007
protocol: TCP
falco:
rules_file:
- /etc/falco/falco_rules.yaml
- /etc/falco/k8s_audit_rules.yaml
- /etc/falco/rules.d
plugins:
- name: k8saudit
library_path: libk8saudit.so
init_config:
""
open_params: "http://:9765/k8s-audit"
- name: json
library_path: libjson.so
init_config: ""
load_plugins: [k8saudit, json]
tty: true
EOF
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm repo update
helm install falco -n falco falcosecurity/falco --create-namespace -f values.yaml
kubectl create secret generic db-user-pass --from-literal=username=admin --from-literal=password='S!B\*d$zDsb='
kubectl logs -f -l app.kubernetes.io/instance=falco -n falco
falco-5f47786987-9hssb falco 14:07:48.050346000: Informational K8s Secret Created (user=kubernetes-admin secret=db-user-pass ns=default resource=secrets resp=201 decision=allow reason=)