Bumalik sa mga microservice kasama si Istio. Bahagi 3

Bumalik sa mga microservice kasama si Istio. Bahagi 3

Tandaan. transl.: Ang unang bahagi ang seryeng ito ay nakatuon sa pagkilala sa mga kakayahan ng Istio at pagpapakita ng mga ito sa pagkilos, pangalawa β€” pinong nakatutok na pagruruta at pamamahala ng trapiko sa network. Ngayon ay pag-uusapan natin ang tungkol sa seguridad: upang ipakita ang mga pangunahing pag-andar na nauugnay dito, ginagamit ng may-akda ang serbisyo ng pagkakakilanlan ng Auth0, ngunit ang iba pang mga provider ay maaaring i-configure sa katulad na paraan.

Nag-set up kami ng Kubernetes cluster kung saan kami nag-deploy ng Istio at isang halimbawang microservice application, Sentiment Analysis, para ipakita ang mga kakayahan ni Istio.

Sa Istio, nagawa naming panatilihing maliit ang aming mga serbisyo dahil hindi na nila kailangang magpatupad ng mga layer tulad ng Retries, Timeouts, Circuit Breakers, Tracing, Monitoring. . Bilang karagdagan, gumamit kami ng mga advanced na pagsubok at diskarte sa pag-deploy: A/B testing, mirroring at canary rollout.

Bumalik sa mga microservice kasama si Istio. Bahagi 3

Sa bagong materyal, haharapin natin ang mga huling layer sa landas patungo sa halaga ng negosyo: pagpapatunay at awtorisasyon - at sa Istio ito ay isang tunay na kasiyahan!

Authentication at authorization sa Istio

Hindi ako kailanman naniniwala na ako ay magiging inspirasyon ng pagpapatunay at awtorisasyon. Ano ang maiaalok ng Istio mula sa pananaw ng teknolohiya upang gawing masaya ang mga paksang ito at, higit pa, nagbibigay-inspirasyon para sa iyo?

Ang sagot ay simple: Inilipat ni Istio ang responsibilidad para sa mga kakayahan na ito mula sa iyong mga serbisyo patungo sa Envoy proxy. Sa oras na maabot ng mga kahilingan ang mga serbisyo, napatotohanan at pinahintulutan na ang mga ito, kaya ang kailangan mo lang gawin ay magsulat ng code na kapaki-pakinabang sa negosyo.

Mukhang maganda? Tingnan natin ang loob!

Pagpapatunay gamit ang Auth0

Bilang isang server para sa pamamahala ng pagkakakilanlan at pag-access, gagamitin namin ang Auth0, na may trial na bersyon, ay madaling gamitin at gusto ko lang ito. Gayunpaman, ang parehong mga prinsipyo ay maaaring ilapat sa anumang iba pa Mga pagpapatupad ng OpenID Connect: KeyCloak, IdentityServer at marami pang iba.

Upang makapagsimula, pumunta sa Auth0 Portal gamit ang iyong account, gumawa ng nangungupahan (nangungupahan - "nangungupahan", lohikal na yunit ng paghihiwalay, para sa higit pang mga detalye tingnan dokumentasyon β€” tinatayang. transl.) at pumunta sa Mga Application > Default na Apppumipili Domain, tulad ng ipinapakita sa screenshot sa ibaba:

Bumalik sa mga microservice kasama si Istio. Bahagi 3

Tukuyin ang domain na ito sa file resource-manifests/istio/security/auth-policy.yaml (pinagmulan):

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

Sa gayong mapagkukunan, Pilot (isa sa tatlong pangunahing bahagi ng Control Plane sa Istio - tinatayang transl.) Kino-configure ang Envoy upang patotohanan ang mga kahilingan bago ipasa ang mga ito sa mga serbisyo: sa-web-app ΠΈ sa-feedback. Kasabay nito, hindi inilalapat ang configuration sa mga Envoy ng serbisyo sa-frontend, na nagpapahintulot sa amin na iwanang hindi napatotohanan ang frontend. Upang ilapat ang Patakaran, patakbuhin ang command:

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

Bumalik sa pahina at gumawa ng isang kahilingan - makikita mo na nagtatapos ito sa katayuan 401 Di-awtorisadong. Ngayon, i-redirect natin ang mga frontend na user upang mag-authenticate gamit ang Auth0.

Pagpapatunay ng mga kahilingan sa Auth0

Para ma-authenticate ang mga kahilingan ng end user, kailangan mong gumawa ng API sa Auth0 na kakatawan sa mga na-authenticate na serbisyo (mga review, detalye, at rating). Para gumawa ng API, pumunta sa Auth0 Portal > Mga API > Gumawa ng API at punan ang form:

Bumalik sa mga microservice kasama si Istio. Bahagi 3

Ang mahalagang impormasyon dito ay identifier, na gagamitin namin mamaya sa script. Isulat natin ito tulad nito:

  • Audience: {YOUR_AUDIENCE}

Ang natitirang mga detalye na kailangan namin ay matatagpuan sa Auth0 Portal sa seksyon aplikasyon - pumili Pagsusulit na Aplikasyon (awtomatikong nilikha kasama ang API).

Dito tayo magsusulat:

  • Domain: {YOUR_DOMAIN}
  • ID ng kliyente: {YOUR_CLIENT_ID}

Mag-scroll sa Pagsusulit na Aplikasyon sa field ng text Pinapayagan ang mga URL ng Callback (mga nalutas na URL para sa callback), kung saan tinukoy namin ang URL kung saan dapat ipadala ang tawag pagkatapos makumpleto ang pagpapatunay. Sa aming kaso ito ay:

http://{EXTERNAL_IP}/callback

At para sa Pinapayagan ang mga URL ng Pag-logout (mga pinapayagang URL para sa pag-log out) idagdag:

http://{EXTERNAL_IP}/logout

Lumipat tayo sa frontend.

Update sa frontend

Lumipat sa sangay auth0 imbakan [istio-mastery]. Sa branch na ito, binago ang frontend code upang i-redirect ang mga user sa Auth0 para sa pagpapatunay at gamitin ang JWT token sa mga kahilingan sa iba pang mga serbisyo. Ang huli ay ipinatupad bilang mga sumusunod (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));
}

Para baguhin ang frontend para magamit ang data ng tenant sa Auth0, buksan sa-frontend/src/services/Auth.js at palitan dito ang mga halaga na isinulat namin sa itaas (Auth.js):

const Config = {
    clientID: '{YOUR_CLIENT_ID}',
    domain:'{YOUR_DOMAIN}',
    audience: '{YOUR_AUDIENCE}',
    ingressIP: '{EXTERNAL_IP}' // Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для Ρ€Π΅Π΄ΠΈΡ€Π΅ΠΊΡ‚Π° послС Π°ΡƒΡ‚Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΠΈ
}

Ang aplikasyon ay handa na. Tukuyin ang iyong Docker ID sa mga command sa ibaba kapag bumubuo at nagde-deploy ng mga pagbabagong ginawa:

$ 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

Subukan ang app! Ire-redirect ka sa Auth0, kung saan kailangan mong mag-log in (o magparehistro), pagkatapos nito ay ipapadala ka pabalik sa pahina kung saan gagawin ang mga na-authenticate na kahilingan. Kung susubukan mo ang mga utos na binanggit sa mga unang bahagi ng artikulo na may curl, makukuha mo ang code 401 Status Code, na nagpapahiwatig na ang kahilingan ay hindi awtorisado.

Gawin natin ang susunod na hakbang - pahintulutan ang mga kahilingan.

Awtorisasyon sa Auth0

Nagbibigay-daan sa amin ang pagpapatotoo na maunawaan kung sino ang isang user, ngunit kinakailangan ang pahintulot upang malaman kung ano ang mayroon sila ng access. Nag-aalok din ang Istio ng mga tool para dito.

Bilang halimbawa, gumawa tayo ng dalawang pangkat ng gumagamit (tingnan ang diagram sa ibaba):

  • Mga gumagamit (mga gumagamit) β€” na may access lamang sa mga serbisyo ng SA-WebApp at SA-Frontend;
  • Mga moderator (mga moderator) β€” na may access sa lahat ng tatlong serbisyo.

Bumalik sa mga microservice kasama si Istio. Bahagi 3
Konsepto ng awtorisasyon

Upang gawin ang mga pangkat na ito, gagamitin namin ang extension ng Auth0 Authorization at gagamitin namin ang Istio para bigyan sila ng iba't ibang antas ng access.

Pag-install at pagsasaayos ng Auth0 Authorization

Sa portal ng Auth0, pumunta sa mga extension (Extension) at i-install Awtorisasyon ng Auth0. Pagkatapos ng pag-install, pumunta sa Extension ng Awtorisasyon, at doon - sa configuration ng nangungupahan sa pamamagitan ng pag-click sa kanang tuktok at pagpili sa naaangkop na opsyon sa menu (Pag-configure). I-activate ang mga grupo (Mga Grupo) at mag-click sa publish rule button (I-publish ang panuntunan).

Bumalik sa mga microservice kasama si Istio. Bahagi 3

Lumikha ng mga pangkat

Sa Authorization Extension pumunta sa Grupo at gumawa ng grupo Mga Moderador. Dahil ituturing namin ang lahat ng na-authenticate na user bilang mga regular na user, hindi na kailangang gumawa ng karagdagang grupo para sa kanila.

Pumili ng grupo Mga Moderador, Pindutin Magdagdag ng mga Miyembro, idagdag ang iyong pangunahing account. Iwanan ang ilang user na walang anumang grupo upang matiyak na sila ay tinanggihan ng access. (Ang mga bagong user ay maaaring gawin nang manu-mano sa pamamagitan ng Auth0 Portal > Mga User > Gumawa ng User.)

Magdagdag ng Group Claim sa Access Token

Ang mga user ay naidagdag sa mga pangkat, ngunit ang impormasyong ito ay dapat ding ipakita sa mga token ng pag-access. Upang makasunod sa OpenID Connect at sa parehong oras ay ibalik ang mga grupo na kailangan namin, ang token ay kailangang magdagdag ng sarili nito pasadyang paghahabol. Ipinatupad sa pamamagitan ng mga panuntunan ng Auth0.

Upang gumawa ng panuntunan, pumunta sa Auth0 Portal sa Batas, Pindutin Lumikha ng Panuntunan at pumili ng walang laman na panuntunan mula sa mga template.

Bumalik sa mga microservice kasama si Istio. Bahagi 3

Kopyahin ang code sa ibaba at i-save ito bilang bagong panuntunan Magdagdag ng Group Claim (namespacedGroup.js):

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

Nota: Kinukuha ng code na ito ang unang pangkat ng user na tinukoy sa Extension ng Awtorisasyon at idinaragdag ito sa token ng pag-access bilang isang custom na claim (sa ilalim ng namespace nito, ayon sa kinakailangan ng Auth0).

Bumalik sa pahina Batas at tingnan kung mayroon kang dalawang panuntunang nakasulat sa sumusunod na pagkakasunud-sunod:

  • auth0-authorization-extension
  • Magdagdag ng Group Claim

Mahalaga ang pagkakasunud-sunod dahil natatanggap ng field ng pangkat ang panuntunan nang asynchronous auth0-authorization-extension at pagkatapos nito ay idinagdag ito bilang paghahabol ng pangalawang tuntunin. Ang resulta ay isang access token tulad nito:

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

Ngayon ay kailangan mong i-configure ang Envoy proxy upang suriin ang pag-access ng user, kung saan ang grupo ay kukunin mula sa paghahabol (https://sa.io/group) sa ibinalik na access token. Ito ang paksa para sa susunod na seksyon ng artikulo.

Configuration ng awtorisasyon sa Istio

Para gumana ang pahintulot, dapat mong paganahin ang RBAC para sa Istio. Upang gawin ito, gagamitin namin ang sumusunod na pagsasaayos:

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" 

Paliwanag:

  • 1 β€” paganahin ang RBAC para lamang sa mga serbisyo at namespace na nakalista sa field Inclusion;
  • 2 β€” naglilista kami ng listahan ng aming mga serbisyo.

Ilapat natin ang pagsasaayos gamit ang sumusunod na utos:

$ kubectl apply -f resource-manifests/istio/security/enable-rbac.yaml
rbacconfig.rbac.istio.io/default created

Ang lahat ng mga serbisyo ay nangangailangan na ngayon ng Role-Based Access Control. Sa madaling salita, ang pag-access sa lahat ng mga serbisyo ay ipinagbabawal at magreresulta sa isang tugon RBAC: access denied. Ngayon payagan natin ang access sa mga awtorisadong user.

I-access ang configuration para sa mga regular na user

Ang lahat ng mga gumagamit ay dapat magkaroon ng access sa mga serbisyo ng SA-Frontend at SA-WebApp. Ipinatupad gamit ang mga sumusunod na mapagkukunan ng Istio:

  • SerbisyoRole β€” tinutukoy ang mga karapatan na mayroon ang gumagamit;
  • ServiceRoleBinding β€” tinutukoy kung kanino kabilang ang ServiceRole na ito.

Para sa mga ordinaryong user, papayagan namin ang pag-access sa ilang partikular na serbisyo (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: ["*"]

At pagkatapos regular-user-binding ilapat ang ServiceRole sa lahat ng bisita ng page (regular-user-service-role-binding.yaml):

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
  name: regular-user-binding
  namespace: default
spec:
  subjects:
  - user: "*"
  roleRef:
    kind: ServiceRole
    name: "regular-user"

Nangangahulugan ba ang "lahat ng user" na magkakaroon din ng access sa SA WebApp ang mga hindi napatotohanang user? Hindi, susuriin ng patakaran ang validity ng JWT token.

Ilapat natin ang mga pagsasaayos:

$ 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

I-access ang configuration para sa mga moderator

Para sa mga moderator, gusto naming paganahin ang access sa lahat ng mga serbisyo (mod-service-role.yaml):

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

Ngunit gusto namin ang mga ganoong karapatan para lamang sa mga user na ang token ng access ay naglalaman ng claim https://sa.io/group may kahulugan 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" 

Ilapat natin ang mga pagsasaayos:

$ 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

Dahil sa pag-cache sa mga envoy, maaaring tumagal ng ilang minuto bago magkabisa ang mga panuntunan sa pagpapahintulot. Pagkatapos ay maaari mong tiyakin na ang mga user at moderator ay may iba't ibang antas ng pag-access.

Konklusyon sa bahaging ito

Pero seryoso, nakakita ka na ba ng mas simple, walang hirap, nasusukat at secure na diskarte sa pagpapatunay at awtorisasyon?

Tatlong mapagkukunan lamang ng Istio (RbacConfig, ServiceRole, at ServiceRoleBinding) ang kinakailangan upang makamit ang mahusay na kontrol sa pagpapatotoo at pagpapahintulot ng access ng end user sa mga serbisyo.

Bilang karagdagan, inalagaan namin ang mga isyung ito mula sa aming mga serbisyo ng envoy, na nakamit:

  • pagbabawas ng dami ng generic na code na maaaring naglalaman ng mga problema sa seguridad at mga bug;
  • pagbabawas ng bilang ng mga hangal na sitwasyon kung saan ang isang endpoint ay naging mapupuntahan mula sa labas at nakalimutang iulat ito;
  • pag-aalis ng pangangailangang i-update ang lahat ng serbisyo sa tuwing may idaragdag na bagong tungkulin o karapatan;
  • na ang mga bagong serbisyo ay mananatiling simple, secure at mabilis.

Pagbubuhos

Binibigyang-daan ng Istio ang mga team na ituon ang kanilang mga mapagkukunan sa mga gawaing kritikal sa negosyo nang hindi nagdaragdag ng overhead sa mga serbisyo, na ibinabalik ang mga ito sa micro status.

Ang artikulo (sa tatlong bahagi) ay nagbigay ng pangunahing kaalaman at handa na mga praktikal na tagubilin para sa pagsisimula sa Istio sa mga totoong proyekto.

PS mula sa tagasalin

Basahin din sa aming blog:

Pinagmulan: www.habr.com

Magdagdag ng komento