Izlaganje usluga u Kubernetesu

Reading time: 7 minutes

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

Postoje različiti načini za izlaganje usluga u Kubernetesu tako da i interni i eksterni krajnji tačke mogu da im pristupe. Ova Kubernetes konfiguracija je prilično kritična jer administrator može dati pristup napadačima uslugama kojima ne bi trebali imati pristup.

Automatska enumeracija

Pre nego što počnete da enumerišete načine na koje K8s nudi izlaganje usluga javnosti, znajte da ako možete da listate namespace-ove, usluge i ingrese, možete pronaći sve što je izloženo javnosti sa:

bash
kubectl get namespace -o custom-columns='NAME:.metadata.name' | grep -v NAME | while IFS='' read -r ns; do
echo "Namespace: $ns"
kubectl get service -n "$ns"
kubectl get ingress -n "$ns"
echo "=============================================="
echo ""
echo ""
done | grep -v "ClusterIP"
# Remove the last '| grep -v "ClusterIP"' to see also type ClusterIP

ClusterIP

ClusterIP servis je podrazumevani Kubernetes servis. Omogućava vam servis unutar vašeg klastera kojem mogu pristupiti druge aplikacije unutar vašeg klastera. Nema spoljnog pristupa.

Međutim, ovo se može pristupiti koristeći Kubernetes Proxy:

bash
kubectl proxy --port=8080

Sada možete navigirati kroz Kubernetes API da biste pristupili uslugama koristeći ovu shemu:

http://localhost:8080/api/v1/proxy/namespaces/<NAMESPACE>/services/<SERVICE-NAME>:<PORT-NAME>/

Na primer, možete koristiti sledeći URL:

http://localhost:8080/api/v1/proxy/namespaces/default/services/my-internal-service:http/

da biste pristupili ovoj usluzi:

yaml
apiVersion: v1
kind: Service
metadata:
name: my-internal-service
spec:
selector:
app: my-app
type: ClusterIP
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP

Ova metoda zahteva da pokrenete kubectl kao autentifikovani korisnik.

Nabrojte sve ClusterIP-ove:

bash
kubectl get services --all-namespaces -o=custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,TYPE:.spec.type,CLUSTER-IP:.spec.clusterIP,PORT(S):.spec.ports[*].port,TARGETPORT(S):.spec.ports[*].targetPort,SELECTOR:.spec.selector' | grep ClusterIP

NodePort

Kada se koristi NodePort, određeni port je dostupan na svim čvorovima (koji predstavljaju virtuelne mašine). Saobraćaj usmeren na ovaj specifičan port se sistematski usmerava ka servisu. Obično, ova metoda se ne preporučuje zbog svojih nedostataka.

Lista svih NodePort-ova:

bash
kubectl get services --all-namespaces -o=custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,TYPE:.spec.type,CLUSTER-IP:.spec.clusterIP,PORT(S):.spec.ports[*].port,NODEPORT(S):.spec.ports[*].nodePort,TARGETPORT(S):.spec.ports[*].targetPort,SELECTOR:.spec.selector' | grep NodePort

Primer specifikacije NodePort:

yaml
apiVersion: v1
kind: Service
metadata:
name: my-nodeport-service
spec:
selector:
app: my-app
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
nodePort: 30036
protocol: TCP

Ako ne navedete nodePort u yaml-u (to je port koji će biti otvoren), koristiće se port u opsegu 30000–32767.

LoadBalancer

Izlaže Servis spolja koristeći load balancer provajdera u oblaku. Na GKE, ovo će pokrenuti Network Load Balancer koji će vam dati jedinstvenu IP adresu koja će preusmeriti sav saobraćaj na vaš servis. U AWS-u će pokrenuti Load Balancer.

Morate plaćati za LoadBalancer po izloženom servisu, što može biti skupo.

Lista svih LoadBalancera:

bash
kubectl get services --all-namespaces -o=custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,TYPE:.spec.type,CLUSTER-IP:.spec.clusterIP,EXTERNAL-IP:.status.loadBalancer.ingress[*],PORT(S):.spec.ports[*].port,NODEPORT(S):.spec.ports[*].nodePort,TARGETPORT(S):.spec.ports[*].targetPort,SELECTOR:.spec.selector' | grep LoadBalancer

Eksterne IP adrese

tip

Eksterne IP adrese su izložene od strane usluga tipa Load Balancers i obično se koriste kada se koristi eksterna Cloud Provider Load Balancer.

Da biste ih pronašli, proverite load balancere sa vrednostima u polju EXTERNAL-IP.

Saobraćaj koji ulazi u klaster sa eksternom IP adresom (kao odredišna IP adresa), na portu usluge, biće usmeren na jedan od krajnjih tačaka usluge. externalIPs nisu upravljane od strane Kubernetesa i odgovornost su administratora klastera.

U specifikaciji usluge, externalIPs mogu biti navedene zajedno sa bilo kojim od ServiceTypes. U sledećem primeru, "my-service" može biti pristupljeno od strane klijenata na "80.11.12.10:80" (externalIP:port)

yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- name: http
protocol: TCP
port: 80
targetPort: 9376
externalIPs:
- 80.11.12.10

ExternalName

Iz dokumenata: Servisi tipa ExternalName mapiraju servis na DNS ime, a ne na tipičan selektor kao što je my-service ili cassandra. Ove servise definišete pomoću parametra spec.externalName.

Ova definicija servisa, na primer, mapira my-service servis u prod imenskom prostoru na my.database.example.com:

yaml
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: prod
spec:
type: ExternalName
externalName: my.database.example.com

Kada se traži host my-service.prod.svc.cluster.local, klasterska DNS usluga vraća CNAME zapis sa vrednošću my.database.example.com. Pristup my-service funkcioniše na isti način kao i druge usluge, ali sa ključnom razlikom da preusmeravanje se dešava na DNS nivou umesto putem proksiranja ili prosleđivanja.

Nabrojte sve ExternalNames:

bash
kubectl get services --all-namespaces | grep ExternalName

Ingress

Za razliku od svih gore navedenih primera, Ingress NIJE tip usluge. Umesto toga, on se nalazi ispred više usluga i deluje kao “pametan ruter” ili ulazna tačka u vaš klaster.

Možete raditi mnogo različitih stvari sa Ingress-om, i postoje različite vrste Ingress kontrolera koji imaju različite mogućnosti.

Podrazumevani GKE ingress kontroler će pokrenuti HTTP(S) Load Balancer za vas. Ovo će vam omogućiti da radite i rutiranje zasnovano na putanji i rutiranje zasnovano na poddomenama ka pozadinskim uslugama. Na primer, možete poslati sve na foo.yourdomain.com ka foo usluzi, i sve ispod putanje yourdomain.com/bar/ ka bar usluzi.

YAML za Ingress objekat na GKE sa L7 HTTP Load Balancer može izgledati ovako:

yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
spec:
backend:
serviceName: other
servicePort: 8080
rules:
- host: foo.mydomain.com
http:
paths:
- backend:
serviceName: foo
servicePort: 8080
- host: mydomain.com
http:
paths:
- path: /bar/*
backend:
serviceName: bar
servicePort: 8080

Nabrojite sve ulaze:

bash
kubectl get ingresses --all-namespaces -o=custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,RULES:spec.rules[*],STATUS:status'

Iako je u ovom slučaju bolje dobiti informacije o svakom pojedinačno kako bi se lakše pročitali:

bash
kubectl get ingresses --all-namespaces -o=yaml

Reference

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