Dennis Hemeier

Falco - Container Native Runtime Security

Tools
Mit Falco kann sehr einfach eine Intrusion und abnormality Detection in bestehende Kubernetes Cluster integriert werden. Die nahtlose Integration von K8S Audit Logs macht das Tool besonders interessant.
Falco

In der modernen Welt von Kubernetes, bei der Entwickler immer mehr Rechte über komplette Systeme (Container) bekommen, ist es wichtig, auch ein entsprechendes System zur Überprüfung der Aktivitäten auf einem Cluster zu implementieren. Falco ist hierbei ein idealer Kandidat. Doch was genau kann ich mit Falco alles überwachen?

Features

Falco hängt sich direkt an den Kernel und kann so auf alle Ereignisse reagieren, die einen Linux Sys-Call ausgelöst haben. Somit ist Falco nicht von einer eigenen Implementierung abhängig, sondern funktioniert auch mit bestehenden Anwendungen. Als Beispiele seien hier folgende Events aufgeführt:

  • Eine Shell wird in einem Container ausgeführt

  • Ein Server Prozess startet einen Child Prozess mit einem unerwarteten Typ

  • Eine sensitive Datei, z.B. /etc/shadow wird gelesen / geschrieben

  • Eine "non-device" Datei wird unter /dev geschrieben

  • Eine Standart Systemkomponente (z.B. ls) startet eine ausgehende Netzwerkverbindung

Zusätzlich kann Falco so Konfiguriert werden, dass es die Kubernetes Audit-Logs bekommt und so einen noch tieferen Einblick in das System bekommt.

Installation

Die Installation gestaltet sich denkbar einfach. Im Kern ist Falco ein Daemonset, welches somit auf jeder Node in deinem Cluster läuft. Die genaue Installationsanleitung ist in der Dokumentation zu finden.

Grundlegend sind folgende Schritte Notwendig:

  1. Clone des Repositories / Wechsel in das entsprechende Verzeichnis:

    git clone https://github.com/falcosecurity/falco/ && cd falco/integrations/k8s-using-daemonset
  2. Falco Serviceaccount:

    kubectl apply -f k8s-with-rbac/falco-account.yaml
  3. Falco Service:

    kubectl apply -f k8s-with-rbac/falco-service.yaml
  4. Erforderliche Konfigurationen in ein neues Verzeichnis kopieren:

    mkdir -p k8s-with-rbac/falco-config cp ../../falco.yaml k8s-with-rbac/falco-config/ cp ../../rules/falco_rules.* k8s-with-rbac/falco-config/ cp ../../rules/k8s_audit_rules.yaml k8s-with-rbac/falco-config/
  5. ConfigMap erzeugen:

    kubectl create configmap falco-config --from-file=k8s-with-rbac/falco-config
  6. Falco DaemonSet:

    kubectl apply -f k8s-with-rbac/falco-daemonset-configmap.yaml

Anschließend sollte Falco starten, die Nodes entsprechend so anpassen, dass die Kernel Events ausgelesen werden können und anschließend alle Events loggen können. Somit haben wir den ersten Part der Installation abgeschlossen.

Integration der Kubernetes Audit Logs

Die Audit Logs müssen nun in einem weiteren Step konfiguriert werden. Dazu nutzt Falco die in Kubernetes implementierte dynamische AuditSink Konfiguration. Da der Kubernetes API Server NICHT mit Kubernetes internen Services sprechen kann, muss das Logging an eine statische IP Adresse gesendet werden. Diese Konfiguration wird anhand eines Templates unter /examples/k8s_audit_config/ wie folgt erstellt: 

FALCO_SERVICE_CLUSTERIP=$(kubectl get service falco-service -o=jsonpath={.spec.clusterIP}) envsubst < webhook-config.yaml.in > webhook-config.yaml

Um die Konfiguration zu aktivieren, wird ein kleines Hilfsscript verwendet:

bash ./enable-k8s-audit.sh <variant> dynamic

Hierbei wird für <variant> je nach Installationsart kops oder minikube eingesetzt. Für andere Installationen müssen die Änderungen händisch vorgenommen werden. Für kops muss zusätzlich der API-Server Host angegeben werden: APISERVER_HOST=api.my-kops-cluster.com.

Verwendung von Falco

Alle Events von Falco landen standardmäßig in den Logs der Container. Erweitert werden kann das ganze über z.B. Webhooks oder andere Backends. Um sich für alle Nodes die Logs anschauen zu können, nutzen wir bei kubectl logs die Möglichkeit, anhand eines Labels zu loggen. Somit erhalten wir die Logs von allen laufenden Containern:

kubectl logs -l app=falco

In den Logs seht ihr anhand der Example Kubernetes Konfiguration, welche von Falco mitgeliefert wird, nun z.B. folgende Ausgaben in den Container Logs. Auf diese könnte man in weiteren Schritten entsprechend reagieren.

11:15:41.410620639: Notice A shell was spawned in a container with an attached terminal (user=root k8s.ns=cloudpirate k8s.pod=cloudpirate-deployment-88dc64d88-frf62 container=01da62e24137 shell=bash parent=docker-runc cmdline=bash terminal=34816 container_id=01da62e24137 image=hdcms/client) k8s.ns=cloudpirate k8s.pod=cloudpirate-deployment-88dc64d88-frf62 container=01da62e24137

11:15:41.171320064: Notice Attach/Exec to pod (user=kubecfg pod=cloudpirate-deployment-88dc64d88-frf62 ns=cloudpirate action=exec command=bash)

Critical File Edit

11:17:14.817387894: Error File created below /dev by untrusted program (user=root command=touch unexpected-file file=/dev/unexpected-file container_id=01da62e24137 image=hdcms/client) k8s.ns=cloudpirate k8s.pod=cloudpirate-deployment-88dc64d88-frf62 container=01da62e24137 k8s.ns=cloudpirate k8s.pod=cloudpirate-deployment-88dc64d88-frf62 container=01da62e24137

Ich hoffe dieser kleine Einstieg zeigt das Potenzial von Falco, seine Anwendungen und Cluster zu überwachen. Besonders interessant dabei finde ich, dass ohne Änderungen an den laufenden Pods eine Überwachung möglich ist. Somit kann dieses System sehr einfach in bestehende Kubernetes Cluster eingesetzt werden.