Osnovi Kubernetesa

Reading time: 18 minutes

Osnovi Kubernetesa

tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks

Originalni autor ove stranice je Jorge (pročitajte njegov originalni post ovde)

Arhitektura i Osnovi

Šta radi Kubernetes?

  • Omogućava pokretanje kontejnera u kontejnerskom motoru.
  • Raspoređuje kontejnerske misije efikasno.
  • Održava kontejnere aktivnim.
  • Omogućava komunikaciju između kontejnera.
  • Omogućava tehnike implementacije.
  • Rukuje količinama informacija.

Arhitektura

  • Čvor: operativni sistem sa podom ili podovima.
  • Pod: Omotač oko kontejnera ili više kontejnera. Pod bi trebao sadržati samo jednu aplikaciju (tako da obično, pod pokreće samo 1 kontejner). Pod je način na koji Kubernetes apstrahuje tehnologiju kontejnera koja se pokreće.
  • Servis: Svaki pod ima 1 internu IP adresu iz unutrašnjeg opsega čvora. Međutim, može biti izložen i putem servisa. Servis takođe ima IP adresu i njegov cilj je održavanje komunikacije između podova, tako da ako jedan umre, novi zamenski (sa drugačijom internom IP) će biti dostupan izložen na isto IP servisa. Može se konfigurisati kao unutrašnji ili spoljašnji. Servis takođe deluje kao balansirnik opterećenja kada su 2 poda povezana na isti servis.
    Kada se servis kreira, možete pronaći krajnje tačke svakog servisa pokretanjem kubectl get endpoints
  • Kubelet: Primarni agent čvora. Komponenta koja uspostavlja komunikaciju između čvora i kubectl, i može pokretati samo podove (putem API servera). Kubelet ne upravlja kontejnerima koji nisu kreirani od strane Kubernetesa.
  • Kube-proxy: je servis zadužen za komunikaciju (servise) između apiservera i čvora. Osnova je IPtables za čvorove. Najiskusniji korisnici mogu instalirati druge kube-proxije od drugih dobavljača.
  • Sidecar kontejner: Sidecar kontejneri su kontejneri koji bi trebali raditi zajedno sa glavnim kontejnerom u podu. Ovaj sidecar obrazac proširuje i poboljšava funkcionalnost trenutnih kontejnera bez njihovog menjanja. Danas znamo da koristimo tehnologiju kontejnera da obavijemo sve zavisnosti za aplikaciju da bi radila bilo gde. Kontejner radi samo jednu stvar i radi tu stvar veoma dobro.
  • Glavni proces:
  • Api Server: Je način na koji korisnici i podovi komuniciraju sa glavnim procesom. Samo autentifikovani zahtevi bi trebali biti dozvoljeni.
  • Raspoređivač: Raspoređivanje se odnosi na osiguranje da su podovi usklađeni sa čvorovima kako bi Kubelet mogao da ih pokrene. Ima dovoljno inteligencije da odluči koji čvor ima više dostupnih resursa i dodeli novi pod njemu. Imajte na umu da raspoređivač ne pokreće nove podove, samo komunicira sa Kubelet procesom koji se pokreće unutar čvora, koji će pokrenuti novi pod.
  • Kube Controller menadžer: Proverava resurse kao što su replikacione grupe ili implementacije da proveri da li, na primer, ispravan broj podova ili čvorova radi. U slučaju da nedostaje pod, komuniciraće sa raspoređivačem da pokrene novi. Kontroliše replikaciju, tokene i usluge računa za API.
  • etcd: Skladište podataka, postojano, konzistentno i distribuirano. To je baza podataka Kubernetesa i skladište ključ-vrednost gde čuva potpuno stanje klastera (svaka promena se ovde beleži). Komponente kao što su Raspoređivač ili Menadžer kontrolera zavise od ovih podataka da bi znale koje su promene nastale (dostupni resursi čvorova, broj pokrenutih podova...)
  • Cloud controller menadžer: Specifični je kontroler za tokove kontrole i aplikacije, tj: ako imate klastere u AWS-u ili OpenStack-u.

Imajte na umu da kako može biti nekoliko čvorova (koji pokreću nekoliko podova), može biti i nekoliko glavnih procesa čiji je pristup API serveru balansiran opterećenjem i njihov etcd sinhronizovan.

Volumeni:

Kada pod kreira podatke koji ne bi trebali biti izgubljeni kada pod nestane, trebali bi biti smešteni u fizičkom volumenu. Kubernetes omogućava povezivanje volumena sa podom kako bi se podaci sačuvali. Volumen može biti na lokalnoj mašini ili u daljinskom skladištu. Ako pokrećete podove na različitim fizičkim čvorovima, trebali biste koristiti daljinsko skladište kako bi svi podovi mogli da mu pristupe.

Druge konfiguracije:

  • ConfigMap: Možete konfigurisati URL-ove za pristup servisima. Pod će dobiti podatke odavde da zna kako da komunicira sa ostalim servisima (podovima). Imajte na umu da ovo nije preporučeno mesto za čuvanje akreditiva!
  • Secret: Ovo je mesto za čuvanje tajnih podataka kao što su lozinke, API ključevi... kodirani u B64. Pod će moći da pristupi ovim podacima da koristi potrebne akreditive.
  • Implementacije: Ovo je mesto gde su navedeni komponenti koje će Kubernetes pokrenuti. Korisnik obično ne radi direktno sa podovima, podovi su apstrahovani u ReplicaSets (broj istih podova replikovanih), koji se pokreću putem implementacija. Imajte na umu da su implementacije za stateless aplikacije. Minimalna konfiguracija za implementaciju je ime i slika koja se pokreće.
  • StatefulSet: Ova komponenta je namenjena posebno za aplikacije kao što su baze podataka koje trebaju pristup istom skladištu.
  • Ingress: Ovo je konfiguracija koja se koristi za izlaganje aplikacije javno putem URL-a. Imajte na umu da se ovo može uraditi i korišćenjem spoljašnjih servisa, ali ovo je ispravan način za izlaganje aplikacije.
  • Ako implementirate Ingress, biće potrebno da kreirate Ingress kontrolere. Ingress kontroler je pod koji će biti krajnja tačka koja će primati zahteve, proveravati ih i balansirati ih na servise. Ingress kontroler će slati zahtev na osnovu konfigurisanih ingress pravila. Imajte na umu da ingress pravila mogu ukazivati na različite putanje ili čak poddomene različitim internim Kubernetes servisima.
  • Bolja praksa u vezi sa bezbednošću bi bila korišćenje cloud balansirnika opterećenja ili proxy servera kao ulazne tačke kako ne bi bilo koje delove Kubernetes klastera izložene.
  • Kada se primi zahtev koji ne odgovara nijednom ingress pravilu, ingress kontroler će ga usmeriti na "Default backend". Možete describe ingress kontroler da dobijete adresu ovog parametra.
  • minikube addons enable ingress

PKI infrastruktura - Sertifikacijska vlast CA:

  • CA je poverljivi koren za sve sertifikate unutar klastera.
  • Omogućava komponentama da se međusobno validiraju.
  • Svi klasterski sertifikati su potpisani od strane CA.
  • ETCd ima svoj sertifikat.
  • tipovi:
  • apiserver sertifikat.
  • kubelet sertifikat.
  • raspoređivač sertifikat.

Osnovne Akcije

Minikube

Minikube se može koristiti za izvođenje nekih brzih testova na Kubernetesu bez potrebe za implementacijom celog Kubernetes okruženja. Pokrenuće glavne i čvorne procese na jednoj mašini. Minikube će koristiti virtualbox za pokretanje čvora. Pogledajte ovde kako da ga instalirate.

$ 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 Osnovi

Kubectl je alat za komandnu liniju za kubernetes klastere. Komunicira sa Api serverom glavnog procesa kako bi izvršio akcije u kubernetesu ili zatražio podatke.

bash
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

Dashboard vam omogućava da lakše vidite šta minikube radi, možete pronaći URL za pristup u:

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/

YAML конфигурационе датотеке примери

Свака конфигурациона датотека има 3 дела: метаподаци, спецификација (шта треба да се покрене), статус (жељено стање).
Унутар спецификације конфигурационе датотеке за распоређивање можете пронаћи шаблон дефинисан новом конфигурационом структуром која дефинише слику за покретање:

Пример распоређивања + услуге декларисане у истој конфигурационој датотеци (из овде)

Како је услуга обично повезана са једним распоређивањем, могуће је декларисати обе у истој конфигурационој датотеци (услуга декларисана у овој конфигурацији је доступна само интерно):

yaml
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

Primer konfiguracije spoljne usluge

Ova usluga će biti dostupna spolja (proverite atribute nodePort i type: LoadBlancer):

yaml
---
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

note

Ovo je korisno za testiranje, ali za produkciju trebate imati samo interne usluge i Ingress za izlaganje aplikacije.

Primer Ingress konfiguracione datoteke

Ovo će izložiti aplikaciju na http://dashboard.com.

yaml
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

Primer konfiguracione datoteke za tajne

Obratite pažnju na to kako su lozinke kodirane u B64 (što nije sigurno!)

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

Primer ConfigMap-a

A ConfigMap je konfiguracija koja se daje podovima kako bi znali kako da lociraju i pristupaju drugim servisima. U ovom slučaju, svaki pod će znati da je ime mongodb-service adresa poda sa kojim mogu da komuniciraju (ovaj pod će izvršavati mongodb):

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

Zatim, unutar deployment config ova adresa može biti specificirana na sledeći način kako bi se učitala unutar env pod-a:

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

Primer konfiguracije volumena

Možete pronaći različite primere yaml datoteka za konfiguraciju skladišta na https://gitlab.com/nanuchi/youtube-tutorial-series/-/tree/master/kubernetes-volumes.
Napomena: volumeni nisu unutar imenskih prostora

Imenski prostori

Kubernetes podržava više virtuelnih klastera koji se oslanjaju na isti fizički klaster. Ovi virtuelni klasteri se nazivaju imenski prostori. Namenjeni su za korišćenje u okruženjima sa mnogo korisnika raspoređenih u više timova ili projekata. Za klastere sa nekoliko do desetina korisnika, ne bi trebalo da kreirate ili razmišljate o imenskim prostorima. Trebalo bi da počnete da koristite imenske prostore kako biste imali bolju kontrolu i organizaciju svake komponente aplikacije koja je implementirana u kubernetesu.

Imenski prostori pružaju opseg za imena. Imena resursa moraju biti jedinstvena unutar imenskog prostora, ali ne i između imenskih prostora. Imenski prostori ne mogu biti ugnježdeni jedni unutar drugih i svaki Kubernetes resurs može biti samo u jednom imenskom prostoru.

Postoje 4 imenska prostora po defaultu ako koristite 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: Nije namenjen za korišćenje od strane korisnika i ne biste trebali da ga dirate. To je za master i kubectl procese.
  • kube-public: Javno dostupni podaci. Sadrži configmap koji sadrži informacije o klasteru.
  • kube-node-lease: Određuje dostupnost čvora.
  • default: Namespace koji korisnik koristi za kreiranje resursa.
bash
#Create namespace
kubectl create namespace my-namespace

note

Imajte na umu da su većina Kubernetes resursa (npr. pods, services, replication controllers i drugi) u nekim namespaces. Međutim, drugi resursi kao što su namespace resursi i niskonivo resursi, kao što su nodes i persistentVolumes, nisu u namespace-u. Da biste videli koji Kubernetes resursi su i nisu u namespace-u:

kubectl api-resources --namespaced=true #U namespace-u
kubectl api-resources --namespaced=false #Nije u namespace-u

Možete sačuvati namespace za sve naredne kubectl komande u tom kontekstu.

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

Helm

Helm je menadžer paketa za Kubernetes. Omogućava pakovanje YAML datoteka i distribuciju u javnim i privatnim repozitorijumima. Ovi paketi se nazivaju Helm Charts.

helm search <keyword>

Helm je takođe engine za šablone koji omogućava generisanje konfiguracionih fajlova sa promenljivim:

Kubernetes tajne

Tajna je objekat koji sadrži osetljive podatke kao što su lozinka, token ili ključ. Takve informacije bi inače mogle biti stavljene u specifikaciju Pod-a ili u sliku. Korisnici mogu kreirati Tajne, a sistem takođe kreira Tajne. Ime objekta Tajne mora biti validno DNS poddomen ime. Pročitajte ovde zvaničnu dokumentaciju.

Tajne mogu biti stvari poput:

  • API, SSH ključevi.
  • OAuth tokeni.
  • Akreditivi, Lozinke (obični tekst ili b64 + enkripcija).
  • Informacije ili komentari.
  • Kod za povezivanje sa bazom podataka, stringovi… .

Postoje različite vrste tajni u Kubernetes-u

Ugrađena vrstaUpotreba
Opaquearbitrarni podaci koje definiše korisnik (Podrazumevano)
kubernetes.io/service-account-tokentoken za servisni nalog
kubernetes.io/dockercfgserijalizovana ~/.dockercfg datoteka
kubernetes.io/dockerconfigjsonserijalizovana ~/.docker/config.json datoteka
kubernetes.io/basic-authakreditivi za osnovnu autentifikaciju
kubernetes.io/ssh-authakreditivi za SSH autentifikaciju
kubernetes.io/tlspodaci za TLS klijent ili server
bootstrap.kubernetes.io/tokenpodaci o bootstrap tokenu

note

Opaque tip je podrazumevani, tipični par ključ-vrednost koji definišu korisnici.

Kako tajne funkcionišu:

Sledeći konfiguracioni fajl definiše tajnu pod nazivom mysecret sa 2 para ključ-vrednost username: YWRtaW4= i password: MWYyZDFlMmU2N2Rm. Takođe definiše pod pod nazivom secretpod koji će imati username i password definisane u mysecret izložene u promenljivim okruženja SECRET_USERNAME __ i __ SECRET_PASSWOR. Takođe će montirati tajnu username unutar mysecret na putanji /etc/foo/my-group/my-username sa 0640 dozvolama.

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
bash
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

Tajne u etcd

etcd je konzistentna i visoko dostupna key-value skladište koje se koristi kao pozadinsko skladište za sve podatke klastera u Kubernetes-u. Hajde da pristupimo tajnama koje su pohranjene u etcd:

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

Videćete certifikate, ključeve i URL-ove koji se nalaze u FS-u. Kada ih dobijete, moći ćete da se povežete na etcd.

bash
#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

Kada uspostavite komunikaciju, moći ćete da dobijete tajne:

bash
#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

Dodavanje enkripcije u ETCD

Po defaultu, sve tajne su smeštene u običnom tekstu unutar etcd-a, osim ako ne primenite sloj enkripcije. Sledeći primer se zasniva 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: {}

Nakon toga, potrebno je postaviti --encryption-provider-config zastavicu na kube-apiserver da ukazuje na lokaciju kreirane konfiguracione datoteke. Možete izmeniti /etc/kubernetes/manifest/kube-apiserver.yaml i dodati sledeće linije:

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

Pomaknite se prema dolje u volumeMounts:

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

Pomaknite se prema dolje u volumeMounts do hostPath:

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

Proveravanje da su podaci enkriptovani

Podaci su enkriptovani kada se zapisuju u etcd. Nakon ponovnog pokretanja vašeg kube-apiserver, svaka nova ili ažurirana tajna treba da bude enkriptovana kada se skladišti. Da biste proverili, možete koristiti etcdctl komandnu liniju da dobijete sadržaj vaše tajne.

  1. Kreirajte novu tajnu pod nazivom secret1 u default imenskom prostoru:
kubectl create secret generic secret1 -n default --from-literal=mykey=mydata
  1. Koristeći etcdctl komandnu liniju, pročitajte tu tajnu iz etcd:

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

gde [...] moraju biti dodatni argumenti za povezivanje sa etcd serverom.

  1. Proverite da je sačuvana tajna prefiksirana sa k8s:enc:aescbc:v1: što ukazuje da je aescbc provajder enkriptovao dobijene podatke.
  2. Proverite da je tajna ispravno dekriptovana kada se preuzme putem API-ja:
kubectl describe secret secret1 -n default

trebalo bi da odgovara mykey: bXlkYXRh, mydata je kodirana, proverite dekodiranje tajne da biste potpuno dekodirali tajnu.

Pošto su tajne enkriptovane prilikom pisanja, izvršavanje ažuriranja na tajni će enkriptovati taj sadržaj:

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

Završni saveti:

Reference

kubesectips v1 | sickrov.github.io

- YouTube

tip

Učite i vežbajte AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Učite i vežbajte Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Podržite HackTricks