Exposing Services in Kubernetes
Reading time: 8 minutes
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le đŹ groupe Discord ou le groupe telegram ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépÎts github.
Il existe différentes maniÚres d'exposer des services dans Kubernetes afin que les points de terminaison internes et externes puissent y accéder. Cette configuration Kubernetes est assez critique car l'administrateur pourrait donner accÚs à des attaquants à des services auxquels ils ne devraient pas avoir accÚs.
Automatic Enumeration
Avant de commencer à énumérer les maniÚres dont K8s offre d'exposer des services au public, sachez que si vous pouvez lister les espaces de noms, les services et les ingresses, vous pouvez trouver tout ce qui est exposé au public avec :
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
Un service ClusterIP est le service par défaut de Kubernetes. Il vous fournit un service à l'intérieur de votre cluster auquel d'autres applications à l'intérieur de votre cluster peuvent accéder. Il n'y a pas d'accÚs externe.
Cependant, cela peut ĂȘtre accessible en utilisant le Proxy Kubernetes :
kubectl proxy --port=8080
Maintenant, vous pouvez naviguer à travers l'API Kubernetes pour accéder aux services en utilisant ce schéma :
http://localhost:8080/api/v1/proxy/namespaces/<NAMESPACE>/services/<SERVICE-NAME>:<PORT-NAME>/
Par exemple, vous pourriez utiliser l'URL suivante :
http://localhost:8080/api/v1/proxy/namespaces/default/services/my-internal-service:http/
pour accéder à ce service :
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
Cette méthode nécessite que vous exécutiez kubectl
en tant qu'utilisateur authentifié.
Listez tous les ClusterIPs :
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
Lorsque NodePort est utilisĂ©, un port dĂ©signĂ© est rendu disponible sur tous les nĆuds (reprĂ©sentant les machines virtuelles). Le trafic dirigĂ© vers ce port spĂ©cifique est ensuite systĂ©matiquement acheminĂ© vers le service. En gĂ©nĂ©ral, cette mĂ©thode n'est pas recommandĂ©e en raison de ses inconvĂ©nients.
Liste de tous les 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
Un exemple de spécification 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
Si vous ne spĂ©cifiez pas le nodePort dans le yaml (c'est le port qui sera ouvert), un port dans la plage 30000â32767 sera utilisĂ©.
LoadBalancer
Expose le Service à l'extérieur en utilisant le load balancer d'un fournisseur de cloud. Sur GKE, cela lancera un Network Load Balancer qui vous donnera une seule adresse IP qui redirigera tout le trafic vers votre service. Sur AWS, cela lancera un Load Balancer.
Vous devez payer pour un LoadBalancer par service exposĂ©, ce qui peut ĂȘtre coĂ»teux.
Listez tous les 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
Les IP externes sont exposées par des services de type Load Balancers et elles sont généralement utilisées lorsqu'un Load Balancer de fournisseur de Cloud externe est utilisé.
Pour les trouver, vérifiez les load balancers avec des valeurs dans le champ EXTERNAL-IP
.
Le trafic qui entre dans le cluster avec l'IP externe (comme IP de destination), sur le port du Service, sera acheminé vers l'un des points de terminaison du Service. externalIPs
ne sont pas gérés par Kubernetes et relÚvent de la responsabilité de l'administrateur du cluster.
Dans la spécification du Service, externalIPs
peuvent ĂȘtre spĂ©cifiĂ©s avec n'importe lequel des ServiceTypes
. Dans l'exemple ci-dessous, "my-service
" peut ĂȘtre accessible par les clients sur "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
ExternalName
D'aprÚs la documentation : Les Services de type ExternalName mappent un Service à un nom DNS, et non à un sélecteur typique tel que my-service
ou cassandra
. Vous spécifiez ces Services avec le paramÚtre spec.externalName
.
Cette définition de Service, par exemple, mappe le Service my-service
dans l'espace de noms prod
Ă my.database.example.com
:
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: prod
spec:
type: ExternalName
externalName: my.database.example.com
Lors de la recherche de l'hĂŽte my-service.prod.svc.cluster.local
, le Service DNS du cluster renvoie un enregistrement CNAME
avec la valeur my.database.example.com
. L'accĂšs Ă my-service
fonctionne de la mĂȘme maniĂšre que d'autres Services, mais avec la diffĂ©rence cruciale que la redirection se produit au niveau DNS plutĂŽt que par le biais de proxy ou de transfert.
Listez tous les ExternalNames :
kubectl get services --all-namespaces | grep ExternalName
Ingress
Contrairement à tous les exemples ci-dessus, Ingress n'est PAS un type de service. Au lieu de cela, il se trouve devant plusieurs services et agit comme un "routeur intelligent" ou point d'entrée dans votre cluster.
Vous pouvez faire beaucoup de choses différentes avec un Ingress, et il existe de nombreux types de contrÎleurs Ingress qui ont des capacités différentes.
Le contrÎleur d'ingress GKE par défaut va créer un HTTP(S) Load Balancer pour vous. Cela vous permettra de faire à la fois un routage basé sur le chemin et un routage basé sur le sous-domaine vers des services backend. Par exemple, vous pouvez envoyer tout sur foo.yourdomain.com au service foo, et tout sous le chemin yourdomain.com/bar/ au service bar.
Le YAML pour un objet Ingress sur GKE avec un L7 HTTP Load Balancer pourrait ressembler Ă ceci :
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
Listez tous les ingresses :
kubectl get ingresses --all-namespaces -o=custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name,RULES:spec.rules[*],STATUS:status'
Bien qu'il soit préférable dans ce cas d'obtenir les informations de chacun un par un pour mieux les lire :
kubectl get ingresses --all-namespaces -o=yaml
Références
- 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
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le đŹ groupe Discord ou le groupe telegram ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépÎts github.