Tillbaka till mikrotjänster med Istio. Del 3

Tillbaka till mikrotjänster med Istio. Del 3

Notera. transl.: Den första delen denna serie ägnades åt att lära känna Istios kapacitet och demonstrera dem i aktion, andra — finjusterad routing och nätverkstrafikhantering. Nu kommer vi att prata om säkerhet: för att demonstrera de grundläggande funktionerna relaterade till det använder författaren Auth0-identitetstjänsten, men andra leverantörer kan konfigureras på liknande sätt.

Vi skapade ett Kubernetes-kluster där vi distribuerade Istio och ett exempel på en mikrotjänstapplikation, Sentiment Analysis, för att demonstrera Istios kapacitet.

Med Istio kunde vi hålla våra tjänster små eftersom de inte behöver implementera lager som Retries, Timeouts, Circuit Breakers, Tracing, Monitoring. . Dessutom använde vi avancerade test- och distributionstekniker: A/B-testning, spegling och utrullningar av kanariefåglar.

Tillbaka till mikrotjänster med Istio. Del 3

I det nya materialet kommer vi att ta itu med de sista lagren på vägen till affärsvärde: autentisering och auktorisering - och i Istio är det ett sant nöje!

Autentisering och auktorisering i Istio

Jag skulle aldrig ha trott att jag skulle bli inspirerad av autentisering och auktorisering. Vad kan Istio erbjuda ur ett teknikperspektiv för att göra dessa ämnen roliga och ännu mer inspirerande för dig?

Svaret är enkelt: Istio flyttar ansvaret för dessa funktioner från dina tjänster till Envoy proxy. När förfrågningarna når tjänsterna har de redan autentiserats och auktoriserats, så allt du behöver göra är att skriva affärsanvändbar kod.

Låter bra? Låt oss ta en titt inuti!

Autentisering med Auth0

Som server för identitets- och åtkomsthantering kommer vi att använda Auth0, som har en testversion, är intuitiv att använda och jag gillar det helt enkelt. Samma principer kan dock tillämpas på alla andra OpenID Connect implementeringar: KeyCloak, IdentityServer och många andra.

För att komma igång, gå till Auth0 Portal skapa en hyresgäst med ditt konto (hyresgäst - "hyresgäst", logisk isoleringsenhet, för mer information se dokumentation - cirka. översätt.) och gå till Applikationer > Standardappväljer Domän, som visas i skärmdumpen nedan:

Tillbaka till mikrotjänster med Istio. Del 3

Ange denna domän i filen resource-manifests/istio/security/auth-policy.yaml (källa):

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 sådan resurs, Pilot (en av de tre grundläggande styrplanskomponenterna i Istio - cirka översättning) konfigurerar Envoy att autentisera förfrågningar innan de vidarebefordras till tjänster: sa-web-app и sa-feedback. Samtidigt tillämpas inte konfigurationen på tjänstenvoy sa-frontend, vilket gör att vi kan lämna gränssnittet oautentiserat. För att tillämpa policyn, kör kommandot:

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

Gå tillbaka till sidan och gör en förfrågan - du kommer att se att den slutar med statusen 401 obehörigt. Låt oss nu omdirigera frontend-användare för att autentisera med Auth0.

Autentisera förfrågningar med Auth0

För att autentisera slutanvändarförfrågningar måste du skapa ett API i Auth0 som representerar de autentiserade tjänsterna (recensioner, detaljer och betyg). För att skapa ett API, gå till Auth0 Portal > API:er > Skapa API och fyll i formuläret:

Tillbaka till mikrotjänster med Istio. Del 3

Den viktiga informationen här är Identifiera, som vi kommer att använda senare i skriptet. Låt oss skriva ner det så här:

  • publik: {Your_audience}

De återstående detaljerna vi behöver finns på Auth0-portalen i avsnittet Applikationer - Välj Testapplikation (skapas automatiskt tillsammans med API).

Här kommer vi att skriva:

  • Domän: {DIN_DOMÄN}
  • Klient ID: {Your_client_id}

Bläddra till Testapplikation till textfält Tillåtna återuppringningsadresser (lösta URL:er för återuppringningen), där vi anger URL:en dit anropet ska skickas efter att autentiseringen är klar. I vårt fall är det:

http://{EXTERNAL_IP}/callback

Och för Tillåtna utloggningsadresser (tillåtna webbadresser för utloggning) lägg till:

http://{EXTERNAL_IP}/logout

Låt oss gå vidare till frontend.

Frontend-uppdatering

Byt till filial auth0 förvaret [istio-mastery]. I den här grenen ändras frontendkoden för att omdirigera användare till Auth0 för autentisering och använda JWT-token i förfrågningar till andra tjänster. Det senare implementeras enligt följande (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));
}

För att ändra gränssnittet för att använda klientdata i Auth0, öppna sa-frontend/src/services/Auth.js och ersätt i den värdena som vi skrev ovan (Auth.js):

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

Ansökan är klar. Ange ditt Docker-ID i kommandona nedan när du bygger och distribuerar de ändringar som gjorts:

$ 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

Testa appen! Du kommer att omdirigeras till Auth0, där du behöver logga in (eller registrera dig), varefter du skickas tillbaka till sidan från vilken redan autentiserade förfrågningar kommer att göras. Om du provar kommandona som nämns i de första delarna av artikeln med curl får du koden 401 Statuskod, vilket signalerar att begäran inte är auktoriserad.

Låt oss ta nästa steg - auktorisera förfrågningar.

Auktorisering med Auth0

Autentisering låter oss förstå vem en användare är, men behörighet krävs för att veta vad de har tillgång till. Istio erbjuder verktyg för detta också.

Som ett exempel, låt oss skapa två användargrupper (se diagrammet nedan):

  • Medlemmar (användare) — med endast tillgång till SA-WebApp och SA-Frontend-tjänster;
  • Moderatorer (moderatorer) — med tillgång till alla tre tjänsterna.

Tillbaka till mikrotjänster med Istio. Del 3
Auktorisation koncept

För att skapa dessa grupper kommer vi att använda tillägget Auth0 Authorization och använda Istio för att ge dem olika åtkomstnivåer.

Installation och konfiguration av Auth0 Authorization

I Auth0-portalen, gå till tillägg (förlängningar) och installera Auth0 Auktorisering. Efter installationen, gå till Auktorisationsförlängning, och där - till hyresgästens konfiguration genom att klicka uppe till höger och välja lämpligt menyalternativ (Konfiguration). Aktivera grupper (Grupper) och klicka på knappen publicera regel (Publicera regel).

Tillbaka till mikrotjänster med Istio. Del 3

Skapa grupper

I Auktoriseringsförlängning gå till Grupper och skapa en grupp moderatorer. Eftersom vi kommer att behandla alla autentiserade användare som vanliga användare, finns det ingen anledning att skapa en extra grupp för dem.

Välj en grupp moderatorer, Tryck Lägg till medlemmar, lägg till ditt huvudkonto. Lämna några användare utan någon grupp för att se till att de nekas åtkomst. (Nya användare kan skapas manuellt via Auth0 Portal > Användare > Skapa användare.)

Lägg till gruppanspråk till åtkomsttoken

Användare har lagts till i grupper, men denna information måste också återspeglas i åtkomsttokens. För att följa OpenID Connect och samtidigt returnera de grupper vi behöver, kommer token att behöva lägga till sin egen anpassat anspråk. Implementerad genom Auth0-regler.

För att skapa en regel, gå till Auth0 Portal till regler, Tryck Skapa regel och välj en tom regel från mallarna.

Tillbaka till mikrotjänster med Istio. Del 3

Kopiera koden nedan och spara den som en ny regel Lägg till gruppanspråk (namespacedgroup.js):

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

Notera: Den här koden tar den första användargruppen som definierats i auktoriseringstillägget och lägger till den i åtkomsttoken som ett anpassat anspråk (under dess namnområde, som krävs av Auth0).

Gå tillbaka till sidan regler och kontrollera att du har två regler skrivna i följande ordning:

  • autoriserad autoriseringsutveckling
  • Lägg till gruppanspråk

Ordningen är viktig eftersom gruppfältet tar emot regeln asynkront autoriserad autoriseringsutveckling och därefter läggs det till som ett krav genom den andra regeln. Resultatet är en åtkomsttoken så här:

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

Nu måste du konfigurera Envoy proxy för att kontrollera användaråtkomst, för vilken gruppen kommer att dras från anspråk (https://sa.io/group) i den returnerade åtkomsttoken. Detta är ämnet för nästa avsnitt av artikeln.

Behörighetskonfiguration i Istio

För att behörighet ska fungera måste du aktivera RBAC för Istio. För att göra detta kommer vi att använda följande konfiguration:

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" 

Förklaring:

  • 1 — aktivera RBAC endast för tjänster och namnområden som anges i fältet Inclusion;
  • 2 — vi listar en lista över våra tjänster.

Låt oss tillämpa konfigurationen med följande kommando:

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

Alla tjänster kräver nu rollbaserad åtkomstkontroll. Med andra ord, tillgång till alla tjänster är förbjuden och kommer att resultera i ett svar RBAC: access denied. Låt oss nu tillåta åtkomst till behöriga användare.

Åtkomstkonfiguration för vanliga användare

Alla användare måste ha tillgång till tjänsterna SA-Frontend och SA-WebApp. Implementerat med hjälp av följande Istio-resurser:

  • ServiceRoll — bestämmer de rättigheter som användaren har;
  • TjänstRollbindning — bestämmer vem denna tjänsteroll tillhör.

För vanliga användare kommer vi att tillåta åtkomst till vissa tjänster (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: ["*"]

Och efter regular-user-binding tillämpa ServiceRole på alla sidbesökare (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"

Betyder "alla användare" att oautentiserade användare också kommer att ha tillgång till SA WebApp? Nej, policyn kontrollerar giltigheten av JWT-token.

Låt oss tillämpa konfigurationerna:

$ 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

Åtkomstkonfiguration för moderatorer

För moderatorer vill vi möjliggöra åtkomst till alla tjänster (modtjänstroll.yaml):

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

Men vi vill bara ha sådana rättigheter för de användare vars åtkomsttoken innehåller anspråk 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" 

Låt oss tillämpa konfigurationerna:

$ 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å grund av cachning i sändebud kan det ta ett par minuter innan behörighetsreglerna träder i kraft. Du kan sedan se till att användare och moderatorer har olika åtkomstnivåer.

Slutsats på denna del

Men allvarligt talat, har du någonsin sett en enklare, enkel, skalbar och säker metod för autentisering och auktorisering?

Endast tre Istio-resurser (RbacConfig, ServiceRole och ServiceRoleBinding) krävdes för att uppnå finkornig kontroll över autentisering och auktorisering av slutanvändaråtkomst till tjänster.

Dessutom har vi tagit hand om dessa frågor från våra sändebudstjänster och uppnått:

  • minska mängden generisk kod som kan innehålla säkerhetsproblem och buggar;
  • minska antalet dumma situationer där en slutpunkt visade sig vara tillgänglig från utsidan och glömde att rapportera den;
  • eliminerar behovet av att uppdatera alla tjänster varje gång en ny roll eller rättighet läggs till;
  • att nya tjänster förblir enkla, säkra och snabba.

Utgång

Istio låter team fokusera sina resurser på affärskritiska uppgifter utan att lägga till overhead till tjänsterna och återställa dem till mikrostatus.

Artikeln (i tre delar) gav grundläggande kunskaper och färdiga praktiska instruktioner för att komma igång med Istio i riktiga projekt.

PS från översättaren

Läs även på vår blogg:

Källa: will.com

Lägg en kommentar