Обратно към микроуслугите с Istio. Част 3

Обратно към микроуслугите с Istio. Част 3

Забележка. превод: Първата част тази серия беше посветена на опознаването на възможностите на Istio и демонстрирането им в действие, втори — фино настроено маршрутизиране и управление на мрежовия трафик. Сега ще говорим за сигурността: за да демонстрира основните функции, свързани с нея, авторът използва услугата за самоличност Auth0, но други доставчици могат да бъдат конфигурирани по подобен начин.

Създадохме клъстер Kubernetes, в който внедрихме Istio и примерно приложение за микросервизи, Sentiment Analysis, за да демонстрираме възможностите на Istio.

С Istio успяхме да запазим нашите услуги малки, защото те не се нуждаят от прилагане на слоеве като повторни опити, изчакване, прекъсвачи, проследяване, наблюдение. Освен това използвахме усъвършенствани техники за тестване и внедряване: A/B тестване, дублиране и внедряване на Canary.

Обратно към микроуслугите с Istio. Част 3

В новия материал ще се занимаваме с последните слоеве по пътя към бизнес стойността: удостоверяване и оторизация – а в Istio това е истинско удоволствие!

Удостоверяване и оторизация в Istio

Никога не бих повярвал, че ще се вдъхновя от удостоверяване и оторизация. Какво може да предложи Istio от гледна точка на технологиите, за да направи тези теми забавни и още повече вдъхновяващи за вас?

Отговорът е прост: Istio прехвърля отговорността за тези възможности от вашите услуги към проксито Envoy. Докато заявките достигнат до услугите, те вече са били удостоверени и оторизирани, така че всичко, което трябва да направите, е да напишете полезен за бизнеса код.

Звучи добре? Да надникнем вътре!

Удостоверяване с Auth0

Като сървър за управление на идентичността и достъпа ще използваме Auth0, който има пробна версия, интуитивен е за използване и просто ми харесва. Същите принципи обаче могат да се приложат към всеки друг Реализации на OpenID Connect: KeyCloak, IdentityServer и много други.

За да започнете, отидете на Портал Auth0 с вашия акаунт създайте наемател (наемател - „наемател“, логическа единица на изолация, за повече подробности вижте документация - прибл. превод) и отидете на Приложения > Приложение по подразбиранеизбор домейн, както е показано на екранната снимка по-долу:

Обратно към микроуслугите с Istio. Част 3

Посочете този домейн във файла 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

С такъв ресурс, Пилот (един от трите основни компонента на Control Plane в Istio - прибл. превод) конфигурира Envoy да удостоверява заявките, преди да ги препрати към услуги: sa-web-app и sa-feedback. В същото време конфигурацията не се прилага към услугата Envoys sa-frontend, което ни позволява да оставим интерфейса неавтентифициран. За да приложите правилата, изпълнете командата:

$ kubectl apply -f resource-manifests/istio/security/auth-policy.yaml
policy.authentication.istio.io “auth-policy” created

Върнете се на страницата и направете заявка - ще видите, че завършва със статуса 401 Неразрешено. Сега нека пренасочим потребителите на предния край към удостоверяване с Auth0.

Удостоверяване на заявки с Auth0

За да удостоверите заявките за крайни потребители, трябва да създадете API в Auth0, който ще представлява удостоверените услуги (отзиви, подробности и оценки). За да създадете API, отидете на Портал Auth0 > API > Създаване на API и попълнете формата:

Обратно към микроуслугите с Istio. Част 3

Важната информация тук е Identifier, който ще използваме по-късно в скрипта. Нека го запишем така:

  • Публика: {ВАШАТА_АУДИТОРИЯ}

Останалите подробности, от които се нуждаем, се намират на портала Auth0 в раздела Приложения - изберете Тестово приложение (създаден автоматично заедно с API).

Тук ще напишем:

  • домейн: {ВАШИЯ_ДОМЕЙН}
  • Идент. № на клиента: {YOUR_CLIENT_ID}

Превъртете до Тестово приложение към текстово поле Разрешени URL адреси за обратно извикване (разрешени URL адреси за обратното извикване), в които посочваме URL адреса, на който да бъде изпратено повикването след завършване на удостоверяването. В нашия случай това е:

http://{EXTERNAL_IP}/callback

И за Разрешени URL адреси за излизане (разрешени URL адреси за излизане) добави:

http://{EXTERNAL_IP}/logout

Да преминем към интерфейса.

Актуализация на предния край

Преминете към клон auth0 хранилище [istio-mastery]. В този клон кодът на интерфейса е променен, за да пренасочва потребителите към Auth0 за удостоверяване и да използва JWT токена в заявки към други услуги. Последният се реализира по следния начин (App.js):

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));
}

За да промените интерфейса за използване на данни на клиента в Auth0, отворете sa-frontend/src/services/Auth.js и заменете в него стойностите, които написахме по-горе (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 предлага инструменти и за това.

Като пример, нека създадем две потребителски групи (вижте диаграмата по-долу):

  • Потребители (потребители) — с достъп само до услугите SA-WebApp и SA-Frontend;
  • Модератори (модератори) — с достъп до трите услуги.

Обратно към микроуслугите с Istio. Част 3
Концепция за оторизация

За да създадем тези групи, ще използваме разширението Auth0 Authorization и Istio, за да им предоставим различни нива на достъп.

Инсталиране и конфигуриране на Auth0 Authorization

В портала Auth0 отидете на разширения (Разширения) и инсталирайте Auth0 Упълномощаване. След инсталирането отидете на Удължаване на разрешението, а там - към конфигурацията на наемателя, като щракнете горе вдясно и изберете съответната опция от менюто (Конфигурация). Активиране на групи (Групи) и щракнете върху бутона за публикуване на правило (Правило за публикуване).

Обратно към микроуслугите с Istio. Част 3

Създавайте групи

В Разширение за разрешение отидете на Групи и създайте група Модератори. Тъй като ще третираме всички удостоверени потребители като обикновени потребители, няма нужда да създаваме допълнителна група за тях.

Изберете група Модератори, Натиснете Добавяне на членове, добавете основния си акаунт. Оставете някои потребители без група, за да сте сигурни, че им е отказан достъп. (Нови потребители могат да бъдат създадени ръчно чрез Портал Auth0 > Потребители > Създаване на потребител.)

Добавете групово искане към маркер за достъп

Потребителите са добавени към групи, но тази информация трябва да бъде отразена и в маркерите за достъп. За да отговаря на OpenID Connect и в същото време да върне нужните ни групи, токенът ще трябва да добави свой собствен иск по поръчка. Внедрено чрез правила Auth0.

За да създадете правило, отидете на Auth0 Portal към Правилник, Натиснете Създаване на правило и изберете празно правило от шаблоните.

Обратно към микроуслугите с Istio. Част 3

Копирайте кода по-долу и го запазете като ново правило Добавете групово искане (namespacedGroup.js):

function (user, context, callback) {
    context.accessToken['https://sa.io/group'] = user.groups[0];
    return callback(null, user, context);
}

Внимание: Този код взема първата потребителска група, дефинирана в Разширението за оторизация, и я добавя към маркера за достъп като персонализирана претенция (под нейното пространство от имена, както се изисква от Auth0).

Върнете се към страницата Правилник и проверете дали имате две правила, написани в следния ред:

  • auth0-упълномощаване-разширение
  • Добавете групово искане

Редът е важен, защото груповото поле получава правилото асинхронно auth0-упълномощаване-разширение и след това се добавя като претенция от второто правило. Резултатът е токен за достъп като този:

{
 "https://sa.io/group": "Moderators",
 "iss": "https://sentiment-analysis.eu.auth0.com/",
 "sub": "google-oauth2|196405271625531691872"
 // [сокращено для наглядности]
}

Сега трябва да конфигурирате проксито на Envoy за проверка на достъпа на потребителите, за което групата ще бъде изтеглена от заявка (https://sa.io/group) в върнатия маркер за достъп. Това е темата за следващия раздел на статията.

Конфигуриране на оторизация в 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

Всички услуги вече изискват контрол на достъпа, базиран на роли. С други думи, достъпът до всички услуги е забранен и ще доведе до отговор RBAC: access denied. Сега нека разрешим достъп на оторизирани потребители.

Конфигурация на достъп за редовни потребители

Всички потребители трябва да имат достъп до услугите SA-Frontend и SA-WebApp. Внедрено с помощта на следните ресурси на Istio:

  • ServiceRole — определя правата, които има потребителят;
  • ServiceRoleBinding — определя на кого принадлежи тази ServiceRole.

За обикновените потребители ще разрешим достъп до определени услуги (servicerole.yaml):

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 към всички посетители на страницата (регулярна-потребителска-услуга-роля-обвързване.yaml):

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

Конфигурация на достъп за модератори

За модераторите искаме да разрешим достъп до всички услуги (mod-service-role.yaml):

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
  name: mod-user
  namespace: default
spec:
  rules:
  - services: ["*"]
    paths: ["*"]
    methods: ["*"]

Но искаме такива права само за тези потребители, чийто маркер за достъп съдържа претенция https://sa.io/group със стойност Moderators (mod-service-role-binding.yaml):

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

Поради кеширане на пратеници може да отнеме няколко минути, докато правилата за оторизация влязат в сила. След това можете да гарантирате, че потребителите и модераторите имат различни нива на достъп.

Заключение по тази част

Сериозно обаче, виждали ли сте някога по-прост, лесен, мащабируем и сигурен подход за удостоверяване и оторизация?

Само три ресурса на Istio (RbacConfig, ServiceRole и ServiceRoleBinding) бяха необходими за постигане на фин контрол върху удостоверяването и оторизацията на достъпа на крайния потребител до услугите.

В допълнение, ние се погрижихме за тези проблеми извън нашите служби за пратеници, постигайки:

  • намаляване на количеството общ код, който може да съдържа проблеми със сигурността и грешки;
  • намаляване на броя на глупавите ситуации, в които една крайна точка се оказва достъпна отвън и забравяме да я докладваме;
  • елиминиране на необходимостта от актуализиране на всички услуги всеки път, когато се добави нова роля или право;
  • че новите услуги остават прости, сигурни и бързи.

Продукция

Istio позволява на екипите да съсредоточат ресурсите си върху критични за бизнеса задачи, без да добавят допълнителни разходи към услугите, връщайки ги към микро статус.

Статията (в три части) предостави основни знания и готови практически инструкции за започване на работа с Istio в реални проекти.

PS от преводача

Прочетете също в нашия блог:

Източник: www.habr.com

Добавяне на нов коментар