Torna als microserveis amb Istio. Part 3

Torna als microserveis amb Istio. Part 3

Nota. transl.: Primera part aquesta sèrie es va dedicar a conèixer les capacitats d'Istio i demostrar-les en acció, segon — Encaminament ajustat i gestió del trànsit de xarxa. Ara parlarem de seguretat: per demostrar les funcions bàsiques relacionades amb ella, l'autor utilitza el servei d'identitat Auth0, però altres proveïdors es poden configurar de manera similar.

Hem configurat un clúster de Kubernetes en el qual hem desplegat Istio i una aplicació de microservei d'exemple, Sentiment Analysis, per demostrar les capacitats d'Istio.

Amb Istio, hem pogut mantenir els nostres serveis petits perquè no necessiten implementar capes com ara Reintents, Temps d'espera, Interruptors, Seguiment, Monitorització. A més, hem utilitzat tècniques de prova i desplegament avançades: proves A/B, duplicació i llançaments canaris.

Torna als microserveis amb Istio. Part 3

En el nou material, tractarem les capes finals del camí cap al valor empresarial: autenticació i autorització, i a Istio és un autèntic plaer!

Autenticació i autorització a Istio

Mai hauria cregut que m'inspiraria l'autenticació i l'autorització. Què pot oferir Istio des d'una perspectiva tecnològica perquè aquests temes siguin divertits i, encara més, inspiradors per a tu?

La resposta és senzilla: Istio transfereix la responsabilitat d'aquestes capacitats dels vostres serveis al servidor intermediari d'Envoy. Quan les sol·licituds arriben als serveis, ja s'han autenticat i autoritzat, de manera que només cal escriure codi útil per a l'empresa.

Sona bé? Fem una ullada a dins!

Autenticació amb Auth0

Com a servidor per a la gestió d'identitats i accessos, farem servir Auth0, que té una versió de prova, és intuïtiu d'utilitzar i simplement m'agrada. Tanmateix, els mateixos principis es poden aplicar a qualsevol altre Implementacions d'OpenID Connect: KeyCloak, IdentityServer i molts altres.

Per començar, aneu a Auth0 Portal amb el vostre compte, creeu un inquilí (inquilí - "inquilí", unitat lògica d'aïllament, per a més detalls vegeu documentació -aprox. trad.) i vés a Aplicacions > Aplicació predeterminadamitjançant la selecció domini, tal com es mostra a la captura de pantalla següent:

Torna als microserveis amb Istio. Part 3

Especifiqueu aquest domini al fitxer resource-manifests/istio/security/auth-policy.yaml (font):

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

Amb aquest recurs, Pilot (un dels tres components bàsics del pla de control a Istio - aprox. traducció) configura Envoy per autenticar les sol·licituds abans de reenviar-les als serveis: sa-web-app и sa-feedback. Al mateix temps, la configuració no s'aplica als enviats de servei sa-frontend, que ens permet deixar la interfície sense autenticar. Per aplicar la política, executeu l'ordre:

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

Torneu a la pàgina i feu una sol·licitud: veureu que acaba amb l'estat 401 no autoritzat. Ara anem a redirigir els usuaris de frontend perquè s'autentiquin amb Auth0.

Autenticació de sol·licituds amb Auth0

Per autenticar les sol·licituds dels usuaris finals, heu de crear una API a Auth0 que representi els serveis autenticats (ressenyes, detalls i puntuacions). Per crear una API, aneu a Auth0 Portal > API > Crea API i omple el formulari:

Torna als microserveis amb Istio. Part 3

La informació important aquí és identificador, que utilitzarem més endavant en el guió. Escrivim-ho així:

  • Audiència: {YOUR_AUDIENCE}

La resta de detalls que necessitem es troben al Portal Auth0 de la secció Aplicacions — seleccionar Aplicació de prova (creat automàticament juntament amb l'API).

Aquí escriurem:

  • domini: {YOUR_DOMAIN}
  • Id. del client: {YOUR_CLIENT_ID}

Desplaça't fins a Aplicació de prova al camp de text URL de retorn de trucada permesos (URL resolts per a la devolució de trucada), en què especifiquem l'URL on s'ha d'enviar la trucada un cop finalitzada l'autenticació. En el nostre cas és:

http://{EXTERNAL_IP}/callback

I per a URL de tancament de sessió permesos (URL permesos per tancar la sessió) afegiu:

http://{EXTERNAL_IP}/logout

Passem a la interfície.

Actualització de front-end

Canvia a la branca auth0 repositori [istio-mastery]. En aquesta branca, es canvia el codi d'interfície per redirigir els usuaris a Auth0 per a l'autenticació i utilitzar el testimoni JWT en sol·licituds a altres serveis. Aquest últim s'implementa de la següent manera (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));
}

Per canviar la interfície per utilitzar les dades de l'inquilí a Auth0, obriu sa-frontend/src/services/Auth.js i substituïu-hi els valors que hem escrit més amunt (Auth.js):

const Config = {
    clientID: '{YOUR_CLIENT_ID}',
    domain:'{YOUR_DOMAIN}',
    audience: '{YOUR_AUDIENCE}',
    ingressIP: '{EXTERNAL_IP}' // Используется для редиректа после аутентификации
}

L'aplicació està llesta. Especifiqueu el vostre ID de Docker a les ordres següents quan creeu i implementeu els canvis realitzats:

$ 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

Prova l'aplicació! Se us redirigirà a Auth0, on haureu d'iniciar sessió (o registrar-vos), després de la qual cosa se us enviarà de nou a la pàgina des de la qual es faran les sol·licituds ja autenticades. Si proveu les ordres esmentades a les primeres parts de l'article amb curl, obtindreu el codi Codi d'estat 401, indicant que la sol·licitud no està autoritzada.

Fem el següent pas: autoritzar les sol·licituds.

Autorització amb Auth0

L'autenticació ens permet entendre qui és un usuari, però cal autorització per saber a què té accés. Istio també ofereix eines per a això.

Com a exemple, creem dos grups d'usuaris (vegeu el diagrama següent):

  • Membres (usuaris) — amb accés només als serveis SA-WebApp i SA-Frontend;
  • Moderadors (moderadors) — amb accés als tres serveis.

Torna als microserveis amb Istio. Part 3
Concepte d'autorització

Per crear aquests grups, utilitzarem l'extensió Auth0 Authorization i utilitzarem Istio per oferir-los diferents nivells d'accés.

Instal·lació i configuració de l'Autorització Auth0

Al portal Auth0, aneu a extensions (Extensions) i instal·lar Autorització Auth0. Després de la instal·lació, aneu a Extensió d'autorització, i allà - a la configuració del llogater fent clic a la part superior dreta i seleccionant l'opció de menú corresponent (Configuració). Activar grups (Grups) i feu clic al botó de publicació de la regla (Regla de publicació).

Torna als microserveis amb Istio. Part 3

Crear grups

A Extensió d'autorització aneu a grups i crear un grup Moderadors. Com que tractarem tots els usuaris autenticats com a usuaris habituals, no cal crear-hi un grup addicional.

Trieu un grup Moderadors, Premeu Afegeix membres, afegeix el teu compte principal. Deixeu alguns usuaris sense cap grup per assegurar-vos que se'ls nega l'accés. (Es poden crear nous usuaris manualment mitjançant Auth0 Portal > Usuaris > Crea usuari.)

Afegeix una reclamació de grup al testimoni d'accés

S'han afegit usuaris als grups, però aquesta informació també s'ha de reflectir en els testimonis d'accés. Per complir amb OpenID Connect i al mateix temps retornar els grups que necessitem, el testimoni haurà d'afegir el seu propi reclamació personalitzada. Implementat mitjançant regles Auth0.

Per crear una regla, aneu al portal Auth0 per Regles, Premeu Crea una regla i seleccioneu una regla buida de les plantilles.

Torna als microserveis amb Istio. Part 3

Copieu el codi següent i deseu-lo com a regla nova Afegeix una reclamació de grup (namespacedGroup.js):

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

Nota: aquest codi agafa el primer grup d'usuaris definit a l'extensió d'autorització i l'afegeix al testimoni d'accés com a reclamació personalitzada (sota el seu espai de noms, tal com requereix Auth0).

Torna a la pàgina Regles i comproveu que teniu dues regles escrites en l'ordre següent:

  • auth0-authorization-extension
  • Afegeix una reclamació de grup

L'ordre és important perquè el camp del grup rep la regla de manera asíncrona auth0-authorization-extension i després s'afegeix com a reclamació per la segona regla. El resultat és un testimoni d'accés com aquest:

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

Ara heu de configurar el servidor intermediari d'Envoy per comprovar l'accés dels usuaris, per al qual el grup es retirarà de la reclamació (https://sa.io/group) al testimoni d'accés retornat. Aquest és el tema de la següent secció de l'article.

Configuració d'autorització a Istio

Perquè l'autorització funcioni, heu d'habilitar RBAC per a Istio. Per fer-ho, utilitzarem la configuració següent:

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" 

Explicació:

  • 1: habiliteu RBAC només per als serveis i espais de noms enumerats al camp Inclusion;
  • 2: enumerem una llista dels nostres serveis.

Apliquem la configuració amb l'ordre següent:

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

Tots els serveis ara requereixen un control d'accés basat en rols. És a dir, l'accés a tots els serveis està prohibit i donarà lloc a una resposta RBAC: access denied. Ara permetrem l'accés als usuaris autoritzats.

Configuració d'accés per a usuaris habituals

Tots els usuaris han de tenir accés als serveis SA-Frontend i SA-WebApp. Implementat amb els recursos d'Istio següents:

  • Rol de servei — determina els drets que té l'usuari;
  • ServiceRoleBinding — determina a qui pertany aquesta funció de servei.

Per als usuaris normals permetrem l'accés a determinats serveis (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: ["*"]

I a través regular-user-binding aplicar ServiceRole a tots els visitants de la pàgina (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"

"Tots els usuaris" vol dir que els usuaris no autenticats també tindran accés a l'aplicació web SA? No, la política comprovarà la validesa del testimoni JWT.

Apliquem les configuracions:

$ 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

Configuració d'accés per a moderadors

Per als moderadors, volem habilitar l'accés a tots els serveis (mod-service-role.yaml):

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

Però volem aquests drets només per a aquells usuaris el testimoni d'accés dels quals conté reclamacions https://sa.io/group amb significat 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" 

Apliquem les configuracions:

$ 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

A causa de la memòria cau als enviats, les regles d'autorització poden tardar uns quants minuts a entrar en vigor. A continuació, podeu assegurar-vos que els usuaris i els moderadors tinguin diferents nivells d'accés.

Conclusió d'aquesta part

De debò, però, heu vist mai un enfocament més senzill, sense esforç, escalable i segur per a l'autenticació i l'autorització?

Només es van requerir tres recursos Istio (RbacConfig, ServiceRole i ServiceRoleBinding) per aconseguir un control detallat sobre l'autenticació i l'autorització de l'accés dels usuaris finals als serveis.

A més, ens hem ocupat d'aquestes qüestions des dels nostres serveis enviats, aconseguint:

  • reduir la quantitat de codi genèric que pot contenir problemes de seguretat i errors;
  • reduir el nombre de situacions estúpides en què un punt final resultava accessible des de l'exterior i s'oblidava d'informar-lo;
  • eliminant la necessitat d'actualitzar tots els serveis cada vegada que s'afegeix un nou rol o dret;
  • que els nous serveis siguin senzills, segurs i ràpids.

Sortida

Istio permet als equips centrar els seus recursos en tasques crítiques per a l'empresa sense afegir despeses generals als serveis, tornant-los a l'estat micro.

L'article (en tres parts) proporciona coneixements bàsics i instruccions pràctiques ja fetes per començar amb Istio en projectes reals.

PS del traductor

Llegeix també al nostre blog:

Font: www.habr.com

Afegeix comentari