
Заўв. перав.: гэтага цыклу была прысвечана знаёмству з магчымасцямі Istio і іх дэманстрацыі ў дзеянні, - тонка наладжвальнай маршрутызацыі і кіраванню сеткавым трафікам. Цяпер жа гаворка пойдзе пра бяспеку: для дэманстрацыі злучаных з ёй базавых функцый аўтар выкарыстае identity-сэрвіс Auth0, аднак па аналогіі з ім могуць наладжвацца і іншыя правайдэры.
Мы наладзілі Kubernetes-кластар, у якім разгарнулі Istio і прыклад мікрасэрвіснага прыкладання Sentiment Analysis, – так былі прадэманстраваны магчымасці Istio.
З дапамогай Istio нам удалося захаваць невялікі памер сэрвісаў, паколькі яны не маюць патрэбы ў рэалізацыі такіх «пластоў», як паўторныя спробы падключэння (Retries), таймаўты (Timeouts), аўтаматычны выключальнікі (Circuit Breakers), трасіроўка (Tracing), маніторынг (Monitoring) . Акрамя таго, мы задзейнічалі тэхнікі прасунутага тэсціравання і дэплою: A / B-тэставанне, люстраванне і канарэечныя выкаты.

У новым матэрыяле мы разбярэмся з фінальнымі пластамі на шляху да business value: аўтэнтыфікацыяй і аўтарызацыяй - і ў Istio гэта суцэльнае задавальненне!
Аўтэнтыфікацыя і аўтарызацыя ў Istio
Ніколі б не паверыў, што натхнюся аўтэнтыфікацыяй і аўтарызацыяй. Што ж такога з тэхналагічнага пункта гледжання можа прапанаваць Istio для таго, каб зрабіць гэтыя тэмы займальнымі і нават больш за тое – каб яны натхнілі і вас?
Адказ просты: Istio пераносіць адказнасць за гэтыя магчымасці з вашых сэрвісаў на проксі Envoy. Да часу, калі запыты дасягаюць сэрвісаў, яны ўжо аўтэнтыфікаваны і аўтарызаваны, так што вам застаецца проста пісаць карысны для бізнэсу код.
Гучыць нядрэнна? Зазірнем жа ўнутр!
Аўтэнтыфікацыя з Auth0
У якасці сервера для кіравання ідэнтыфікацыяй і доступам будзем выкарыстоўваць Auth0, у якога ёсць выпрабавальная версія, які інтуітыўна зразумелы ў выкарыстанні і папросту падабаецца мне. Зрэшты, тыя ж самыя прынцыпы можна прымяніць і ў адносінах да любой іншай. : KeyCloak, IdentityServer і многім іншым.
Для пачатку зайдзіце на са сваім акаўнтам, стварыце tenant (tenant - «арандатар», лагічная адзінка ізаляцыі, падрабязней гл. у - заўв. перав.) і зайдзіце ў Applications > Default App, выбраўшы дамен, як паказана на скрыншоце ніжэй:

Выберыце гэты дамен у файле resource-manifests/istio/security/auth-policy.yaml ():
apiVersion: authentication.istio.io/v1alpha1
kind: Policy
metadata:
name: auth-policy
spec:
targets:
- name: sa-web-app
- name: sa-feedback
origins:
- jwt:
issuer: "https://{YOUR_DOMAIN}/"
jwksUri: "https://{YOUR_DOMAIN}/.well-known/jwks.json"
principalBinding: USE_ORIGIN Размяшчаючы такім рэсурсам, Pilot (адзін з трох базавых кампанентаў Control Plane у Istio — заўв. перакл.) настройвае Envoy'і на аўтэнтыфікацыю запытаў перад тым, як перанакіроўваць іх на сэрвісы: sa-web-app и sa-feedback. У той жа самы час канфігурацыя не прымяняецца да Envoy'ям сэрвісу sa-frontend, дазваляючы нам пакінуць фронтэнд неаўтэнтыфікаваным. Каб прымяніць палітыку (Policy), выканайце каманду:
$ kubectl apply -f resource-manifests/istio/security/auth-policy.yaml
policy.authentication.istio.io “auth-policy” createdКалі ласка, вярніцеся на старонку і зрабіце запыт - убачыце, што ён скончыцца статусам 401 Несанкцыянаванае. Зараз перанакіруем карыстальнікаў фронтэнда на аўтэнтыфікацыю з Auth0.
Аўтэнтыфікацыя запытаў з Auth0
Каб аўтэнтыфікаваць запыты канчатковага карыстальніка, неабходна стварыць API у Auth0, які будзе прадстаўляць аўтэнтыфікаваныя сэрвісы (reviews, details і ratings). Для стварэння API перайдзіце ў Auth0 Portal > APIs > Create API і запоўніце форму:

Важнай інфармацыяй тут з'яўляецца ідэнтыфікатар, які пазней мы будзем выкарыстоўваць у скрыпце. Выпішам яго сабе так:
- Аўдыторыя: {YOUR_AUDIENCE}
Пакінутыя патрэбныя нам дэталі размешчаны на Auth0 Portal у падзеле прыкладанняў - выберыце Тэставае прыкладанне (ствараецца аўтаматычна разам з API).
Тут мы запішам:
- дамен: {YOUR_DOMAIN}
- Ідэнтыфікатар кліента: {YOUR_CLIENT_ID}
Пракруціце ў Тэставае прыкладанне да тэкставага поля Allowed Callback URLs (дазволеныя URL'ы для callback'а), у якім мы пакажам URL, куды павінен адпраўляцца выклік пасля таго, як аўтэнтыфікацыя завершана. У нашым выпадку гэта:
http://{EXTERNAL_IP}/callbackА для Allowed Logout URLs (дазволеныя URL'ы для разлагінвання) дадамо:
http://{EXTERNAL_IP}/logoutПяройдзем да франтэнда.
Абнаўленне фронтэнда
Пераключыцеся на галінку auth0 рэпазітара [istio-mastery]. У гэтай галінцы код фронтэнда зменены так, каб перанакіроўваць карыстальнікаў у Auth0 для аўтэнтыфікацыі і выкарыстоўваць JWT-токен у запытах да астатніх сэрвісаў. Апошняе рэалізавана наступным чынам ():
analyzeSentence() {
fetch('/sentiment', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${auth.getAccessToken()}` // Access Token
},
body: JSON.stringify({ sentence: this.textField.getValue() })
})
.then(response => response.json())
.then(data => this.setState(data));
} Каб перавесці фронтэнд на выкарыстанне дадзеных tenant'а ў Auth0, адкрыйце sa-frontend/src/services/Auth.js і заменіце ў ім значэння, якія мы запісалі вышэй ():
const Config = {
clientID: '{YOUR_CLIENT_ID}',
domain:'{YOUR_DOMAIN}',
audience: '{YOUR_AUDIENCE}',
ingressIP: '{EXTERNAL_IP}' // Используется для редиректа после аутентификации
}Прыкладанне гатова. Пакажыце свой Docker ID у камандах ніжэй пры зборцы і дэплоі зробленых змен:
$ docker build -f sa-frontend/Dockerfile
-t $DOCKER_USER_ID/sentiment-analysis-frontend:istio-auth0
sa-frontend
$ docker push $DOCKER_USER_ID/sentiment-analysis-frontend:istio-auth0
$ kubectl set image deployment/sa-frontend
sa-frontend=$DOCKER_USER_ID/sentiment-analysis-frontend:istio-auth0Паспрабуйце дадатак! Вас перанакіруюць на Auth0, дзе неабходна залагініцца (ці зарэгістравацца), пасля чаго вас адправяць назад на старонку, з якой будуць рабіцца ўжо аўтэнтыфікаваныя запыты. Калі ж вы паспрабуеце згаданыя ў першых частках артыкула каманды з curl - атрымаеце код 401 Код стану, які сігналізуе аб тым, што запыт не аўтарызаваны.
Зробім наступны крок - аўтарызуем запыты.
Аўтарызацыя з Auth0
Аўтэнтыфікацыя дазваляе нам зразумець, кім з'яўляецца карыстач, але для таго, каб пазнаць, да чаго ў яго ёсць доступ, патрабуецца аўтарызацыя. Istio прапануе інструменты і для гэтага.
У якасці прыкладу створым дзве групы карыстальнікаў (гл. на схеме ніжэй):
- Карыстальнікі (users) - з доступам толькі да сэрвісаў SA-WebApp і SA-Frontend;
- Мадэратары (moderators) - з доступам да ўсіх трох сэрвісаў.

Канцэпцыя аўтарызацыі
Для стварэння гэтых груп скарыстаемся пашырэннем Auth0 Authorization і з дапамогай Istio дамо ім розныя ўзроўні доступу.
Ўстаноўка і канфігурацыя Auth0 Authorization
На партале Auth0 перайдзіце да пашырэнняў (Пашырэння) і ўсталюйце Auth0 Authorization. Пасля ўстаноўкі перайдзіце да Authorization Extension, а там - да канфігурацыі tenant'а па кліку справа наверсе і выбару адпаведнай опцыі меню (Канфігурацыя). Актывуйце групы (Групы) і націсніце на кнопку публікацыі правілы (Publish rule).

Стварэнне груп
У Authorization Extension перайдзіце ў груп і стварыце групу мадэратары. Паколькі мы будзем разглядаць усіх аўтэнтыфікаваных карыстальнікаў як звычайных, патрэбнасці ў стварэнні для іх дадатковай групы няма.
Абярыце групу мадэратары, націсніце на Дадаць удзельнікаў, дадайце свой асноўны рахунак. Пакіньце некаторых карыстальнікаў без якой-небудзь групы, каб пераканацца, што доступ для іх забаронены. (Новых карыстальнікаў можна стварыць уручную праз Auth0 Portal > Users > Create User.)
Дадайце Group Claim у Access Token
Карыстальнікі дададзены ў групы, аднак гэтая інфармацыя павінна быць адлюстравана і ў токена для доступу. Каб адпавядаць OpenID Connect і ў той жа час вяртаць групы, якія нам патрэбныя, токену спатрэбіцца дадаваць свой . Рэалізуецца праз правілы Auth0.
Для стварэння правіла перайдзіце на Auth0 Portal да Правілы, націсніце на Стварыць правіла і абярыце пустое правіла з шаблонаў.

Скапіюйце код ніжэй і захавайце яго як новае правіла Add Group Claim ():
function (user, context, callback) {
context.accessToken['https://sa.io/group'] = user.groups[0];
return callback(null, user, context);
}Заўвага: гэты код бярэ першую групу карыстальніка, вызначаную ў Authorization Extension, і дадае яе ў access-токен як custom claim (пад сваёй прасторай імёнаў, як таго патрабуе Auth0).
Калі ласка, вярніцеся да старонкі Правілы і праверце, што ў вас ёсць два правілы, запісаныя ў наступным парадку:
- auth0-authorization-extension
- Add Group Claim
Парадак важны, таму што поле групы асінхронна атрымлівае правіла. auth0-authorization-extension і пасля гэтага дадаецца як claim другім правілам. У выніку атрымліваецца такі access-токен:
{
"https://sa.io/group": "Moderators",
"iss": "https://sentiment-analysis.eu.auth0.com/",
"sub": "google-oauth2|196405271625531691872"
// [сокращено для наглядности]
} Зараз неабходна наладзіць Envoy-проксі на праверку карыстацкага доступу, для чаго гурт будзе выцягвацца з claim (https://sa.io/group) ва які вяртаецца access-токене. Гэта тэма для наступнага раздзела артыкула.
Канфігурацыя аўтарызацыі ў Istio
Каб аўтарызацыя пачала працаваць, неабходна ўключыць RBAC для Istio. Для гэтага скарыстаемся наступнай канфігурацыяй:
apiVersion: "rbac.istio.io/v1alpha1"
kind: RbacConfig
metadata:
name: default
spec:
mode: 'ON_WITH_INCLUSION' # 1
inclusion:
services: # 2
- "sa-frontend.default.svc.cluster.local"
- "sa-web-app.default.svc.cluster.local"
- "sa-feedback.default.svc.cluster.local" Тлумачэнні:
- 1 — уключаем RBAC толькі для сэрвісаў і прастор імёнаў, пералічаных у поле
Inclusion; - 2 - пералічваем спіс нашых сэрвісаў.
Ужыем канфігурацыю такой камандай:
$ kubectl apply -f resource-manifests/istio/security/enable-rbac.yaml
rbacconfig.rbac.istio.io/default created Цяпер усе сэрвісы патрабуюць кіравання доступам на аснове роляў (Role-Based Access Control). Іншымі словамі, доступ да ўсіх сэрвісаў забаронены і прывядзе да адказу. RBAC: access denied. Цяпер дазволім доступ аўтарызаваным карыстальнікам.
Канфігурацыя доступу для звычайных карыстальнікаў
Усе карыстачы павінны мець доступ да сэрвісаў SA-Frontend і SA-WebApp. Рэалізуецца з дапамогай наступных рэсурсаў Istio:
- ServiceRole - вызначае правы, якія ёсць у карыстальніка;
- ServiceRoleBinding - Вызначае, да каго гэтая ServiceRole ставіцца.
Для звычайных карыстальнікаў дазволім доступ да пэўных сэрвісаў ():
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
name: regular-user
namespace: default
spec:
rules:
- services:
- "sa-frontend.default.svc.cluster.local"
- "sa-web-app.default.svc.cluster.local"
paths: ["*"]
methods: ["*"] А праз regular-user-binding ужывальны ServiceRole да ўсіх наведвальнікаў старонкі ():
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
name: regular-user-binding
namespace: default
spec:
subjects:
- user: "*"
roleRef:
kind: ServiceRole
name: "regular-user"Ці азначае "ўсе карыстальнікі", што і неаўтэнтыфікаваныя карыстальнікі атрымаюць доступ да SA WebApp? Не, палітыка праверыць валіднасць JWT-токена.
Ужывальны канфігурацыі:
$ kubectl apply -f resource-manifests/istio/security/user-role.yaml
servicerole.rbac.istio.io/regular-user created
servicerolebinding.rbac.istio.io/regular-user-binding createdКанфігурацыя доступу для мадэратараў
Для мадэратараў мы жадаем уключыць доступ да ўсіх сэрвісаў ():
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
name: mod-user
namespace: default
spec:
rules:
- services: ["*"]
paths: ["*"]
methods: ["*"] Але мы жадаем такіх мае рацыю толькі для тых карыстачоў, у access-токене якіх ёсць claim https://sa.io/group са значэннем Moderators ():
apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
name: mod-user-binding
namespace: default
spec:
subjects:
- properties:
request.auth.claims[https://sa.io/group]: "Moderators"
roleRef:
kind: ServiceRole
name: "mod-user" Ужывальны канфігурацыі:
$ kubectl apply -f resource-manifests/istio/security/mod-role.yaml
servicerole.rbac.istio.io/mod-user created
servicerolebinding.rbac.istio.io/mod-user-binding createdЗ-за кэшавання ў envoy'ях для ўступлення правіл аўтарызацыі ў сілу можа запатрабавацца пару мінуць. Пасля гэтага вы зможаце пераканацца, што ў карыстачоў і мадэратараў розныя ўзроўні доступу.
Заключэнне па гэтай частцы
Ну вось сур'ёзна: вы дзе-небудзь бачылі прасцейшы, не патрабавальны высілкаў, які маштабуецца і бяспечны падыход да аўтэнтыфікацыі і аўтарызацыі?
Усяго толькі тры рэсурсы Istio (RbacConfig, ServiceRole, and ServiceRoleBinding) запатрабаваліся для таго, каб дамагчыся тонкага кантролю над аўтэнтыфікацыяй і аўтарызацыяй доступу канчатковых карыстачоў да сэрвісаў.
У дадатак, мы вынеслі клопат аб гэтых праблемах з нашых сэрвісаў у envoy'і, дамогшыся:
- памяншэнні колькасці тыпавога кода, у якім могуць апынуцца праблемы бяспекі і багі;
- зніжэння колькасці дурных сітуацый, у якіх адзін endpoint аказаўся даступным звонку і забыўся паведаміць пра гэта;
- устаранення неабходнасці ў абнаўленні ўсіх сэрвісаў пры кожным даданні новай ролі або права;
- таго, што новыя сервісы застаюцца простымі, бяспечнымі і хуткімі.
Выснова
Istio дазваляе камандам сфакусаваць свае рэсурсы на важных для бізнэсу задачах, не дадаючы накладныя выдаткі сэрвісам, вяртаючы іх да статуту "мікра".
Артыкул (у трох частках) падала базавыя веды і гатовую практычную інструкцыю для пачатку працы з Istio у рэальных праектах.
PS ад перакладчыка
Чытайце таксама ў нашым блогу:
- «Назад да мікрасэрвісаў разам з Istio»: , ;
- «»;
- «.
Крыніца: habr.com
