Exposing Services in Kubernetes

Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks:

Istnieje kilka sposobów ujawniania usług w Kubernetes, dzięki czemu zarówno wewnętrzne punkty końcowe, jak i zewnętrzne punkty końcowe mogą do nich uzyskać dostęp. Konfiguracja Kubernetes jest dość krytyczna, ponieważ administrator może udostępnić atakującym usługi, do których nie powinni mieć dostępu.

Automatyczne wyliczanie

Przed rozpoczęciem wyliczania sposobów, jakie K8s oferuje do ujawniania usług publicznie, warto wiedzieć, że jeśli można wyświetlić przestrzenie nazw, usługi i wprowadzenia, można znaleźć wszystko, co jest ujawnione publicznie za pomocą:

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

Usługa ClusterIP jest domyślną usługą Kubernetes. Daje ci usługę wewnątrz twojego klastra, do której inne aplikacje wewnątrz klastra mogą uzyskać dostęp. Nie ma dostępu zewnętrznego.

Jednak można uzyskać do niej dostęp za pomocą Kubernetes Proxy:

kubectl proxy --port=8080

Teraz możesz nawigować przez interfejs API Kubernetes, aby uzyskać dostęp do usług, korzystając z tego schematu:

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

Na przykład, możesz użyć następującego adresu URL:

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

aby uzyskać dostęp do tej usługi:

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

Ta metoda wymaga uruchomienia kubectl jako uwierzytelniony użytkownik.

NodePort

Kiedy jest wykorzystywany NodePort, określony port jest udostępniany na wszystkich węzłach (reprezentujących wirtualne maszyny). Ruch skierowany do tego konkretnego portu jest następnie systematycznie kierowany do usługi. Zwykle ta metoda nie jest zalecana ze względu na jej wady.

Przykład specyfikacji NodePort:

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

Jeśli nie określisz nodePort w pliku yaml (jest to port, który zostanie otwarty), zostanie użyty port w zakresie 30000-32767.

LoadBalancer

Wystawia usługę na zewnątrz, korzystając z load balancera dostawcy chmury. W przypadku GKE, zostanie uruchomiony Network Load Balancer, który zapewni pojedynczy adres IP, przekierowujący cały ruch do Twojej usługi.

Musisz płacić za LoadBalancer dla każdej wystawionej usługi, co może być kosztowne.

ExternalName

Z dokumentacji: Usługi typu ExternalName mapują usługę na nazwę DNS, a nie na typowy selektor, tak jak my-service lub cassandra. Określasz te usługi za pomocą parametru spec.externalName.

Na przykład, poniższa definicja usługi mapuje usługę my-service w przestrzeni nazw prod na my.database.example.com:

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

Podczas wyszukiwania hosta my-service.prod.svc.cluster.local, usługa DNS klastra zwraca rekord CNAME o wartości my.database.example.com. Dostęp do my-service działa tak samo jak w przypadku innych usług, ale z istotną różnicą, że przekierowanie następuje na poziomie DNS, a nie za pośrednictwem proxy lub przekazywania.

Zewnętrzne adresy IP

Ruch, który wchodzi do klastra z zewnętrznym adresem IP (jako adres docelowy IP) na porcie usługi, zostanie przekierowany do jednego z punktów końcowych usługi. externalIPs nie są zarządzane przez Kubernetes i są odpowiedzialnością administratora klastra.

W specyfikacji usługi można określić externalIPs wraz z dowolnym z ServiceTypes. W poniższym przykładzie "my-service" można uzyskać dostęp przez klientów na "80.11.12.10:80" (externalIP:port)

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

Ingress

W przeciwieństwie do wszystkich powyższych przykładów, Ingress NIE jest rodzajem usługi. Zamiast tego, działa on przed wieloma usługami i pełni rolę "inteligentnego routera" lub punktu wejścia do klastra.

Możesz wykonywać wiele różnych czynności za pomocą Ingress, a istnieje wiele rodzajów kontrolerów Ingress o różnych możliwościach.

Domyślny kontroler Ingress w GKE uruchomi dla Ciebie Load Balancer HTTP(S). Dzięki temu będziesz mógł wykonywać zarówno routowanie oparte na ścieżce, jak i oparte na subdomenie do usług backendowych. Na przykład, możesz przekierować wszystko na foo.yourdomain.com do usługi foo, a wszystko pod ścieżką yourdomain.com/bar/ do usługi bar.

Poniżej znajduje się przykład YAML dla obiektu Ingress w GKE z Load Balancerem HTTP L7:

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

Odnośniki

Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks:

Last updated