Kubernetes Basics

Kubernetes Grundlagen

Erlernen Sie AWS-Hacking von Grund auf mit htARTE (HackTricks AWS Red Team Expert)!

Andere Möglichkeiten, HackTricks zu unterstützen:

Der ursprüngliche Autor dieser Seite ist Jorge (lesen Sie seinen Originalbeitrag hier)

Architektur & Grundlagen

Was macht Kubernetes?

  • Ermöglicht das Ausführen von Container/n in einem Container-Engine.

  • Der Scheduler ermöglicht effizientes Container-Management.

  • Hält Container am Leben.

  • Ermöglicht die Kommunikation zwischen Containern.

  • Ermöglicht Bereitstellungstechniken.

  • Verwaltet Datenmengen.

Architektur

  • Node: Betriebssystem mit Pod oder Pods.

  • Pod: Wrapper um einen Container oder mehrere Container. Ein Pod sollte nur eine Anwendung enthalten (normalerweise führt ein Pod nur 1 Container aus). Der Pod ist die Art und Weise, wie Kubernetes die Container-Technologie abstrahiert.

  • Service: Jeder Pod hat 1 interne IP-Adresse aus dem internen Bereich des Nodes. Es kann jedoch auch über einen Service freigegeben werden. Der Service hat ebenfalls eine IP-Adresse und sein Ziel ist es, die Kommunikation zwischen den Pods aufrechtzuerhalten, sodass, wenn einer stirbt, der neue Ersatz (mit einer anderen internen IP) im gleichen IP des Service zugänglich ist. Er kann als intern oder extern konfiguriert werden. Der Service fungiert auch als Lastenausgleicher, wenn 2 Pods mit demselben Service verbunden sind. Wenn ein Service erstellt wird, können Sie die Endpunkte jedes Dienstes finden, der kubectl get endpoints ausführt.

  • Kubelet: Primärer Knoten-Agent. Die Komponente, die die Kommunikation zwischen Knoten und kubectl herstellt und nur Pods ausführen kann (über den API-Server). Der Kubelet verwaltet keine Container, die nicht von Kubernetes erstellt wurden.

  • Kube-Proxy: ist der Dienst, der für die Kommunikation (Services) zwischen dem API-Server und dem Knoten zuständig ist. Die Basis ist ein IPtables für Knoten. Erfahrene Benutzer könnten auch andere Kube-Proxies von anderen Anbietern installieren.

  • Sidecar-Container: Sidecar-Container sind die Container, die zusammen mit dem Hauptcontainer im Pod ausgeführt werden sollten. Dieses Sidecar-Muster erweitert und verbessert die Funktionalität der aktuellen Container, ohne sie zu ändern. Heutzutage wissen wir, dass wir die Container-Technologie verwenden, um alle Abhängigkeiten für die Anwendung zu verpacken, damit sie überall ausgeführt werden kann. Ein Container macht nur eine Sache und macht diese Sache sehr gut.

  • Master-Prozess:

  • API-Server: Ist die Art und Weise, wie Benutzer und Pods mit dem Master-Prozess kommunizieren. Es sollten nur authentifizierte Anfragen zugelassen werden.

  • Scheduler: Die Planung bezieht sich darauf, sicherzustellen, dass Pods den Knoten zugeordnet sind, damit Kubelet sie ausführen kann. Er verfügt über genügend Intelligenz, um zu entscheiden, welcher Knoten über mehr verfügbare Ressourcen verfügt und den neuen Pod diesem zuweist. Beachten Sie, dass der Scheduler keine neuen Pods startet, sondern nur mit dem im Knoten ausgeführten Kubelet-Prozess kommuniziert, der den neuen Pod starten wird.

  • Kube-Controller-Manager: Überprüft Ressourcen wie Replikamengen oder Bereitstellungen, um zu überprüfen, ob beispielsweise die richtige Anzahl von Pods oder Knoten ausgeführt wird. Wenn ein Pod fehlt, wird er mit dem Scheduler kommunizieren, um einen neuen zu starten. Er steuert Replikationen, Token und Kontodienste für die API.

  • etcd: Datenspeicherung, persistent, konsistent und verteilt. Ist die Datenbank von Kubernetes und der Schlüssel-Wert-Speicher, in dem der vollständige Zustand der Cluster gespeichert wird (jede Änderung wird hier protokolliert). Komponenten wie der Scheduler oder der Controller-Manager sind auf diese Daten angewiesen, um zu wissen, welche Änderungen aufgetreten sind (verfügbare Ressourcen der Knoten, Anzahl der ausgeführten Pods...).

  • Cloud-Controller-Manager: Ist der spezifische Controller für Flusssteuerungen und Anwendungen, z. B. wenn Sie Cluster in AWS oder OpenStack haben.

Beachten Sie, dass es möglicherweise mehrere Knoten (die mehrere Pods ausführen) gibt, es möglicherweise auch mehrere Master-Prozesse gibt, deren Zugriff auf den API-Server ausbalanciert ist und deren etcd synchronisiert ist.

Volumes:

Wenn ein Pod Daten erstellt, die nicht verloren gehen sollten, wenn der Pod verschwindet, sollten sie in einem physischen Volume gespeichert werden. Kubernetes ermöglicht das Anhängen eines Volumes an einen Pod, um die Daten zu persistieren. Das Volume kann sich auf der lokalen Maschine oder in einem externen Speicher befinden. Wenn Sie Pods auf verschiedenen physischen Knoten ausführen, sollten Sie einen externen Speicher verwenden, damit alle Pods darauf zugreifen können.

Andere Konfigurationen:

  • ConfigMap: Sie können URLs konfigurieren, um auf Dienste zuzugreifen. Der Pod wird Daten von hier abrufen, um zu wissen, wie er mit dem Rest der Dienste (Pods) kommunizieren soll. Beachten Sie, dass dies nicht der empfohlene Ort zum Speichern von Anmeldeinformationen ist!

  • Secret: Hier werden geheime Daten wie Passwörter, API-Schlüssel... codiert in B64 gespeichert. Der Pod kann auf diese Daten zugreifen, um die erforderlichen Anmeldeinformationen zu verwenden.

  • Bereitstellungen: Hier werden die von Kubernetes auszuführenden Komponenten angegeben. Ein Benutzer arbeitet normalerweise nicht direkt mit Pods, Pods werden in Replika-Sets (Anzahl der replizierten gleichen Pods) abstrahiert, die über Bereitstellungen ausgeführt werden. Beachten Sie, dass Bereitstellungen für zustandslose Anwendungen sind. Die Mindestkonfiguration für eine Bereitstellung ist der Name und das auszuführende Image.

  • StatefulSet: Diese Komponente ist speziell für Anwendungen wie Datenbanken gedacht, die auf denselben Speicher zugreifen müssen.

  • Ingress: Dies ist die Konfiguration, die verwendet wird, um die Anwendung öffentlich mit einer URL freizugeben. Beachten Sie, dass dies auch mit externen Diensten möglich ist, aber dies ist der richtige Weg, um die Anwendung freizugeben.

  • Wenn Sie ein Ingress implementieren, müssen Sie Ingress-Controller erstellen. Der Ingress-Controller ist ein Pod, der der Endpunkt ist, der die Anfragen empfängt und überprüft und sie an die Dienste verteilt. Der Ingress-Controller wird die Anfrage basierend auf den konfigurierten Ingress-Regeln weiterleiten. Beachten Sie, dass die Ingress-Regeln auf verschiedene Pfade oder sogar Subdomains zu verschiedenen internen Kubernetes-Diensten verweisen können.

  • Eine bessere Sicherheitspraxis wäre die Verwendung eines Cloud-Lastenausgleichs oder eines Proxy-Servers als Einstiegspunkt, um keinen Teil des Kubernetes-Clusters freizulegen.

  • Wenn eine Anfrage eingeht, die keiner Ingress-Regel entspricht, leitet der Ingress-Controller sie an den "Standard-Backend" weiter. Sie können describe des Ingress-Controllers verwenden, um die Adresse dieses Parameters zu erhalten.

  • minikube addons enable ingress

PKI Infrastruktur - Zertifizierungsstelle CA:

  • CA ist die vertrauenswürdige Wurzel für alle Zertifikate innerhalb des Clusters.

  • Ermöglicht es Komponenten, sich gegenseitig zu validieren.

  • Alle Cluster-Zertifikate werden von der CA signiert.

  • ETCd hat sein eigenes Zertifikat.

  • Typen:

    • apiserver-Zertifikat.

    • kubelet-Zertifikat.

    • Scheduler-Zertifikat.

Grundlegende Aktionen

Minikube

Minikube kann verwendet werden, um einige schnelle Tests auf Kubernetes durchzuführen, ohne eine komplette Kubernetes-Umgebung bereitzustellen. Es führt die Master- und Node-Prozesse auf einer Maschine aus. Minikube verwendet VirtualBox, um den Node auszuführen. Siehe hier, wie man es installiert.

$ minikube start
😄  minikube v1.19.0 on Ubuntu 20.04
✨  Automatically selected the virtualbox driver. Other choices: none, ssh
💿  Downloading VM boot image ...
> minikube-v1.19.0.iso.sha256: 65 B / 65 B [-------------] 100.00% ? p/s 0s
> minikube-v1.19.0.iso: 244.49 MiB / 244.49 MiB  100.00% 1.78 MiB p/s 2m17.
👍  Starting control plane node minikube in cluster minikube
💾  Downloading Kubernetes v1.20.2 preload ...
> preloaded-images-k8s-v10-v1...: 491.71 MiB / 491.71 MiB  100.00% 2.59 MiB
🔥  Creating virtualbox VM (CPUs=2, Memory=3900MB, Disk=20000MB) ...
🐳  Preparing Kubernetes v1.20.2 on Docker 20.10.4 ...
▪ Generating certificates and keys ...
▪ Booting up control plane ...
▪ Configuring RBAC rules ...
🔎  Verifying Kubernetes components...
▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
🌟  Enabled addons: storage-provisioner, default-storageclass
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by defaul

$ minikube status
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

---- ONCE YOU HAVE A K8 SERVICE RUNNING WITH AN EXTERNAL SERVICE -----
$ minikube service mongo-express-service
(This will open your browser to access the service exposed port)

$ minikube delete
🔥  Deleting "minikube" in virtualbox ...
💀  Removed all traces of the "minikube" cluster

Kubectl Grundlagen

Kubectl ist das Befehlszeilentool für Kubernetes-Cluster. Es kommuniziert mit dem API-Server des Master-Prozesses, um Aktionen in Kubernetes auszuführen oder Daten abzurufen.

kubectl version #Get client and server version
kubectl get pod
kubectl get services
kubectl get deployment
kubectl get replicaset
kubectl get secret
kubectl get all
kubectl get ingress
kubectl get endpoints

#kubectl create deployment <deployment-name> --image=<docker image>
kubectl create deployment nginx-deployment --image=nginx
#Access the configuration of the deployment and modify it
#kubectl edit deployment <deployment-name>
kubectl edit deployment nginx-deployment
#Get the logs of the pod for debbugging (the output of the docker container running)
#kubectl logs <replicaset-id/pod-id>
kubectl logs nginx-deployment-84cd76b964
#kubectl describe pod <pod-id>
kubectl describe pod mongo-depl-5fd6b7d4b4-kkt9q
#kubectl exec -it <pod-id> -- bash
kubectl exec -it mongo-depl-5fd6b7d4b4-kkt9q -- bash
#kubectl describe service <service-name>
kubectl describe service mongodb-service
#kubectl delete deployment <deployment-name>
kubectl delete deployment mongo-depl
#Deploy from config file
kubectl apply -f deployment.yml

Minikube-Dashboard

Das Dashboard ermöglicht es Ihnen, einfacher zu sehen, was Minikube ausführt. Sie finden die URL zum Zugriff darauf unter:

minikube dashboard --url


🔌  Enabling dashboard ...
▪ Using image kubernetesui/dashboard:v2.3.1
▪ Using image kubernetesui/metrics-scraper:v1.0.7
🤔  Verifying dashboard health ...
🚀  Launching proxy ...
🤔  Verifying proxy health ...
http://127.0.0.1:50034/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/

Beispiele für YAML-Konfigurationsdateien

Jede Konfigurationsdatei hat 3 Teile: Metadaten, Spezifikation (was gestartet werden muss), Status (gewünschter Zustand). Innerhalb der Spezifikation der Bereitstellungskonfigurationsdatei finden Sie die Vorlage definiert mit einer neuen Konfigurationsstruktur, die das auszuführende Image definiert:

Beispiel für Bereitstellung + Service, die in derselben Konfigurationsdatei deklariert sind (von hier)

Da ein Dienst normalerweise mit einer Bereitstellung zusammenhängt, ist es möglich, beides in derselben Konfigurationsdatei zu deklarieren (der in dieser Konfiguration deklarierte Dienst ist nur intern zugänglich):

apiVersion: apps/v1
kind: Deployment
metadata:
name: mongodb-deployment
labels:
app: mongodb
spec:
replicas: 1
selector:
matchLabels:
app: mongodb
template:
metadata:
labels:
app: mongodb
spec:
containers:
- name: mongodb
image: mongo
ports:
- containerPort: 27017
env:
- name: MONGO_INITDB_ROOT_USERNAME
valueFrom:
secretKeyRef:
name: mongodb-secret
key: mongo-root-username
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mongodb-secret
key: mongo-root-password
---
apiVersion: v1
kind: Service
metadata:
name: mongodb-service
spec:
selector:
app: mongodb
ports:
- protocol: TCP
port: 27017
targetPort: 27017

Beispiel für die Konfiguration eines externen Dienstes

Dieser Dienst wird extern zugänglich sein (überprüfen Sie die Attribute nodePort und type: LoadBalancer):

---
apiVersion: v1
kind: Service
metadata:
name: mongo-express-service
spec:
selector:
app: mongo-express
type: LoadBalancer
ports:
- protocol: TCP
port: 8081
targetPort: 8081
nodePort: 30000

Dies ist nützlich für Tests, aber für die Produktion sollten Sie nur interne Dienste und einen Ingress haben, um die Anwendung freizugeben.

Beispiel einer Ingress-Konfigurationsdatei

Dies wird die Anwendung unter http://dashboard.com freigeben.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: dashboard-ingress
namespace: kubernetes-dashboard
spec:
rules:
- host: dashboard.com
http:
paths:
- backend:
serviceName: kubernetes-dashboard
servicePort: 80

Beispiel einer Secrets-Konfigurationsdatei

Beachten Sie, wie die Passwörter in B64 codiert sind (was nicht sicher ist!)

apiVersion: v1
kind: Secret
metadata:
name: mongodb-secret
type: Opaque
data:
mongo-root-username: dXNlcm5hbWU=
mongo-root-password: cGFzc3dvcmQ=

Beispiel für ConfigMap

Ein ConfigMap ist die Konfiguration, die den Pods gegeben wird, damit sie wissen, wie sie andere Dienste lokalisieren und darauf zugreifen können. In diesem Fall wird jeder Pod wissen, dass der Name mongodb-service die Adresse eines Pods ist, mit dem sie kommunizieren können (dieser Pod wird ein mongodb ausführen):

apiVersion: v1
kind: ConfigMap
metadata:
name: mongodb-configmap
data:
database_url: mongodb-service

Dann kann diese Adresse innerhalb einer Bereitstellungskonfiguration auf folgende Weise angegeben werden, damit sie im env des Pods geladen wird:

[...]
spec:
[...]
template:
[...]
spec:
containers:
- name: mongo-express
image: mongo-express
ports:
- containerPort: 8081
env:
- name: ME_CONFIG_MONGODB_SERVER
valueFrom:
configMapKeyRef:
name: mongodb-configmap
key: database_url
[...]

Beispiel für Volumenkonfiguration

Sie können verschiedene Beispiele für Speicherkonfigurations-YAML-Dateien unter https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes finden. Beachten Sie, dass Volumes nicht innerhalb von Namespaces liegen

Namespaces

Kubernetes unterstützt mehrere virtuelle Cluster, die vom selben physischen Cluster unterstützt werden. Diese virtuellen Cluster werden Namespaces genannt. Diese sind für die Verwendung in Umgebungen mit vielen Benutzern über mehrere Teams oder Projekte verteilt gedacht. Für Cluster mit einigen bis zehn Benutzern sollten Sie keine Namespaces erstellen oder darüber nachdenken müssen. Sie sollten nur mit der Verwendung von Namespaces beginnen, um eine bessere Kontrolle und Organisation jedes Teils der Anwendung, die in Kubernetes bereitgestellt wird, zu haben.

Namespaces bieten einen Bereich für Namen. Namen von Ressourcen müssen innerhalb eines Namespaces eindeutig sein, aber nicht über Namespaces hinweg. Namespaces können nicht ineinander verschachtelt werden und jede Kubernetes-Ressource kann nur in einem Namespace sein.

Es gibt standardmäßig 4 Namespaces, wenn Sie minikube verwenden:

kubectl get namespace
NAME              STATUS   AGE
default           Active   1d
kube-node-lease   Active   1d
kube-public       Active   1d
kube-system       Active   1d
  • kube-system: Es ist nicht für die Benutzer gedacht und du solltest es nicht berühren. Es ist für Master- und kubectl-Prozesse.

  • kube-public: Öffentlich zugängliche Daten. Enthält einen Configmap, der Clusterinformationen enthält.

  • kube-node-lease: Bestimmt die Verfügbarkeit eines Knotens.

  • default: Der Namespace, den der Benutzer zum Erstellen von Ressourcen verwenden wird.

#Create namespace
kubectl create namespace my-namespace

Beachten Sie, dass die meisten Kubernetes-Ressourcen (z. B. Pods, Services, Replikationscontroller und andere) in bestimmten Namespaces sind. Andere Ressourcen wie Namespace-Ressourcen und Ressourcen auf niedriger Ebene, wie Nodes und PersistenVolumes, befinden sich jedoch nicht in einem Namespace. Um zu sehen, welche Kubernetes-Ressourcen in einem Namespace sind und welche nicht:

kubectl api-resources --namespaced=true #In a namespace
kubectl api-resources --namespaced=false #Not in a namespace

Sie können den Namespace für alle nachfolgenden kubectl-Befehle in diesem Kontext speichern.

kubectl config set-context --current --namespace=<insert-namespace-name-here>

Helm

Helm ist der Paketmanager für Kubernetes. Es ermöglicht das Verpacken von YAML-Dateien und deren Verteilung in öffentlichen und privaten Repositories. Diese Pakete werden als Helm-Charts bezeichnet.

helm search <keyword>

Kubernetes Geheimnisse

Ein Secret ist ein Objekt, das sensible Daten wie ein Passwort, ein Token oder einen Schlüssel enthält. Solche Informationen könnten anderweitig in einer Pod-Spezifikation oder in einem Image platziert werden. Benutzer können Secrets erstellen und das System erstellt auch Secrets. Der Name eines Secret-Objekts muss ein gültiger DNS-Subdomänenname sein. Lesen Sie hier die offizielle Dokumentation.

Geheimnisse könnten Dinge wie sein:

  • API, SSH-Schlüssel.

  • OAuth-Token.

  • Anmeldeinformationen, Passwörter (Klartext oder b64 + Verschlüsselung).

  • Informationen oder Kommentare.

  • Datenbankverbindungscodes, Zeichenfolgen… .

Es gibt verschiedene Arten von Secrets in Kubernetes

Eingebauter TypVerwendung

Undurchsichtig

beliebige benutzerdefinierte Daten (Standard)

kubernetes.io/service-account-token

Servicekonto-Token

kubernetes.io/dockercfg

serialisierte ~/.dockercfg-Datei

kubernetes.io/dockerconfigjson

serialisierte ~/.docker/config.json-Datei

kubernetes.io/basic-auth

Anmeldeinformationen für die Basisauthentifizierung

kubernetes.io/ssh-auth

Anmeldeinformationen für die SSH-Authentifizierung

kubernetes.io/tls

Daten für einen TLS-Client oder -Server

bootstrap.kubernetes.io/token

Bootstrap-Token-Daten

Der Opaque-Typ ist der Standardtyp, das typische Schlüssel-Wert-Paar, das von Benutzern definiert wird.

Wie Secrets funktionieren:

Die folgende Konfigurationsdatei definiert ein Secret namens mysecret mit 2 Schlüssel-Wert-Paaren username: YWRtaW4= und password: MWYyZDFlMmU2N2Rm. Es definiert auch einen Pod namens secretpod, der die in mysecret definierten username und password in den Umgebungsvariablen SECRET_USERNAME und SECRET_PASSWOR freigibt. Es wird auch das username-Secret innerhalb von mysecret im Pfad /etc/foo/my-group/my-username mit Berechtigungen 0640 einhängen.

secretpod.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
---
apiVersion: v1
kind: Pod
metadata:
name: secretpod
spec:
containers:
- name: secretpod
image: nginx
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
volumeMounts:
- name: foo
mountPath: "/etc/foo"
restartPolicy: Never
volumes:
- name: foo
secret:
secretName: mysecret
items:
- key: username
path: my-group/my-username
mode: 0640
kubectl apply -f <secretpod.yaml>
kubectl get pods #Wait until the pod secretpod is running
kubectl exec -it  secretpod -- bash
env | grep SECRET && cat /etc/foo/my-group/my-username && echo

Geheimnisse in etcd

etcd ist ein konsistenter und hochverfügbarer Schlüssel-Wert-Speicher, der als Kubernetes-Back-End-Speicher für alle Clusterdaten verwendet wird. Lassen Sie uns auf die in etcd gespeicherten Geheimnisse zugreifen:

cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep etcd

Du wirst Zertifikate, Schlüssel und URLs sehen, die sich im Dateisystem befinden. Sobald du sie hast, wirst du in der Lage sein, eine Verbindung zum etcd herzustellen.

#ETCDCTL_API=3 etcdctl --cert <path to client.crt> --key <path to client.ket> --cacert <path to CA.cert> endpoint=[<ip:port>] health

ETCDCTL_API=3 etcdctl --cert /etc/kubernetes/pki/apiserver-etcd-client.crt --key /etc/kubernetes/pki/apiserver-etcd-client.key --cacert /etc/kubernetes/pki/etcd/etcd/ca.cert endpoint=[127.0.0.1:1234] health

Sobald Sie die Kommunikation hergestellt haben, können Sie die Geheimnisse erhalten:

#ETCDCTL_API=3 etcdctl --cert <path to client.crt> --key <path to client.ket> --cacert <path to CA.cert> endpoint=[<ip:port>] get <path/to/secret>

ETCDCTL_API=3 etcdctl --cert /etc/kubernetes/pki/apiserver-etcd-client.crt --key /etc/kubernetes/pki/apiserver-etcd-client.key --cacert /etc/kubernetes/pki/etcd/etcd/ca.cert endpoint=[127.0.0.1:1234] get /registry/secrets/default/secret_02

Hinzufügen von Verschlüsselung zum ETCD

Standardmäßig werden alle Geheimnisse im ETCD im Klartext gespeichert, es sei denn, Sie wenden eine Verschlüsselungsschicht an. Das folgende Beispiel basiert auf https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/

encryption.yaml
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: cjjPMcWpTPKhAdieVtd+KhG4NN+N6e3NmBPMXJvbfrY= #Any random key
- identity: {}

Danach müssen Sie das --encryption-provider-config-Flag auf dem kube-apiserver so setzen, dass es auf den Speicherort der erstellten Konfigurationsdatei zeigt. Sie können /etc/kubernetes/manifest/kube-apiserver.yaml bearbeiten und die folgenden Zeilen hinzufügen:

containers:
- command:
- kube-apiserver
- --encriyption-provider-config=/etc/kubernetes/etcd/<configFile.yaml>

Scrollen Sie nach unten zu volumeMounts:

- mountPath: /etc/kubernetes/etcd
name: etcd
readOnly: true

Scrolle im volumeMounts zum hostPath:

- hostPath:
path: /etc/kubernetes/etcd
type: DirectoryOrCreate
name: etcd

Überprüfen, ob Daten verschlüsselt sind

Daten werden verschlüsselt, wenn sie in etcd geschrieben werden. Nach dem Neustart Ihres kube-apiservers sollten neu erstellte oder aktualisierte Secrets verschlüsselt gespeichert werden. Zur Überprüfung können Sie das Befehlszeilenprogramm etcdctl verwenden, um den Inhalt Ihres Secrets abzurufen.

  1. Erstellen Sie ein neues Secret namens secret1 im Namespace default:

kubectl create secret generic secret1 -n default --from-literal=mykey=mydata
  1. Lesen Sie mit dem Befehlszeilenprogramm etcdctl dieses Secret aus etcd:

ETCDCTL_API=3 etcdctl get /registry/secrets/default/secret1 [...] | hexdump -C

wobei [...] die zusätzlichen Argumente für die Verbindung zum etcd-Server sein müssen. 3. Überprüfen Sie, ob das gespeicherte Secret mit k8s:enc:aescbc:v1: beginnt, was darauf hinweist, dass der Anbieter aescbc die resultierenden Daten verschlüsselt hat. 4. Überprüfen Sie, ob das Secret korrekt entschlüsselt wird, wenn es über die API abgerufen wird:

kubectl describe secret secret1 -n default

sollte mykey: bXlkYXRh entsprechen, wobei mydata codiert ist. Überprüfen Sie Entschlüsselung eines Secrets, um das Secret vollständig zu entschlüsseln.

Da Secrets beim Schreiben verschlüsselt werden, wird bei einem Update eines Secrets auch dieser Inhalt verschlüsselt:

kubectl get secrets --all-namespaces -o json | kubectl replace -f -

Abschließende Tipps:

Referenzen

Erlernen Sie AWS-Hacking von Grund auf mit htARTE (HackTricks AWS Red Team Expert)!

Andere Möglichkeiten, HackTricks zu unterstützen:

Last updated