Контроль доступу на вході
Це завдання показує, як застосувати контроль доступу на основі IP до вхідного шлюзу Istio за допомогою політики авторизації.
Перед початком
Перед початком цього завдання зробіть наступне:
Ознайомтеся з концепціями авторизації Istio.
Встановіть Istio за допомогою посібника з установки Istio.
Розгорніть навантаження,
httpbin
, у просторі іменfoo
з увімкненою інʼєкцією sidecar:$ kubectl create ns foo $ kubectl label namespace foo istio-injection=enabled $ kubectl apply -f @samples/httpbin/httpbin.yaml@ -n foo
Експонуйте
httpbin
через вхідний шлюз:
Перевірте, що навантаження
httpbin
і вхідний шлюз працюють як очікувалося, за допомогою цієї команди:$ curl "$INGRESS_HOST:$INGRESS_PORT"/headers -s -o /dev/null -w "%{http_code}\n" 200
Отримання трафіку в Kubernetes та Istio
Усі методи отримання трафіку в Kubernetes передбачають відкриття порту на всіх робочих вузлах. Основні елементи, які це забезпечують, — це сервіси NodePort
та LoadBalancer
. Навіть ресурс Kubernetes Ingress
повинен бути підкріплений контролером Ingress, який створить або сервіс NodePort
, або сервіс LoadBalancer
.
NodePort
просто відкриває порт у діапазоні 30000-32767 на кожному робочому вузлі та використовує селектор міток для ідентифікації того, яким Podʼам надсилати трафік. Вам потрібно вручну створити якийсь тип балансувальника навантаження перед вашими робочими вузлами або використовувати Round-Robin DNS.LoadBalancer
подібний доNodePort
, але також створює специфічний для середовища зовнішній балансувальник навантаження для розподілу трафіку між робочими вузлами. Наприклад, у AWS EKS службаLoadBalancer
створить Classic ELB з вашими робочими вузлами як цільовими. Якщо ваше середовище Kubernetes не має реалізаціїLoadBalancer
, то воно просто поводитиметься якNodePort
. Вхідний шлюз Istio створює сервісLoadBalancer
.
Що робити, якщо Pod, який обробляє трафік з NodePort
або LoadBalancer
, не працює на робочому вузлі, який отримав трафік? Kubernetes має власний внутрішній проксі kube-proxy, який отримує пакети та пересилає їх на правильний вузол.
IP-адреса оригінального клієнта
Якщо пакет проходить через зовнішній проксі балансувальник навантаження і/або kube-proxy, то оригінальна IP-адреса клієнта втрачається. Нижченаведені підрозділи описують деякі стратегії збереження оригінальної IP-адреси клієнта для ведення журналу або для безпеки для різних типів балансувальників навантаження:
- TCP/UDP проксі балансувальник навантаження
- Мережевий балансувальник навантаження
- HTTP/HTTPS балансувальник навантаження
Для довідки наведено типи балансувальників навантаження, які створює Istio з сервісом LoadBalancer
у популярних середовищах Kubernetes, що надаються провадерами послуг:
Хмарний провайдер | Назва балансувальника навантаження | Тип балансувальника навантаження |
---|---|---|
AWS EKS | Classic Elastic Load Balancer | TCP Proxy |
GCP GKE | TCP/UDP Network Load Balancer | Network |
Azure AKS | Azure Load Balancer | Network |
IBM IKS/ROKS | Network Load Balancer | Network |
DO DOKS | Load Balancer | Network |
TCP/UDP проксі балансувальник навантаження
Якщо ви використовуєте зовнішній балансувальник навантаження TCP/UDP (AWS Classic ELB), він може використовувати PROXY Protocol для вбудовування оригінальної IP-адреси клієнта в дані пакета. Для того щоб це працювало, як зовнішній балансувальник навантаження, так і вхідний шлюз Istio повинні підтримувати PROXY протокол.
Ось приклад конфігурації, який показує, як налаштувати вхідний шлюз на AWS EKS для підтримки PROXY Protocol:
Мережевий балансувальник навантаження
Якщо ви використовуєте мережевий балансувальник навантаження TCP/UDP, який зберігає IP-адресу клієнта (AWS Network Load Balancer, GCP External Network Load Balancer, Azure Load Balancer) або використовуєте Round-Robin DNS, ви можете використовувати параметр externalTrafficPolicy: Local
, щоб також зберегти IP-адресу клієнта всередині Kubernetes, обходячи kube-proxy і запобігаючи надсиланню трафіку на інші вузли.
Оновіть вхідний шлюз, щоб встановити externalTrafficPolicy: Local
, щоб зберегти
оригінальну IP-адресу джерела клієнта на вхідному шлюзі, використовуючи наступну команду:
HTTP/HTTPS балансувальник навантаження
Якщо ви використовуєте зовнішній балансувальник навантаження HTTP/HTTPS (AWS ALB, GCP), він може вставити оригінальну IP-адресу клієнта в заголовок X-Forwarded-For. Istio може витягти IP-адресу клієнта з цього заголовка за допомогою певної конфігурації. Дивіться Налаштування топології мережі шлюзу. Швидкий приклад, якщо використовується один балансувальник навантаження перед Kubernetes:
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
meshConfig:
accessLogEncoding: JSON
accessLogFile: /dev/stdout
defaultConfig:
gatewayTopology:
numTrustedProxies: 1
Список дозволених та заборонених IP-адрес
Коли використовувати ipBlocks
або remoteIpBlocks
: Якщо ви використовуєте заголовок X-Forwarded-For HTTP або PROXY Protocol для визначення оригінальної IP-адреси клієнта, тоді слід використовувати remoteIpBlocks
у вашій AuthorizationPolicy
. Якщо ви використовуєте externalTrafficPolicy: Local
, тоді слід використовувати ipBlocks
у вашій AuthorizationPolicy
.
Тип балансувальника навантаження | Джерело IP-адреси клієнта | ipBlocks проти remoteIpBlocks |
---|---|---|
TCP Proxy | PROXY Protocol | remoteIpBlocks |
Мережевий | адреса джерела пакета | ipBlocks |
HTTP/HTTPS | X-Forwarded-For | remoteIpBlocks |
- Наступна команда створює політику авторизації
ingress-policy
для вхідного шлюзу Istio. Ця політика встановлює полеaction
наALLOW
, щоб дозволити IP-адреси, вказані вipBlocks
, доступ до вхідного шлюзу. IP-адреси, яких немає в списку, будуть заблоковані.ipBlocks
підтримує як окремі IP-адреси, так і CIDR-нотацію.
Переконайтеся, що запит до вхідного шлюзу відхилено:
$ curl "$INGRESS_HOST:$INGRESS_PORT"/headers -s -o /dev/null -w "%{http_code}\n" 403
Призначте IP-адресу вашого клієнта змінній env. Якщо ви її не знаєте, ви можете знайти її в журналах Envoy за допомогою наступної команди:
- Оновіть
ingress-policy
, щоб додати IP-адресу вашого клієнта:
Переконайтеся, що запит до вхідного шлюзу дозволено:
$ curl "$INGRESS_HOST:$INGRESS_PORT"/headers -s -o /dev/null -w "%{http_code}\n" 200
Оновіть політику авторизації
ingress-policy
, встановивши ключaction
у значенняDENY
, щоб IP-адреси, вказані вipBlocks
, не мали доступу до вхідного шлюзу:
Переконайтеся, що запит до вхідного шлюзу відхилено:
$ curl "$INGRESS_HOST:$INGRESS_PORT"/headers -s -o /dev/null -w "%{http_code}\n" 403
Ви можете скористатися онлайн-проксі-сервісом для доступу до вхідного шлюзу з іншої клієнтської IP-адреси, щоб переконатися, що запит дозволено.
Якщо ви не отримуєте очікуваних відповідей, перегляньте журнали вхідного шлюзу, які повинні містити інформацію про налагодження RBAC:
Очищення
- Видаліть політику авторизації:
Видалити простір імен
foo
:$ kubectl delete namespace foo