Exposing Services in Kubernetes

Вивчайте хакінг AWS від нуля до героя з htARTE (HackTricks AWS Red Team Expert)!

Інші способи підтримки HackTricks:

Існують різні способи викладання сервісів в Kubernetes, щоб до них могли отримати доступ як внутрішні, так і зовнішні кінцеві точки. Ця конфігурація Kubernetes є досить критичною, оскільки адміністратор може надати доступ зловмисникам до сервісів, до яких вони не повинні мати доступ.

Автоматичне перелічення

Перед тим як почати перелікати способи, які пропонує K8s для викладання сервісів для загального доступу, знайте, що якщо ви можете перелічити простори імен, сервіси та входи, ви можете знайти все, що викладено для загального доступу за допомогою:

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 сервіс - це типовий сервіс Kubernetes. Він надає вам сервіс всередині вашого кластера, до якого можуть отримати доступ інші додатки всередині вашого кластера. Зовнішній доступ відсутній.

Однак до нього можна отримати доступ за допомогою Kubernetes Proxy:

kubectl proxy --port=8080

Зараз ви можете перейти до API Kubernetes, щоб отримати доступ до сервісів за допомогою цієї схеми:

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

Наприклад, ви можете використати наступну URL-адресу:

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

для доступу до цього сервісу:

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

Цей метод вимагає виконання kubectl як аутентифікованого користувача.

NodePort

Коли використовується NodePort, призначений порт стає доступним на всіх вузлах (що представляють віртуальні машини). Трафік, спрямований на цей конкретний порт, потім систематично маршрутизується до сервісу. Зазвичай цей метод не рекомендується через його недоліки.

Приклад специфікації 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

Якщо ви не вказуєте nodePort в yaml (це порт, який буде відкритий), буде використано порт у діапазоні 30000–32767.

LoadBalancer

Викладає сервіс зовні за допомогою балансувальника навантаження хмарного постачальника. На GKE це запустить Мережевий балансувальник навантаження, який надасть вам одну IP-адресу, яка буде пересилати весь трафік на ваш сервіс.

Вам потрібно платити за кожен балансувальник навантаження за кожен викладений сервіс, що може бути дорогим.

ExternalName

З документації: Сервіси типу ExternalName відображають сервіс на DNS-ім'я, а не на типовий селектор, такий як my-service або cassandra. Ви вказуєте ці сервіси за допомогою параметра spec.externalName.

Наприклад, це визначення сервісу відображає сервіс my-service в просторі імен prod на my.database.example.com:

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

При пошуку хоста my-service.prod.svc.cluster.local сервіс DNS кластера повертає запис CNAME зі значенням my.database.example.com. Доступ до my-service працює так само, як і до інших сервісів, але з важливою відмінністю, що перенаправлення відбувається на рівні DNS, а не через проксі або пересилання.

Зовнішні IP-адреси

Трафік, який входить в кластер з зовнішнім IP-адресою (як IP-адреса призначення), на порт сервісу буде маршрутизований до одного з кінцевих точок сервісу. externalIPs не керуються Kubernetes і є відповідальністю адміністратора кластера.

У специфікації сервісу можна вказати externalIPs разом з будь-якими ServiceTypes. У наведеному нижче прикладі "my-service" може бути доступний для клієнтів за "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

На відміну від усіх вищезазначених прикладів, Ingress НЕ є типом сервісу. Замість цього, він знаходиться перед кількома сервісами і діє як "розумний маршрутизатор" або точка входу в ваш кластер.

Ви можете робити багато різних речей з Ingress, і існують багато типів контролерів Ingress з різними можливостями.

Контролер Ingress за замовчуванням GKE запустить HTTP(S) Load Balancer для вас. Це дозволить вам робити маршрутизацію на основі шляху та піддомену до бекенд сервісів. Наприклад, ви можете направити все на foo.yourdomain.com до сервісу foo, а все під шляхом yourdomain.com/bar/ до сервісу bar.

YAML для об'єкта Ingress на GKE з L7 HTTP Load Balancer може виглядати наступним чином:

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

Посилання

Вивчайте хакінг AWS від нуля до героя з htARTE (HackTricks AWS Red Team Expert)!

Інші способи підтримки HackTricks:

Last updated