Kubernetes Basics

Podstawy Kubernetes

Dowiedz się i ćwicz Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE) Dowiedz się i ćwicz Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)

Wesprzyj HackTricks

Oryginalnym autorem tej strony jest Jorge (przeczytaj jego oryginalny post tutaj)

Architektura i Podstawy

Co robi Kubernetes?

  • Pozwala uruchamiać kontenery w silniku kontenerów.

  • Harmonogram pozwala na efektywne wykonywanie kontenerów.

  • Utrzymuje kontenery aktywne.

  • Pozwala na komunikację między kontenerami.

  • Umożliwia techniki wdrażania.

  • Zarządza dużymi ilościami informacji.

Architektura

  • Node: system operacyjny z podem lub podami.

  • Pod: Otoczka wokół kontenera lub wielu kontenerów. Pod powinien zawierać tylko jedną aplikację (zazwyczaj pod uruchamia tylko 1 kontener). Pod jest sposobem, w jaki Kubernetes abstrahuje technologię kontenerów.

  • Usługa: Każdy pod ma 1 wewnętrzny adres IP z wewnętrznego zakresu węzła. Może być również wystawiony za pomocą usługi. Usługa ma również adres IP i jej celem jest utrzymanie komunikacji między podami, więc jeśli jeden umrze, nowa replika (z innym wewnętrznym adresem IP) będzie dostępna wystawiona pod tym samym adresem IP usługi. Może być skonfigurowany jako wewnętrzny lub zewnętrzny. Usługa działa również jako wyważarka obciążenia, gdy 2 pody są podłączone do tej samej usługi. Gdy usługa jest utworzona, można znaleźć punkty końcowe każdej usługi wykonując kubectl get endpoints

  • Kubelet: Główny agent węzła. Składnik, który nawiązuje komunikację między węzłem a kubectl, i może uruchamiać tylko pody (poprzez serwer API). Kubelet nie zarządza kontenerami, które nie zostały utworzone przez Kubernetes.

  • Kube-proxy: jest usługą odpowiedzialną za komunikację (usługi) między serwerem API a węzłem. Podstawą jest IPtables dla węzłów. Bardziej doświadczeni użytkownicy mogą zainstalować inne kube-proxy od innych dostawców.

  • Kontener pomocniczy (Sidecar container): Kontenery pomocnicze to kontenery, które powinny działać razem z głównym kontenerem w podzie. Ten wzorzec kontenera pomocniczego rozszerza i ulepsza funkcjonalność bieżących kontenerów bez ich zmiany. Obecnie wiemy, że używamy technologii kontenerów do spakowania wszystkich zależności potrzebnych do uruchomienia aplikacji w dowolnym miejscu. Kontener robi tylko jedną rzecz i robi to bardzo dobrze.

  • Proces główny:

  • Serwer API: Jest to sposób, w jaki użytkownicy i pody komunikują się z procesem głównym. Powinny być dozwolone tylko uwierzytelnione żądania.

  • Planista (Scheduler): Planowanie oznacza zapewnienie, że Pody są dopasowane do Węzłów, aby Kubelet mógł je uruchomić. Ma wystarczająco dużo inteligencji, aby zdecydować, który węzeł ma więcej dostępnych zasobów i przypisać nowy pod do niego. Należy zauważyć, że planista nie uruchamia nowych podów, tylko komunikuje się z procesem Kubelet działającym wewnątrz węzła, który uruchomi nowy pod.

  • Menedżer kontrolera Kubernetesa: Sprawdza zasoby, takie jak zbiory replik lub wdrożenia, aby sprawdzić, czy na przykład prawidłowa liczba podów lub węzłów jest uruchomiona. W przypadku braku poda, skontaktuje się z planistą, aby uruchomić nowy. Kontroluje replikacje, tokeny i usługi konta do interfejsu API.

  • etcd: Przechowywanie danych, trwałe, spójne i rozproszone. Jest to baza danych Kubernetes i przechowywania kluczy-wartości, w której przechowuje pełny stan klastrów (każda zmiana jest rejestrowana tutaj). Składniki takie jak Planista lub Menedżer kontrolera zależą od tych danych, aby wiedzieć, jakie zmiany nastąpiły (dostępne zasoby węzłów, liczba uruchomionych podów...)

  • Menedżer kontrolera chmury (Cloud controller manager): Jest to konkretny kontroler do sterowania przepływem i aplikacjami, np. jeśli masz klastry w AWS lub OpenStack.

Należy zauważyć, że ponieważ może być kilka węzłów (uruchamiających kilka podów), może być również kilka procesów głównych, których dostęp do serwera API jest zrównoważony obciążeniowo, a ich etcd zsynchronizowany.

Woluminy:

Gdy pod tworzy dane, które nie powinny zostać utracone po zniknięciu poda, powinny być przechowywane w woluminie fizycznym. Kubernetes pozwala dołączyć wolumin do poda, aby zachować dane. Wolumin może być na lokalnej maszynie lub w zdalnym magazynie. Jeśli uruchamiasz pody na różnych fizycznych węzłach, powinieneś użyć zdalnego magazynu, aby wszystkie pody miały do niego dostęp.

Inne konfiguracje:

  • ConfigMap: Możesz skonfigurować adresy URL do dostępu do usług. Pod pobierze dane stąd, aby wiedzieć, jak komunikować się z resztą usług (podów). Należy pamiętać, że to nie jest zalecane miejsce do przechowywania poufnych informacji!

  • Secret: To jest miejsce do przechowywania poufnych danych takich jak hasła, klucze API... zakodowane w B64. Pod będzie mógł uzyskać dostęp do tych danych, aby użyć wymaganych poświadczeń.

  • Wdrożenia (Deployments): Tutaj wskazuje się komponenty do uruchomienia przez kubernetes. Użytkownik zazwyczaj nie będzie bezpośrednio pracować z podami, pody są zasłonięte w Zbiorach replik (liczba tych samych replikowanych podów), które są uruchamiane za pomocą wdrożeń. Należy zauważyć, że wdrożenia są przeznaczone dla aplikacji bezstanowych. Minimalną konfiguracją dla wdrożenia jest nazwa i obraz do uruchomienia.

  • StatefulSet: Ten komponent jest przeznaczony specjalnie dla aplikacji takich jak bazy danych, które muszą uzyskać dostęp do tego samego magazynu.

  • Ingress: To jest konfiguracja, która służy do eksponowania aplikacji publicznie za pomocą adresu URL. Należy zauważyć, że można to również zrobić za pomocą usług zewnętrznych, ale to jest poprawny sposób eksponowania aplikacji.

  • Jeśli wdrożysz Ingress, będziesz musiał utworzyć Kontrolery Ingress. Kontroler Ingress to pod, który będzie punktem końcowym, który otrzyma żądania, sprawdzi je i rozłoży je równomiernie na usługi. kontroler Ingress będzie wysyłać żądanie na podstawie skonfigurowanych reguł Ingress. Należy zauważyć, że reguły Ingress mogą wskazywać na różne ścieżki lub nawet subdomeny do różnych wewnętrznych usług kubernetes.

  • Lepszą praktyką bezpieczeństwa byłoby użycie równoważnika obciążenia chmury lub serwera proxy jako punktu wejścia, aby żadna część klastra Kubernetes nie była wystawiona.

  • Gdy żądanie, które nie pasuje do żadnej reguły Ingress, zostanie otrzymane, kontroler Ingress przekieruje je do "Domyślnego backendu". Możesz użyć describe, aby uzyskać adres tego parametru.

  • minikube addons enable ingress

Infrastruktura PKI - Certyfikat CA:

  • CA jest zaufanym źródłem dla wszystkich certyfikatów wewnątrz klastra.

  • Umożliwia komponentom weryfikację siebie nawzajem.

  • Wszystkie certyfikaty klastra są podpisane przez CA.

  • ETCd ma swój własny certyfikat.

  • Typy:

    • certyfikat apiservera.

    • certyfikat kubeleta.

    • certyfikat schedulera.

Podstawowe działania

Minikube

Minikube można użyć do przeprowadzenia szybkich testów na kubernetes bez konieczności wdrażania całego środowiska kubernetes. Uruchomi on procesy master i node na jednej maszynie. Minikube będzie używać virtualboxa do uruchomienia noda. Zobacz tutaj, jak go zainstalować.

$ 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

Podstawy Kubectl

Kubectl to narzędzie wiersza poleceń do klastrow kubernetes. Komunikuje się z serwerem Api procesu głównego, aby wykonywać czynności w kubernetes lub prosić o dane.

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

Panel Minikube

Panel pozwala łatwiej zobaczyć, co jest uruchomione w minikube, możesz znaleźć URL dostępu tutaj:

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/

Przykłady plików konfiguracyjnych YAML

Każdy plik konfiguracyjny składa się z 3 części: metadanych, specyfikacji (co ma zostać uruchomione), stanu (stan docelowy). Wewnątrz specyfikacji pliku konfiguracyjnego wdrożenia można znaleźć szablon zdefiniowany za pomocą nowej struktury konfiguracyjnej określającej obraz do uruchomienia:

Przykład deklaracji wdrożenia + usługi w tym samym pliku konfiguracyjnym (z tutaj)

Ponieważ usługa zazwyczaj jest powiązana z jednym wdrożeniem, można zadeklarować obie rzeczy w tym samym pliku konfiguracyjnym (usługa zadeklarowana w tej konfiguracji jest dostępna tylko wewnętrznie):

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

Przykład konfiguracji usługi zewnętrznej

Ta usługa będzie dostępna zewnętrznie (sprawdź atrybuty nodePort i 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

To jest przydatne do testowania, ale do produkcji powinieneś mieć tylko usługi wewnętrzne i Ingress do wystawiania aplikacji.

Przykład pliku konfiguracyjnego Ingress

To wystawi aplikację pod adresem http://dashboard.com.

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

Przykład pliku konfiguracyjnego z tajemnicami

Zauważ, jak hasła są zakodowane w B64 (co nie jest bezpieczne!)

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

Przykład ConfigMap

ConfigMap to konfiguracja przekazywana do kapsułek, dzięki której wiedzą, jak zlokalizować i uzyskać dostęp do innych usług. W tym przypadku każda kapsułka będzie wiedziała, że nazwa mongodb-service to adres kapsułki, z którą mogą się komunikować (ta kapsułka będzie wykonywała mongodb):

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

Następnie, wewnątrz konfiguracji deploymentu ten adres można określić w następujący sposób, aby został załadowany do środowiska poda:

[...]
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
[...]

Przykład konfiguracji woluminu

Możesz znaleźć różne przykłady plików konfiguracyjnych yaml dotyczących przechowywania na stronie https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes. Zauważ, że woluminy nie znajdują się w przestrzeniach nazw

Przestrzenie nazw

Kubernetes obsługuje wiele wirtualnych klastrów wspieranych przez ten sam fizyczny klaster. Te wirtualne klastry nazywane są przestrzeniami nazw. Są one przeznaczone do użytku w środowiskach z wieloma użytkownikami rozproszonymi po różnych zespołach lub projektach. Dla klastrów z kilkoma do kilkudziesięciu użytkowników nie powinieneś w ogóle musieć tworzyć ani myśleć o przestrzeniach nazw. Powinieneś zacząć używać przestrzeni nazw tylko po to, aby lepiej kontrolować i organizować każdą część aplikacji wdrożonej w kubernetes.

Przestrzenie nazw zapewniają zakres dla nazw. Nazwy zasobów muszą być unikalne w obrębie przestrzeni nazw, ale nie w obrębie różnych przestrzeni nazw. Przestrzenie nazw nie mogą być zagnieżdżane wewnątrz siebie, a każdy zasób Kubernetes może znajdować się tylko w jednej przestrzeni nazw.

Domyślnie istnieje 4 przestrzenie nazw, jeśli korzystasz z minikube:

kubectl get namespace
NAME              STATUS   AGE
default           Active   1d
kube-node-lease   Active   1d
kube-public       Active   1d
kube-system       Active   1d
  • kube-system: Nie jest przeznaczony do użytku przez użytkowników i nie powinieneś go dotykać. Służy do procesów master i kubectl.

  • kube-public: Publicznie dostępne dane. Zawiera configmapę, która zawiera informacje o klastrze.

  • kube-node-lease: Określa dostępność węzła.

  • default: Przestrzeń nazw, którą użytkownik będzie używał do tworzenia zasobów.

#Create namespace
kubectl create namespace my-namespace

Należy pamiętać, że większość zasobów Kubernetes (np. pods, services, kontrolery replikacji i inne) znajduje się w pewnych przestrzeniach nazw. Jednak inne zasoby, takie jak zasoby przestrzeni nazw i zasoby niskiego poziomu, takie jak węzły i persistenVolumes, nie znajdują się w przestrzeni nazw. Aby sprawdzić, które zasoby Kubernetes znajdują się w przestrzeni nazw, a które nie:

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

Możesz zapisać przestrzeń nazw dla wszystkich kolejnych poleceń kubectl w tym kontekście.

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

Helm

Helm jest menedżerem pakietów dla Kubernetesa. Pozwala spakować pliki YAML i rozpowszechniać je w publicznych i prywatnych repozytoriach. Te pakiety nazywane są wykresami Helma.

helm search <keyword>

Sekrety Kubernetes

Sekret to obiekt, który zawiera poufne dane takie jak hasło, token lub klucz. Takie informacje mogą być umieszczone w specyfikacji Pod lub w obrazie. Użytkownicy mogą tworzyć Sekrety, a system również tworzy Sekrety. Nazwa obiektu Sekretu musi być prawidłową nazwą poddomeny DNS. Przeczytaj tutaj oficjalną dokumentację.

Sekrety mogą zawierać:

  • Klucze API, SSH.

  • Tokeny OAuth.

  • Poświadczenia, hasła (czysty tekst lub b64 + szyfrowanie).

  • Informacje lub komentarze.

  • Kod łączenia z bazą danych, ciągi... .

Istnieją różne typy sekretów w Kubernetes

Typ wbudowanyUżycie

Opaque

dowolne dane zdefiniowane przez użytkownika (Domyślne)

kubernetes.io/service-account-token

token konta usługi

kubernetes.io/dockercfg

zserializowany plik ~/.dockercfg

kubernetes.io/dockerconfigjson

zserializowany plik ~/.docker/config.json

kubernetes.io/basic-auth

poświadczenia do autentykacji podstawowej

kubernetes.io/ssh-auth

poświadczenia do autentykacji SSH

kubernetes.io/tls

dane dla klienta lub serwera TLS

bootstrap.kubernetes.io/token

dane tokena startowego

Typ Opaque jest domyślny, to typowy zestaw klucz-wartość zdefiniowany przez użytkowników.

Jak działają sekrety:

Poniższy plik konfiguracyjny definiuje sekret o nazwie mysecret z 2 parami klucz-wartość username: YWRtaW4= i password: MWYyZDFlMmU2N2Rm. Definiuje również pod o nazwie secretpod, który będzie miał username i password zdefiniowane w mysecret ujawnione w zmiennych środowiskowych SECRET_USERNAME i SECRET_PASSWOR. Będzie również zamontowany sekret username wewnątrz mysecret pod ścieżką /etc/foo/my-group/my-username z uprawnieniami 0640.

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

Sekrety w etcd

etcd to spójny i wysoce dostępny sklep kluczy-wartości używany jako magazyn danych klastra Kubernetes. Pozwólmy na dostęp do przechowywanych w etcd sekretów:

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

Zobaczysz, że certyfikaty, klucze i adresy URL znajdują się w systemie plików. Gdy je uzyskasz, będziesz mógł połączyć się z etcd.

#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

Gdy już osiągniesz nawiązanie komunikacji, będziesz mógł uzyskać tajemnice:

#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

Dodawanie szyfrowania do ETCD

Domyślnie wszystkie tajemnice są przechowywane w formie czystego tekstu wewnątrz etcd, chyba że zastosujesz warstwę szyfrowania. Poniższy przykład jest oparty na 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: {}

Następnie musisz ustawić flagę --encryption-provider-config na kube-apiserver, aby wskazywała na lokalizację utworzonego pliku konfiguracyjnego. Możesz zmodyfikować /etc/kubernetes/manifest/kube-apiserver.yaml i dodać następujące linie:

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

Przewiń w dół w sekcji volumeMounts:

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

Przewiń w dół w volumeMounts do hostPath:

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

Weryfikacja, czy dane są zaszyfrowane

Dane są szyfrowane podczas zapisywania do etcd. Po ponownym uruchomieniu kube-apiserver, każdy nowo utworzony lub zaktualizowany sekret powinien być zaszyfrowany podczas przechowywania. Aby sprawdzić, możesz użyć programu wiersza poleceń etcdctl, aby pobrać zawartość swojego sekretu.

  1. Utwórz nowy sekret o nazwie secret1 w przestrzeni nazw default:

kubectl create secret generic secret1 -n default --from-literal=mykey=mydata
  1. Korzystając z polecenia etcdctl, odczytaj ten sekret z etcd:

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

gdzie [...] muszą być dodatkowymi argumentami do połączenia z serwerem etcd. 3. Zweryfikuj, czy przechowywany sekret jest poprzedzony k8s:enc:aescbc:v1:, co wskazuje, że dostawca aescbc zaszyfrował dane wynikowe. 4. Zweryfikuj, czy sekret jest poprawnie odszyfrowany podczas pobierania za pomocą interfejsu API:

kubectl describe secret secret1 -n default

powinno pasować do mykey: bXlkYXRh, mydata jest zakodowana, sprawdź dekodowanie sekretu, aby całkowicie odszyfrować sekret.

Ponieważ sekrety są szyfrowane podczas zapisywania, wykonanie aktualizacji na sekrecie spowoduje zaszyfrowanie tego treści:

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

Ostateczne wskazówki:

Referencje

Naucz się i ćwicz hakowanie AWS:HackTricks Training AWS Red Team Expert (ARTE) Naucz się i ćwicz hakowanie GCP: HackTricks Training GCP Red Team Expert (GRTE)

Wesprzyj HackTricks

Last updated