Tilbake til mikrotjenester med Istio. Del 3

Tilbake til mikrotjenester med Istio. Del 3

Merk. overs.: Den første delen denne serien var viet til å bli kjent med Istios evner og demonstrere dem i aksjon, andre — finjustert ruting og administrasjon av nettverkstrafikk. Nå skal vi snakke om sikkerhet: For å demonstrere de grunnleggende funksjonene knyttet til det, bruker forfatteren Auth0-identitetstjenesten, men andre leverandører kan konfigureres på lignende måte.

Vi satte opp en Kubernetes-klynge der vi distribuerte Istio og et eksempel på en mikrotjenesteapplikasjon, Sentiment Analysis, for å demonstrere Istios evner.

Med Istio klarte vi å holde tjenestene våre små fordi de ikke trenger å implementere lag som Retries, Timeouts, Circuit Breakers, Tracing, Monitoring. . I tillegg brukte vi avanserte test- og distribusjonsteknikker: A/B-testing, speiling og utrulling av kanarifugler.

Tilbake til mikrotjenester med Istio. Del 3

I det nye materialet vil vi ta for oss de siste lagene på veien til forretningsverdi: autentisering og autorisasjon - og i Istio er det en sann fornøyelse!

Autentisering og autorisasjon i Istio

Jeg hadde aldri trodd at jeg ville bli inspirert av autentisering og autorisasjon. Hva kan Istio tilby fra et teknologiperspektiv for å gjøre disse temaene morsomme og, enda mer, inspirerende for deg?

Svaret er enkelt: Istio flytter ansvaret for disse egenskapene fra tjenestene dine til Envoy proxy. Når forespørslene når tjenestene, har de allerede blitt autentisert og autorisert, så alt du trenger å gjøre er å skrive forretningsnyttig kode.

Høres bra ut? La oss ta en titt på innsiden!

Autentisering med Auth0

Som server for identitets- og tilgangsadministrasjon vil vi bruke Auth0, som har en prøveversjon, er intuitiv å bruke og jeg liker det rett og slett. Imidlertid kan de samme prinsippene brukes på alle andre OpenID Connect-implementeringer: KeyCloak, IdentityServer og mange andre.

For å komme i gang, gå til Auth0-portal opprett en leietaker med kontoen din (leietaker - "leietaker", logisk isolasjonsenhet, for flere detaljer se dokumentasjon — ca. oversett.) og gå til Applikasjoner > Standard appvelger Domene, som vist på skjermbildet nedenfor:

Tilbake til mikrotjenester med Istio. Del 3

Spesifiser dette domenet i filen resource-manifests/istio/security/auth-policy.yaml (kilde):

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

Med en slik ressurs, Pilot (en av de tre grunnleggende kontrollplankomponentene i Istio - ca. oversettelse) konfigurerer Envoy til å autentisere forespørsler før de videresendes til tjenester: sa-web-app и sa-feedback. Samtidig blir ikke konfigurasjonen brukt på tjenesteutsendinger sa-frontend, slik at vi kan la frontend være uautentisert. For å bruke policyen, kjør kommandoen:

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

Gå tilbake til siden og kom med en forespørsel - du vil se at den ender med statusen 401 Uautorisert. La oss nå omdirigere grensesnittbrukere til å autentisere med Auth0.

Autentiserer forespørsler med Auth0

For å autentisere sluttbrukerforespørsler, må du opprette en API i Auth0 som vil representere de autentiserte tjenestene (anmeldelser, detaljer og vurderinger). For å opprette en API, gå til Auth0 Portal > APIer > Opprett API og fyll ut skjemaet:

Tilbake til mikrotjenester med Istio. Del 3

Den viktige informasjonen her er Identifiser, som vi skal bruke senere i manuset. La oss skrive det ned slik:

  • Publikum: {YOUR_AUDIENCE}

De resterende detaljene vi trenger finner du på Auth0-portalen i seksjonen applikasjoner - plukke ut Test søknad (opprettet automatisk sammen med API).

Her vil vi skrive:

  • Domene: {DITT_DOMENE}
  • Klient-ID: {YOUR_CLIENT_ID}

Bla til Test søknad til tekstfeltet Tillatte tilbakeringingsadresser (løste URL-er for tilbakeringingen), der vi spesifiserer URL-en som anropet skal sendes til etter at autentisering er fullført. I vårt tilfelle er det:

http://{EXTERNAL_IP}/callback

Og for Tillatte utloggingsadresser (tillatte nettadresser for utlogging) legg til:

http://{EXTERNAL_IP}/logout

La oss gå videre til frontend.

Frontend-oppdatering

Bytt til filial auth0 oppbevaringssted [istio-mastery]. I denne grenen endres grensesnittkoden for å omdirigere brukere til Auth0 for autentisering og bruke JWT-tokenet i forespørsler til andre tjenester. Sistnevnte implementeres som følger (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));
}

For å endre grensesnittet til å bruke leietakerdata i Auth0, åpne sa-frontend/src/services/Auth.js og bytt inn verdiene som vi skrev ovenfor (Auth.js):

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

Søknaden er klar. Spesifiser Docker-ID-en din i kommandoene nedenfor når du bygger og distribuerer endringene som er gjort:

$ 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

Prøv appen! Du vil bli omdirigert til Auth0, hvor du må logge inn (eller registrere deg), hvoretter du vil bli sendt tilbake til siden som allerede autentiserte forespørsler vil bli sendt fra. Hvis du prøver kommandoene nevnt i de første delene av artikkelen med curl, får du koden 401 Statuskode, som signaliserer at forespørselen ikke er autorisert.

La oss ta neste steg – godkjenne forespørsler.

Autorisasjon med Auth0

Autentisering lar oss forstå hvem en bruker er, men det kreves autorisasjon for å vite hva de har tilgang til. Istio tilbyr også verktøy for dette.

Som et eksempel, la oss lage to brukergrupper (se diagrammet nedenfor):

  • Medlemmer (brukere) — med kun tilgang til SA-WebApp og SA-Frontend-tjenester;
  • Moderatorer (moderatorer) — med tilgang til alle tre tjenestene.

Tilbake til mikrotjenester med Istio. Del 3
Autorisasjonskonsept

For å opprette disse gruppene vil vi bruke Auth0 Authorization-utvidelsen og bruke Istio for å gi dem forskjellige tilgangsnivåer.

Installasjon og konfigurering av Auth0 Authorization

I Auth0-portalen går du til utvidelser (utvidelser) og installer Auth0 Autorisasjon. Etter installasjonen, gå til Autorisasjonsutvidelse, og der - til leietakers konfigurasjon ved å klikke øverst til høyre og velge riktig menyalternativ (Konfigurasjon). Aktiver grupper (Grupper) og klikk på publiser regel-knappen (Publiser regel).

Tilbake til mikrotjenester med Istio. Del 3

Opprette grupper

Gå til Autorisasjonsutvidelse Grupper og opprette en gruppe moderatorer. Siden vi vil behandle alle autentiserte brukere som vanlige brukere, er det ikke nødvendig å opprette en ekstra gruppe for dem.

Velg en gruppe moderatorer, Trykk Legg til medlemmer, legg til hovedkontoen din. La noen brukere være uten noen gruppe for å sikre at de blir nektet tilgang. (Nye brukere kan opprettes manuelt via Auth0 Portal > Brukere > Opprett bruker.)

Legg til gruppekrav til tilgangstoken

Brukere er lagt til i grupper, men denne informasjonen må også gjenspeiles i tilgangstokens. For å overholde OpenID Connect og samtidig returnere gruppene vi trenger, må tokenet legge til sitt eget tilpasset krav. Implementert gjennom Auth0-regler.

For å opprette en regel, gå til Auth0 Portal til Regler, Trykk Opprett regel og velg en tom regel fra malene.

Tilbake til mikrotjenester med Istio. Del 3

Kopier koden nedenfor og lagre den som en ny regel Legg til gruppekrav (namespacedGroup.js):

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

Note: Denne koden tar den første brukergruppen definert i autorisasjonsutvidelsen og legger den til tilgangstokenet som et tilpasset krav (under navneområdet, som kreves av Auth0).

Gå tilbake til siden Regler og sjekk at du har to regler skrevet i følgende rekkefølge:

  • auth0-autorisasjon-utvidelse
  • Legg til gruppekrav

Rekkefølgen er viktig fordi gruppefeltet mottar regelen asynkront auth0-autorisasjon-utvidelse og etter det er det lagt til som et krav etter den andre regelen. Resultatet er et tilgangstoken som dette:

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

Nå må du konfigurere Envoy proxy for å sjekke brukertilgang, som gruppen vil bli trukket fra krav (https://sa.io/group) i det returnerte tilgangstokenet. Dette er temaet for neste del av artikkelen.

Autorisasjonskonfigurasjon i Istio

For at autorisasjon skal fungere, må du aktivere RBAC for Istio. For å gjøre dette bruker vi følgende konfigurasjon:

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" 

Forklaring:

  • 1 — aktiver RBAC bare for tjenester og navneområder som er oppført i feltet Inclusion;
  • 2 — vi viser en liste over våre tjenester.

La oss bruke konfigurasjonen med følgende kommando:

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

Alle tjenester krever nå rollebasert tilgangskontroll. Med andre ord, tilgang til alle tjenester er forbudt og vil resultere i et svar RBAC: access denied. La oss nå gi tilgang til autoriserte brukere.

Tilgang til konfigurasjon for vanlige brukere

Alle brukere må ha tilgang til tjenestene SA-Frontend og SA-WebApp. Implementert ved hjelp av følgende Istio-ressurser:

  • Tjenesterolle — bestemmer rettighetene som brukeren har;
  • TjenesteRoleBinding — bestemmer hvem denne tjenesterollen tilhører.

For vanlige brukere vil vi tillate tilgang til visse tjenester (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: ["*"]

Og etter regular-user-binding bruk ServiceRole på alle besøkende på siden (regular-user-service-rolle-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"

Betyr "alle brukere" at uautentiserte brukere også vil ha tilgang til SA WebApp? Nei, policyen vil sjekke gyldigheten til JWT-tokenet.

La oss bruke konfigurasjonene:

$ 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

Tilgang til konfigurasjon for moderatorer

For moderatorer ønsker vi å aktivere tilgang til alle tjenester (mod-service-rolle.yaml):

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

Men vi ønsker slike rettigheter bare for de brukerne hvis tilgangstoken inneholder krav https://sa.io/group med mening Moderators (mod-service-rolle-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" 

La oss bruke konfigurasjonene:

$ 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

På grunn av bufring i utsendinger kan det ta et par minutter før autorisasjonsreglene trer i kraft. Du kan da sikre at brukere og moderatorer har ulike tilgangsnivåer.

Konklusjon på denne delen

Men seriøst, har du noen gang sett en enklere, uanstrengt, skalerbar og sikker tilnærming til autentisering og autorisasjon?

Bare tre Istio-ressurser (RbacConfig, ServiceRole og ServiceRoleBinding) var nødvendig for å oppnå finmasket kontroll over autentisering og autorisasjon av sluttbrukertilgang til tjenester.

I tillegg har vi tatt hånd om disse problemene fra våre utsendingstjenester, og oppnådd:

  • redusere mengden generisk kode som kan inneholde sikkerhetsproblemer og feil;
  • redusere antall dumme situasjoner der ett endepunkt viste seg å være tilgjengelig fra utsiden og glemte å rapportere det;
  • eliminerer behovet for å oppdatere alle tjenester hver gang en ny rolle eller rettighet legges til;
  • at nye tjenester forblir enkle, sikre og raske.

Utgang

Istio lar team fokusere ressursene sine på forretningskritiske oppgaver uten å legge til overhead til tjenester, og tilbakestille dem til mikrostatus.

Artikkelen (i tre deler) ga grunnleggende kunnskap og ferdige praktiske instruksjoner for å komme i gang med Istio i virkelige prosjekter.

PS fra oversetter

Les også på bloggen vår:

Kilde: www.habr.com

Legg til en kommentar