ZurĂŒck zu den Mikrodiensten mit Istio. Teil 3

ZurĂŒck zu den Mikrodiensten mit Istio. Teil 3

Anmerkung des Übersetzers.: Erster Teil diesem Zyklus war die EinfĂŒhrung in die Möglichkeiten von Istio und deren Demonstration in der Praxis gewidmet, zweite – der feinjustierbaren Routing- und Netzwerkverkehrssteuerung. Jetzt geht es um Sicherheit: Zur Demonstration der damit verbundenen Grundfunktionen verwendet der Autor den IdentitĂ€tsdienst Auth0, wobei auch andere Anbieter analog konfiguriert werden können.

Wir haben ein Kubernetes-Cluster eingerichtet, in dem wir Istio und ein Beispiel fĂŒr eine mikrodienstliche Anwendung zur Sentimentanalyse bereitgestellt haben - so wurden die Möglichkeiten von Istio demonstriert.

Mit Istio ist es uns gelungen, die GrĂ¶ĂŸe der Dienste gering zu halten, da sie keine Implementierung von "Schichten" wie Wiederholungsversuchen (Retries), Timeouts, automatischen Auslösern (Circuit Breakers), Tracing und Monitoring erfordern. DarĂŒber hinaus haben wir Techniken fĂŒr fortgeschrittenes Testen und Deployment eingesetzt: A/B-Tests, Mirroring und Canary Releases.

ZurĂŒck zu den Mikrodiensten mit Istio. Teil 3

Im neuen Material werden wir die letzten Schichten auf dem Weg zum GeschÀftswert behandeln: Authentifizierung und Autorisierung - und in Istio ist das wirklich angenehm!

Authentifizierung und Autorisierung in Istio

Ich hÀtte nie geglaubt, dass ich von Authentifizierung und Autorisierung inspiriert werde. Was kann Istio technologisch bieten, um diese Themen spannend zu machen und noch mehr - um auch euch zu inspirieren?

Die Antwort ist einfach: Istio verlagert die Verantwortung fĂŒr diese Möglichkeiten von euren Diensten auf den Proxy Envoy. Wenn die Anfragen die Dienste erreichen, sind sie bereits authentifiziert und autorisiert, sodass ihr nur noch geschĂ€ftsrelevanten Code schreiben mĂŒsst.

Klingt gut? Schauen wir uns das genauer an!

Authentifizierung mit Auth0

Als Server fĂŒr IdentitĂ€ts- und Zugriffsmanagement verwenden wir Auth0, das eine Testversion hat, intuitiv zu nutzen ist und mir einfach gefĂ€llt. Die gleichen Prinzipien können jedoch auch auf jede andere Implementierung von OpenID Connect: KeyCloak, IdentityServer und viele andere.

Zuerst geht auf Auth0 Portal mit eurem Konto, erstellt einen Tenant (Tenant – "Mieter", eine logische Isolierungseinheit, siehe dazu auch Dokumentation — Anm. d. Übersetzer) und geht zu Applications > Default App, wĂ€hlt Domain, wie im Screenshot unten gezeigt:

ZurĂŒck zu den Mikrodiensten mit Istio. Teil 3

Geben Sie diese Domain in die Datei ein resource-manifests/istio/security/auth-policy.yaml (Quelle):

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

Mit diesem Ressourcen verfĂŒgt Pilot (einer der drei grundlegenden Komponenten des Control Plane in Istio — Anm. d. Übers.) ĂŒber die Konfiguration von Envoy fĂŒr die Authentifizierung von Anforderungen, bevor diese an die Dienste weitergeleitet werden: sa-web-app und sa-feedback. Gleichzeitig wird die Konfiguration nicht auf die Dienste-Envoy angewendet sa-frontend, wodurch wir die Frontend-Anwendung ungeschĂŒtzt lassen können. Um die Richtlinie (Policy) anzuwenden, fĂŒhren Sie den folgenden Befehl aus:

$ kubectl apply -f resource-manifests/istio/security/auth-policy.yaml
policy.authentication.istio.io "auth-policy" erstellt

Gehen Sie zurĂŒck zur Seite und machen Sie eine Anfrage — Sie werden sehen, dass diese mit dem Status endet 401 Unauthorized. Lassen Sie uns jetzt die Benutzer des Frontends zur Authentifizierung bei Auth0 umleiten.

Anforderungen mit Auth0 authentifizieren

Um Anforderungen des Endbenutzers zu authentifizieren, mĂŒssen Sie eine API in Auth0 erstellen, die die authentifizierten Dienste (Bewertungen, Details und Bewertungen) darstellt. Um die API zu erstellen, gehen Sie zu Auth0 Portal > APIs > API erstellen und fĂŒllen Sie das Formular aus:

ZurĂŒck zu den Mikrodiensten mit Istio. Teil 3

Wichtige Informationen hier sind Identifier, das wir spÀter im Skript verwenden werden. Notieren Sie es sich:

  • Audience: {YOUR_AUDIENCE}

Die weiteren benötigten Details finden Sie im Auth0 Portal im Abschnitt Applications — wĂ€hlen Sie Test Application (wird zusammen mit der API automatisch erstellt).

Hier notieren wir uns:

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

Scrollen Sie nach Test Application bis zum Textfeld Allowed Callback URLs (erlaubte URLs fĂŒr den Callback), in dem wir die URL angeben, an die der Aufruf nach Abschluss der Authentifizierung gesendet werden soll. In unserem Fall ist dies:

http://{EXTERNAL_IP}/callback

Und fĂŒr Allowed Logout URLs (erlaubte URLs zur Abmeldung) fĂŒgen wir hinzu:

http://{EXTERNAL_IP}/logout

Gehen wir zum Frontend.

Frontend aktualisieren

Wechseln Sie zu dem Branch auth0 des Repositories [istio-mastery]. In diesem Branch wurde der Frontend-Code geÀndert, um Benutzer zu Auth0 zur Authentifizierung umzuleiten und das JWT-Token in den Anforderungen an die anderen Dienste zu verwenden. Letzteres wird wie folgt umgesetzt (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));
}

Um das Frontend zur Nutzung der Daten des Tenants in Auth0 zu ĂŒbertragen, öffnen Sie sa-frontend/src/services/Auth.js und ersetzen Sie die Werte, die wir oben aufgefĂŒhrt haben (Auth.js):

const Config = {
    clientID: '{YOUR_CLIENT_ID}',
    domain: '{YOUR_DOMAIN}',
    audience: '{YOUR_AUDIENCE}',
    ingressIP: '{EXTERNAL_IP}' // Wird fĂŒr die Umleitung nach der Authentifizierung verwendet
}

Die Anwendung ist bereit. Geben Sie Ihre Docker-ID in den folgenden Befehlen beim Erstellen und Bereitstellen der vorgenommenen Änderungen an:

$ 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

Testen Sie die Anwendung! Sie werden zu Auth0 weitergeleitet, wo Sie sich anmelden (oder registrieren) mĂŒssen, bevor Sie zurĂŒck zur Seite geleitet werden, von der aus authentifizierte Anfragen gestellt werden. Wenn Sie jedoch die in den ersten Teilen des Artikels erwĂ€hnten curl-Befehle ausprobieren, erhalten Sie den Code 401 Statuscode, der signalisiert, dass die Anfrage nicht autorisiert ist.

Lassen Sie uns den nĂ€chsten Schritt machen – autorisieren wir die Anfragen.

Autorisierung mit Auth0

Die Authentifizierung ermöglicht es uns zu verstehen, wer der Benutzer ist, aber um zu wissen, auf was er Zugriff hat, ist eine Autorisierung erforderlich. Istio bietet auch dafĂŒr Werkzeuge an.

Als Beispiel erstellen wir zwei Benutzergruppen (siehe das Schema unten):

  • Benutzer (users) – mit Zugriff nur auf die Dienste SA-WebApp und SA-Frontend;
  • Moderatoren (moderators) – mit Zugriff auf alle drei Dienste.

ZurĂŒck zu den Mikrodiensten mit Istio. Teil 3
Das Konzept der Autorisierung

Um diese Gruppen zu erstellen, verwenden wir die Auth0 Authorization-Erweiterung und gewÀhren ihnen mit Istio unterschiedliche Zugriffsebenen.

Installation und Konfiguration der Auth0 Authorization

Gehen Sie im Auth0-Portal zu den Erweiterungen (Extensions) und installieren Sie Auth0 Authorization. Nach der Installation gehen Sie zu Authorization Extension, und dort zur Konfiguration des Tenants, indem Sie oben rechts klicken und die entsprechende MenĂŒoption wĂ€hlen (Configuration). Aktivieren Sie die Gruppen (Groups) und klicken Sie auf die SchaltflĂ€che zur Veröffentlichung der Regel (Publish rule).

ZurĂŒck zu den Mikrodiensten mit Istio. Teil 3

Gruppen erstellen

Gehen Sie in der Authorization Extension zu Gruppen und erstellen Sie eine Gruppe Moderators. Da wir alle authentifizierten Benutzer als regulĂ€re betrachten, besteht keine Notwendigkeit, eine zusĂ€tzliche Gruppe fĂŒr sie zu erstellen.

WĂ€hlen Sie die Gruppe Moderators, klicken Sie auf Mitglieder hinzufĂŒgen, fĂŒgen Sie Ihr Hauptkonto hinzu. Lassen Sie einige Benutzer ohne Gruppe, um sicherzustellen, dass ihnen der Zugriff verweigert wird. (Neue Benutzer können manuell erstellt werden ĂŒber Auth0-Portal > Benutzer > Benutzer erstellen.)

FĂŒgen Sie den Gruppen-Claim ins Access-Token hinzu

Benutzer wurden Gruppen hinzugefĂŒgt, diese Information muss jedoch auch in den Zugriffstoken zurĂŒckgegeben werden. Um OpenID Connect zu entsprechen und gleichzeitig die benötigten Gruppen zurĂŒckzugeben, muss das Token seinen benutzerdefinierten Anspruch. Dies wird durch Auth0-Regeln umgesetzt.

Um eine Regel zu erstellen, gehen Sie zum Auth0-Portal zu Regeln, klicken Sie auf Regel erstellen und wÀhlen Sie eine leere Regel aus den Vorlagen aus.

ZurĂŒck zu den Mikrodiensten mit Istio. Teil 3

Kopieren Sie den folgenden Code und speichern Sie ihn als neue Regel Gruppen-Claim hinzufĂŒgen (namespacedGroup.js):

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

Hinweis: dieser Code nimmt die erste Gruppe des Benutzers, die in der Authorization-Extension definiert ist, und fĂŒgt sie als benutzerdefinierten Anspruch (unter ihrem Namespace, wie es Auth0 verlangt) ins Access-Token ein.

Gehen Sie zurĂŒck zur Seite Regeln und ĂŒberprĂŒfen Sie, ob Sie zwei Regeln in folgender Reihenfolge aufgefĂŒhrt haben:

  • auth0-authorization-extension
  • Gruppen-Claim hinzufĂŒgen

Die Reihenfolge ist wichtig, da das Gruppenfeld asynchron die Regel erhĂ€lt auth0-authorization-extension und dann als Anspruch durch die zweite Regel hinzugefĂŒgt wird. Das Ergebnis ist ein solches Access-Token:

{
 "https://sa.io/group": "Moderatoren",
 "iss": "https://sentiment-analysis.eu.auth0.com/",
 "sub": "google-oauth2|196405271625531691872"
 // [gekĂŒrzt zur Veranschaulichung]
}

Jetzt mĂŒssen Sie den Envoy-Proxy so konfigurieren, dass der benutzerdefinierte Zugriff ĂŒberprĂŒft wird, wozu die Gruppe aus dem Anspruch (https://sa.io/group) im zurĂŒckgegebenen Access-Token extrahiert wird. Dies ist das Thema des nĂ€chsten Abschnitts des Artikels.

Autorisierungskonfiguration in Istio

Um die Autorisierung zu aktivieren, mĂŒssen Sie RBAC fĂŒr Istio aktivieren. Dazu verwenden wir die folgende 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" 

ErlÀuterungen:

  • 1 — wir aktivieren RBAC nur fĂŒr die in dem Feld aufgefĂŒhrten Dienste und Namespaces Inclusion;
  • 2 — wir listen unsere Dienste auf.

Wenden Sie die Konfiguration mit diesem Befehl an:

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

Jetzt benötigen alle Dienste eine rollenbasierte Zugriffskontrolle. Mit anderen Worten, der Zugang zu allen Diensten ist verweigert und fĂŒhrt zu einer Antwort RBAC: Zugriff verweigert. Jetzt erlauben wir den autorisierten Benutzern den Zugriff.

Zugriffskonfiguration fĂŒr normale Benutzer

Alle Benutzer mĂŒssen Zugriff auf die Dienste SA-Frontend und SA-WebApp haben. Dies wird durch die folgenden Istio-Ressourcen umgesetzt:

  • ServiceRole — definiert die Rechte, die der Benutzer hat;
  • ServiceRoleBinding — definiert, auf wen sich diese ServiceRole bezieht.

FĂŒr normale Benutzer erlauben wir den Zugriff auf bestimmte Dienste (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: ["*"]

Und ĂŒber regular-user-binding wenden wir die ServiceRole auf alle Besucher der Seite an (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"

Bedeutet ‚alle Benutzer‘, dass auch nicht-authentifizierte Benutzer Zugang zur SA WebApp erhalten? Nein, die Richtlinie ĂŒberprĂŒft die GĂŒltigkeit des JWT-Tokens.

Lassen Sie uns die Konfiguration anwenden:

$ kubectl apply -f resource-manifests/istio/security/user-role.yaml
servicerole.rbac.istio.io/regular-user erstellt
servicerolebinding.rbac.istio.io/regular-user-binding erstellt

Zugriffskonfiguration fĂŒr Moderatoren

FĂŒr Moderatoren wollen wir den Zugriff auf alle Dienste aktivieren (mod-service-role.yaml):

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

Aber wir wollen diese Rechte nur fĂŒr die Benutzer haben, deren Zugangstoken den Anspruch enthĂ€lt https://sa.io/group mit dem Wert 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" 

Lassen Sie uns die Konfiguration anwenden:

$ kubectl apply -f resource-manifests/istio/security/mod-role.yaml
servicerole.rbac.istio.io/mod-user erstellt
servicerolebinding.rbac.istio.io/mod-user-binding erstellt

Wegen Caching in den Envoys kann es einige Minuten dauern, bis die Autorisierungsregeln in Kraft treten. Danach können Sie sicherstellen, dass Benutzer und Moderatoren unterschiedliche Zugriffslevels haben.

Zusammenfassung zu diesem Teil

Also ganz ehrlich: Haben Sie schon einmal einen einfacheren, mĂŒhelosen, skalierbaren und sicheren Ansatz fĂŒr Authentifizierung und Autorisierung gesehen?

Es waren nur drei Istio-Ressourcen (RbacConfig, ServiceRole und ServiceRoleBinding) erforderlich, um eine feingranulare Kontrolle ĂŒber die Authentifizierung und die Autorisierung des Zugriffs auf die Dienste der Endbenutzer zu erreichen.

DarĂŒber hinaus haben wir uns um diese Probleme in den Envoys gekĂŒmmert, indem wir Folgendes erreicht haben:

  • eine Reduzierung der Menge an Standardcode, in dem Sicherheitsprobleme und Bugs auftreten können;
  • eine Verringerung der dummen Situationen, in denen ein Endpunkt von außen zugĂ€nglich war und dies vergessen hat zu melden;
  • die Notwendigkeit beseitigt, alle Dienste bei jeder HinzufĂŒgung einer neuen Rolle oder Berechtigung zu aktualisieren;
  • darauf geachtet, dass neue Dienste einfach, sicher und schnell bleiben.

Ausgabe

Istio ermöglicht es den Teams, sich auf geschĂ€ftskritische Aufgaben zu konzentrieren, ohne den Diensten zusĂ€tzliche Kosten aufzuerlegen und sie in ihren «Micro»-Status zurĂŒckzubringen.

Der Artikel (in drei Teilen) bietet grundlegendes Wissen und eine praktische Anleitung fĂŒr den Einstieg in die Arbeit mit Istio in realen Projekten.

P.S. vom Übersetzer

Lesen Sie auch in unserem Blog:

Quelle: habr.com

60GB SSD 8Gb DDR4