Exposing Services in Kubernetes
Reading time: 7 minutes
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.
Es gibt verschiedene Möglichkeiten, Dienste in Kubernetes bereitzustellen, sodass sowohl interne als auch externe Endpunkte darauf zugreifen können. Diese Kubernetes-Konfiguration ist ziemlich kritisch, da der Administrator Angreifern Zugriff auf Dienste gewähren könnte, auf die sie keinen Zugriff haben sollten.
Automatische Enumeration
Bevor Sie mit der Auflistung der Möglichkeiten beginnen, die K8s bietet, um Dienste öffentlich bereitzustellen, wissen Sie, dass Sie, wenn Sie Namespaces, Dienste und Ingresses auflisten können, alles finden können, was öffentlich zugänglich ist mit:
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
Ein ClusterIP-Dienst ist der Standard-Kubernetes-Dienst. Er bietet Ihnen einen Dienst innerhalb Ihres Clusters, auf den andere Apps innerhalb Ihres Clusters zugreifen können. Es gibt keinen externen Zugriff.
Dieser kann jedoch über den Kubernetes Proxy zugegriffen werden:
kubectl proxy --port=8080
Jetzt können Sie über die Kubernetes-API auf Dienste zugreifen, indem Sie dieses Schema verwenden:
http://localhost:8080/api/v1/proxy/namespaces/<NAMESPACE>/services/<SERVICE-NAME>:<PORT-NAME>/
Zum Beispiel könnten Sie die folgende URL verwenden:
http://localhost:8080/api/v1/proxy/namespaces/default/services/my-internal-service:http/
um auf diesen Dienst zuzugreifen:
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
Diese Methode erfordert, dass Sie kubectl
als authentifizierter Benutzer ausführen.
Liste alle ClusterIPs auf:
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
Wenn NodePort verwendet wird, wird ein bestimmter Port auf allen Knoten (die die virtuellen Maschinen darstellen) verfügbar gemacht. Traffic, der an diesen spezifischen Port gerichtet ist, wird dann systematisch zum Dienst geleitet. Typischerweise wird diese Methode aufgrund ihrer Nachteile nicht empfohlen.
Liste aller NodePorts:
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
Ein Beispiel für die NodePort-Spezifikation:
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
Wenn Sie den nodePort im yaml nicht angeben, wird ein Port im Bereich 30000–32767 verwendet.
LoadBalancer
Stellt den Service extern unter Verwendung eines Load Balancers des Cloud-Anbieters bereit. In GKE wird dies einen Network Load Balancer starten, der Ihnen eine einzelne IP-Adresse gibt, die den gesamten Verkehr an Ihren Service weiterleitet. In AWS wird ein Load Balancer gestartet.
Sie müssen für jeden exponierten Service einen LoadBalancer bezahlen, was teuer sein kann.
Liste aller LoadBalancers:
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
External IPs
tip
Externe IPs werden von Diensten des Typs Load Balancers bereitgestellt und werden allgemein verwendet, wenn ein externer Cloud Provider Load Balancer verwendet wird.
Um sie zu finden, überprüfen Sie die Load Balancer mit Werten im Feld EXTERNAL-IP
.
Der Datenverkehr, der in den Cluster mit der externen IP (als Ziel-IP) auf dem Service-Port eingreift, wird zu einem der Service-Endpunkte weitergeleitet. externalIPs
werden nicht von Kubernetes verwaltet und liegen in der Verantwortung des Cluster-Administrators.
Im Service-Spezifikationsdokument können externalIPs
zusammen mit einem der ServiceTypes
angegeben werden. Im folgenden Beispiel kann "my-service
" von Clients unter "80.11.12.10:80
" (externalIP:port
) erreicht werden.
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
Aus den Dokumenten: Dienste vom Typ ExternalName verknüpfen einen Dienst mit einem DNS-Namen, nicht mit einem typischen Selektor wie my-service
oder cassandra
. Diese Dienste geben Sie mit dem Parameter spec.externalName
an.
Diese Dienstdefinition verknüpft beispielsweise den my-service
Dienst im prod
Namespace mit my.database.example.com
:
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: prod
spec:
type: ExternalName
externalName: my.database.example.com
Beim Nachschlagen des Hosts my-service.prod.svc.cluster.local
gibt der Cluster-DNS-Dienst einen CNAME
-Eintrag mit dem Wert my.database.example.com
zurück. Der Zugriff auf my-service
funktioniert auf die gleiche Weise wie bei anderen Diensten, jedoch mit dem entscheidenden Unterschied, dass die Umleitung auf DNS-Ebene und nicht über Proxy oder Weiterleitung erfolgt.
Liste alle ExternalNames auf:
kubectl get services --all-namespaces | grep ExternalName
Ingress
Im Gegensatz zu all den oben genannten Beispielen ist Ingress KEIN Typ von Dienst. Stattdessen sitzt es vor mehreren Diensten und fungiert als „intelligenter Router“ oder Einstiegspunkt in Ihren Cluster.
Sie können mit einem Ingress viele verschiedene Dinge tun, und es gibt viele Arten von Ingress-Controllern, die unterschiedliche Fähigkeiten haben.
Der standardmäßige GKE Ingress-Controller wird für Sie einen HTTP(S) Load Balancer erstellen. Dies ermöglicht Ihnen sowohl pfadbasierte als auch subdomainbasierte Weiterleitungen zu Backend-Diensten. Zum Beispiel können Sie alles auf foo.yourdomain.com an den foo-Dienst senden und alles unter dem Pfad yourdomain.com/bar/ an den bar-Dienst.
Die YAML für ein Ingress-Objekt auf GKE mit einem L7 HTTP Load Balancer könnte so aussehen:
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
Liste alle Ingresses:
kubectl get ingresses --all-namespaces -o=custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,RULES:spec.rules[*],STATUS:status'
Obwohl es in diesem Fall besser ist, die Informationen einzeln abzurufen, um sie besser lesen zu können:
kubectl get ingresses --all-namespaces -o=yaml
Referenzen
- https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0
- https://kubernetes.io/docs/concepts/services-networking/service/
tip
Lernen & üben Sie AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lernen & üben Sie GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lernen & üben Sie Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Unterstützen Sie HackTricks
- Überprüfen Sie die Abonnementpläne!
- Treten Sie der 💬 Discord-Gruppe oder der Telegram-Gruppe bei oder folgen Sie uns auf Twitter 🐦 @hacktricks_live.
- Teilen Sie Hacking-Tricks, indem Sie PRs an die HackTricks und HackTricks Cloud GitHub-Repos senden.