Terug naar microservices met Istio. Deel 3

Terug naar microservices met Istio. Deel 3

Opmerking vertaler.: Eerste deel van deze cyclus was gewijd aan het verkennen van de mogelijkheden van Istio en het demonstreren ervan in de praktijk, tweede – fijn afgestemde routing en netwerkverkeersbeheer. Nu zullen we het hebben over beveiliging: voor de demonstratie van de bijbehorende basisfunctionaliteiten gebruikt de auteur de identity-service Auth0, maar andere providers kunnen op vergelijkbare wijze worden ingesteld.

We hebben een Kubernetes-cluster opgezet waarin we Istio en een voorbeeld van een microservice-applicatie voor Sentiment Analyse hebben uitgerold – zo zijn de mogelijkheden van Istio gedemonstreerd.

Met behulp van Istio zijn we erin geslaagd om de grootte van de services klein te houden, omdat ze geen lagen zoals herhalingen (Retries), time-outs (Timeouts), circuit-breakers (Circuit Breakers), tracing (Tracing) en monitoring (Monitoring) hoeven te implementeren. Bovendien hebben we technieken voor geavanceerd testen en implementeren toegepast: A/B-testing, mirroring en canary deployments.

Terug naar microservices met Istio. Deel 3

In dit nieuwe materiaal zullen we de laatste lagen op de weg naar business value analyseren: authenticatie en autorisatie – en dat is in Istio een waar genot!

Authenticatie en autorisatie in Istio

Ik zou nooit geloven dat ik inspiratie zou halen uit authenticatie en autorisatie. Wat kan Istio technologische gezien bieden om deze onderwerpen boeiend te maken en zelfs jou te inspireren?

Het antwoord is eenvoudig: Istio verlegt de verantwoordelijkheid voor deze mogelijkheden van jouw services naar de Envoy-proxy. Tegen de tijd dat aanvragen de services bereiken, zijn ze al geverifieerd en geautoriseerd, zodat je alleen nog maar nuttige bedrijfsgerichte code hoeft te schrijven.

Klinkt goed? Laten we eens naar binnen kijken!

Authenticatie met Auth0

Als server voor identiteits- en toegangsbeheer zullen we Auth0 gebruiken, dat een gratis proefversie heeft, intuïtief is in gebruik en eenvoudigweg aanspreekt. Dezelfde principes kunnen echter ook worden toegepast op elke andere implementatie van OpenID Connect: KeyCloak, IdentityServer en vele anderen.

Om te beginnen ga je naar Auth0 Portal met je account, creëer een tenant (tenant – „huurder“, een logische isolatie-eenheid, zie voor meer informatie de documentatie – opmerking vert.) en ga naar Applications > Default App, selecteer Domein, zoals weergegeven in de onderstaande screenshot:

Terug naar microservices met Istio. Deel 3

Geef dit domein op in het bestand resource-manifests/istio/security/auth-policy.yaml (bronbestand):

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

Met deze bron stelt Pilot (een van de drie basiscomponenten van het Control Plane in Istio — red. vert.) Envoys in staat om verzoeken te authentiseren voordat ze naar de services worden doorgestuurd: sa-web-app en sa-feedback. Tegelijkertijd wordt de configuratie niet toegepast op de service-Envoys sa-frontend, zodat we de frontend niet-authentiek kunnen laten. Om het beleid (Policy) toe te passen, voert u de volgende opdracht uit:

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

Ga terug naar de pagina en doe een verzoek — u zult zien dat dit eindigt met de status 401 Unauthorized. Laten we nu gebruikers naar de frontend omleiden voor authenticatie met Auth0.

Authenticatie van verzoeken met Auth0

Om verzoeken van eindgebruikers te authentiseren, moet u een API in Auth0 maken die de geauthentiseerde services (reviews, details en ratings) vertegenwoordigt. Ga voor het maken van de API naar Auth0 Portal > APIs > Create API en vul het formulier in:

Terug naar microservices met Istio. Deel 3

Belangrijke informatie hier is Identifier, die we later in het script zullen gebruiken. Laten we deze noteren als:

  • Audience: {YOUR_AUDIENCE}

De overige noodzakelijke details zijn te vinden in het Auth0 Portal onder Applications — kies Test Application (wordt automatisch gemaakt samen met de API).

Hier noteren we:

  • Domein: {YOUR_DOMAIN}
  • Client Id: {YOUR_CLIENT_ID}

Scroll naar beneden naar het tekstveld Test Application Allowed Callback URLs (toegestane URL's voor callback), waarin we de URL opgeven waarheen de oproep moet worden verzonden nadat de authenticatie is voltooid. In ons geval is dit: http://{EXTERNAL_IP}/callback

En voor

Allowed Logout URLs (toegestane URL's voor uitloggen) voegen we toe: http://{EXTERNAL_IP}/logout

Laten we naar de frontend gaan.

Frontend bijwerken

Schakel over naar de tak

auth0 van de repository [istio-mastery] . In deze tak is de frontend-code gewijzigd om gebruikers naar Auth0 te omleiden voor authenticatie en om de JWT-token te gebruiken in verzoeken naar de andere services. Dit is de implementatie (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)); }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));
}

Om de frontend te vertalen naar het gebruik van tenant-gegevens in Auth0, opent u sa-frontend/src/services/Auth.js en vervangt u de waarden die we hierboven hebben genoteerd (Auth.js):

const Config = {
    clientID: '{YOUR_CLIENT_ID}',
    domain:'{YOUR_DOMAIN}',
    audience: '{YOUR_AUDIENCE}',
    ingressIP: '{EXTERNAL_IP}' // Gebruikt voor omleiding na authenticatie
}

De applicatie is klaar. Geef uw Docker-ID op in de onderstaande commando's tijdens het bouwen en implementeren van de aangebrachte wijzigingen:

$ 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

Probeer de applicatie! U wordt doorgestuurd naar Auth0, waar u moet inloggen (of zich registreren), waarna u terug wordt gestuurd naar de pagina waaruit geauthenticeerde verzoeken worden gedaan. Als u echter de in de eerdere delen van het artikel genoemde commando's met curl probeert, ontvangt u de code 401 Status Code, wat aangeeft dat het verzoek niet geautoriseerd is.

Laten we de volgende stap zetten — we autoriseren de verzoeken.

Autorisatie met Auth0

Authenticatie stelt ons in staat te begrijpen wie de gebruiker is, maar om te weten waar deze toegang toe heeft, is autorisatie vereist. Istio biedt ook hiervoor hulpmiddelen.

Laten we als voorbeeld twee gebruikersgroepen creëren (zie de onderstaande afbeelding):

  • Gebruikers (users) — met toegang alleen tot de diensten SA-WebApp en SA-Frontend;
  • Moderators (moderators) — met toegang tot alle drie de diensten.

Terug naar microservices met Istio. Deel 3
Concept van autorisatie

Om deze groepen te maken, gebruiken we de Auth0 Authorization extensie en bieden we verschillende toegangsniveaus aan via Istio.

Installatie en configuratie van Auth0 Authorization

Ga op het Auth0-portaal naar extensies (Extensions) en installeer Auth0 Authorization. Na de installatie gaat u naar Authorization Extension, en vervolgens naar de configuratie van de tenant door rechtsboven op de bijbehorende menu-optie te klikken (Configuration). Activeer groepen (Groups) en druk op de knop regel publiceren (Publish rule).

Terug naar microservices met Istio. Deel 3

Groepen maken

Ga in de Authorization Extension naar Groups en maak een groep Moderators. Aangezien we alle geauthenticeerde gebruikers als gewone gebruikers beschouwen, is er geen behoefte om voor hen een extra groep te creëren.

Selecteer de groep Moderators, klik op Add Members, voeg uw hoofaccount toe. Laat sommige gebruikers zonder groep om ervoor te zorgen dat hun toegang is verboden. (Nieuwe gebruikers kunnen handmatig worden aangemaakt via Auth0 Portal > Gebruikers > Maak Gebruiker Aan.)

Voeg Group Claim toe aan Access Token

Gebruikers zijn aan groepen toegevoegd, maar deze informatie moet ook in de toegangstokens worden weerspiegeld. Om te voldoen aan OpenID Connect en tegelijkertijd de groepen die we nodig hebben terug te geven, moet de token zijn custom claim. Dit wordt geïmplementeerd via Auth0-regels.

Om een regel te creëren, gaat u naar de Auth0 Portal naar Regels, klik op Regel Aanmaken en kies een lege regel uit de sjablonen.

Terug naar microservices met Istio. Deel 3

Kopieer de onderstaande code en sla deze op als een nieuwe regel Voeg Group Claim Toe (namespacedGroup.js):

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

Opmerking: deze code neemt de eerste groep van de gebruiker zoals gedefinieerd in de Authorization Extension en voegt deze toe aan de access-token als een custom claim (onder zijn eigen namespace, zoals vereist door Auth0).

Ga terug naar de pagina Regels en controleer of u twee regels hebt die in de volgende volgorde zijn geschreven:

  • auth0-authorization-extension
  • Voeg Group Claim Toe

De volgorde is belangrijk, omdat het groepsveld asynchroon het regel verkrijgt auth0-authorization-extension en vervolgens als claim wordt toegevoegd door de tweede regel. Dit resulteert in de volgende access-token:

{
 "https://sa.io/group": "Moderators",
 "iss": "https://sentiment-analysis.eu.auth0.com/",
 "sub": "google-oauth2|196405271625531691872"
 // [ingekort voor duidelijkheid]
}

Nu moet de Envoy-proxy worden geconfigureerd om gebruikers toegang te controleren, waarbij de groep uit de claim (https://sa.io/group) in de geretourneerde access-token zal worden gehaald. Dit is het onderwerp voor het volgende deel van het artikel.

Autorisatie Configuratie in Istio

Om autorisatie te laten werken, moet RBAC voor Istio worden ingeschakeld. Hiervoor gebruiken we de volgende configuratie:

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" 

Uitleg:

  • 1 — we schakelen RBAC alleen in voor de services en namespaces die in het veld Inclusion;
  • 2 — we sommen onze services op.

Pas de configuratie toe met het volgende commando:

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

Nu vereisen alle services rolgebaseerd toegangsbeheer (Role-Based Access Control). Met andere woorden, toegang tot alle services is verboden en leidt tot een reactie. RBAC: toegang geweigerd. Laten we nu toegang verlenen aan geautoriseerde gebruikers.

Toegangsconfiguratie voor gewone gebruikers

Alle gebruikers moeten toegang hebben tot de SA-Frontend en SA-WebApp services. Dit wordt gerealiseerd met behulp van de volgende Istio-resources:

  • ServiceRole — definieert de rechten die een gebruiker heeft;
  • ServiceRoleBinding — definieert aan wie deze ServiceRole is toegewezen.

Voor gewone gebruikers verlenen we toegang tot specifieke services (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: ["*"]

En met regular-user-binding passen we de ServiceRole toe op alle bezoekers van de pagina (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"

Betekent "alle gebruikers" dat ook niet-geauthenticeerde gebruikers toegang krijgen tot SA WebApp? Nee, het beleid controleert de geldigheid van de JWT-token.

We passen de configuraties toe:

$ 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

Toegangsconfiguratie voor moderators

Voor moderators willen we toegang verlenen tot alle services (mod-service-role.yaml):

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

Maar we willen deze rechten alleen voor die gebruikers wiens access-token de claim bevat https://sa.io/group met de waarde 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" 

We passen de configuraties toe:

$ 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

Vanwege caching in envoy’s kan het enkele minuten duren voordat de autorisatie regels van kracht worden. Daarna kunt u bevestigen dat gebruikers en moderators verschillende toegangsniveaus hebben.

Conclusie over dit deel

Laten we eerlijk zijn: heeft u ooit een eenvoudigere, moeiteloze, schaalbare en veilige benadering van authenticatie en autorisatie gezien?

Slechts drie Istio-resources (RbacConfig, ServiceRole en ServiceRoleBinding) waren nodig om fijnmazige controle over de authenticatie en autorisatie van eindgebruikers tot services te realiseren.

Daarnaast hebben we de zorg voor deze problemen uit onze services gehaald en zijn we erin geslaagd om:

  • de hoeveelheid standaardcode te verminderen waarin beveiligingsproblemen en bugs kunnen optreden;
  • de hoeveelheid domme situaties te verminderen waarin een endpoint toegankelijk was vanaf buitenaf zonder dit te melden;
  • de noodzaak te elimineren om alle services te updaten bij elke toevoeging van een nieuwe rol of permissie;
  • te zorgen dat nieuwe services eenvoudig, veilig en snel blijven.

Uitslag

Istio stelt teams in staat om zich te concentreren op belangrijke zakelijke taken zonder extra overhead voor de services, waardoor ze terugkeren naar de status van 'micro'.

Het artikel (in drie delen) heeft basiskennis en een praktische handleiding geboden om met Istio aan de slag te gaan in echte projecten.

P.S. van de vertaler

Lees ook op onze blog:

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers 🔥 Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster