Zurück zu Microservices mit Istio. Teil 3

Zurück zu Microservices mit Istio. Teil 3

Notiz. übersetzen: Der erste Teil In dieser Serie ging es darum, die Fähigkeiten von Istio kennenzulernen und sie in Aktion zu demonstrieren. zweite — fein abgestimmtes Routing und Netzwerkverkehrsmanagement. Kommen wir nun zum Thema Sicherheit: Um die damit verbundenen Grundfunktionen zu demonstrieren, verwendet der Autor den Identitätsdienst Auth0, andere Anbieter können jedoch auf ähnliche Weise konfiguriert werden.

Wir haben einen Kubernetes-Cluster eingerichtet, in dem wir Istio und eine Beispiel-Microservice-Anwendung, Sentiment Analysis, bereitgestellt haben, um die Fähigkeiten von Istio zu demonstrieren.

Mit Istio konnten wir unsere Dienste klein halten, da sie keine Ebenen wie Wiederholungen, Zeitüberschreitungen, Leistungsschalter, Ablaufverfolgung und Überwachung implementieren müssen. Darüber hinaus verwendeten wir fortschrittliche Test- und Bereitstellungstechniken: A/B-Tests, Spiegelung und Canary-Rollouts.

Zurück zu Microservices mit Istio. Teil 3

Im neuen Material befassen wir uns mit den letzten Ebenen auf dem Weg zum Geschäftswert: Authentifizierung und Autorisierung – und in Istio ist das ein wahres Vergnügen!

Authentifizierung und Autorisierung in Istio

Ich hätte nie gedacht, dass mich Authentifizierung und Autorisierung inspirieren würden. Was kann Istio aus technologischer Sicht bieten, um diese Themen für Sie unterhaltsam und vor allem inspirierend zu gestalten?

Die Antwort ist einfach: Istio verlagert die Verantwortung für diese Funktionen von Ihren Diensten auf den Envoy-Proxy. Wenn die Anfragen die Dienste erreichen, sind sie bereits authentifiziert und autorisiert, sodass Sie nur noch geschäftsrelevanten Code schreiben müssen.

Hört sich gut an? Werfen wir einen Blick hinein!

Authentifizierung mit Auth0

Als Server für das Identitäts- und Zugriffsmanagement werden wir Auth0 verwenden, das es als Testversion gibt, intuitiv zu bedienen ist und mir einfach gefällt. Die gleichen Prinzipien können jedoch auf alle anderen angewendet werden OpenID Connect-Implementierungen: KeyCloak, IdentityServer und viele andere.

Um zu beginnen, gehen Sie zu Auth0-Portal Erstellen Sie mit Ihrem Konto einen Mieter (Mandant – „Mandant“, logische Einheit der Isolation, weitere Einzelheiten finden Sie unter Dokumentation - ca. übersetzt) und geh zu Anwendungen > Standard-Appwählen Domain, wie im Screenshot unten gezeigt:

Zurück zu Microservices mit Istio. Teil 3

Geben Sie diese Domäne in der Datei an resource-manifests/istio/security/auth-policy.yaml (Quellcode):

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 einer solchen Ressource, Pilot (eine der drei grundlegenden Control Plane-Komponenten in Istio – ca. übersetzt) konfiguriert Envoy so, dass Anfragen authentifiziert werden, bevor sie an Dienste weitergeleitet werden: sa-web-app и sa-feedback. Gleichzeitig wird die Konfiguration nicht auf Service-Envoys angewendet sa-frontend, sodass wir das Frontend nicht authentifizieren können. Um die Richtlinie anzuwenden, führen Sie den folgenden Befehl aus:

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

Kehren Sie zur Seite zurück und stellen Sie eine Anfrage. Sie werden sehen, dass sie mit dem Status endet 401 Nicht autorisiert. Lassen Sie uns nun Frontend-Benutzer zur Authentifizierung mit Auth0 umleiten.

Authentifizieren von Anfragen mit Auth0

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

Zurück zu Microservices mit Istio. Teil 3

Die wichtigen Informationen hier sind Identifizieren, die wir später im Skript verwenden werden. Schreiben wir es so auf:

  • Publikum: {YOUR_AUDIENCE}

Die restlichen Details, die wir benötigen, finden Sie im Auth0-Portal im Abschnitt Anwendungen - wählen Anwendung testen (wird automatisch zusammen mit der API erstellt).

Hier werden wir schreiben:

  • Domain: {DEINE DOMAIN}
  • Kunden ID: {YOUR_CLIENT_ID}

Scrollen Sie zu Anwendung testen zum Textfeld Zulässige Rückruf-URLs (aufgelöste URLs für den Rückruf), in der wir die URL angeben, an die der Anruf nach Abschluss der Authentifizierung gesendet werden soll. In unserem Fall ist es:

http://{EXTERNAL_IP}/callback

Und für Zulässige Abmelde-URLs (erlaubte URLs zum Abmelden) hinzufügen:

http://{EXTERNAL_IP}/logout

Kommen wir zum Frontend.

Frontend-Update

Wechseln Sie zur Filiale auth0 Repository [istio-mastery]. In diesem Zweig wird der Frontend-Code geändert, um Benutzer zur Authentifizierung an Auth0 umzuleiten und das JWT-Token in Anfragen an andere Dienste zu verwenden. Letzteres wird wie folgt implementiert (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 so zu ändern, dass Mandantendaten in Auth0 verwendet werden, öffnen Sie sa-frontend/src/services/Auth.js und ersetzen Sie darin die Werte, die wir oben geschrieben haben (Auth.js):

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

Die Anwendung ist fertig. Geben Sie Ihre Docker-ID in den folgenden Befehlen an, wenn Sie die vorgenommenen Änderungen erstellen und bereitstellen:

$ 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

Probieren Sie die App aus! Sie werden zu Auth0 weitergeleitet, wo Sie sich anmelden (oder registrieren) müssen. Anschließend werden Sie zu der Seite zurückgeleitet, von der aus bereits authentifizierte Anfragen gestellt werden. Wenn Sie die in den ersten Teilen des Artikels genannten Befehle mit Curl ausprobieren, erhalten Sie den Code 401 Statuscode, was signalisiert, dass die Anfrage nicht autorisiert ist.

Machen wir den nächsten Schritt – Anfragen autorisieren.

Autorisierung mit Auth0

Durch die Authentifizierung können wir verstehen, wer ein Benutzer ist. Um zu wissen, worauf er Zugriff hat, ist jedoch eine Autorisierung erforderlich. Auch hierfür bietet Istio Tools an.

Als Beispiel erstellen wir zwei Benutzergruppen (siehe Diagramm unten):

  • Mitglieder (Benutzer) — mit Zugriff nur auf SA-WebApp- und SA-Frontend-Dienste;
  • Moderatoren (Moderatoren) — mit Zugang zu allen drei Diensten.

Zurück zu Microservices mit Istio. Teil 3
Berechtigungskonzept

Um diese Gruppen zu erstellen, verwenden wir die Auth0-Autorisierungserweiterung und verwenden Istio, um ihnen unterschiedliche Zugriffsebenen bereitzustellen.

Installation und Konfiguration der Auth0-Autorisierung

Gehen Sie im Auth0-Portal zu Erweiterungen (Erweiterungsoptionen) und installieren Auth0-Autorisierung. Gehen Sie nach der Installation zu Autorisierungserweiterungund dort zur Konfiguration des Mieters, indem Sie oben rechts klicken und den entsprechenden Menüpunkt auswählen (Aufbau). Gruppen aktivieren (Gruppen) und klicken Sie auf die Schaltfläche „Regel veröffentlichen“. (Veröffentlichungsregel).

Zurück zu Microservices mit Istio. Teil 3

Gruppen erstellen

Gehen Sie in Autorisierungserweiterung zu Groups und eine Gruppe erstellen Moderatoren. Da wir alle authentifizierten Benutzer als reguläre Benutzer behandeln, ist es nicht erforderlich, eine zusätzliche Gruppe für sie zu erstellen.

Wählen Sie eine Gruppe Moderatoren, Drücken Sie 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.)

Gruppenanspruch zum Zugriffstoken hinzufügen

Benutzer wurden zu Gruppen hinzugefügt, diese Informationen müssen sich jedoch auch in Zugriffstokens widerspiegeln. Um OpenID Connect zu entsprechen und gleichzeitig die von uns benötigten Gruppen zurückzugeben, muss dem Token eine eigene hinzugefügt werden kundenspezifischer Anspruch. Implementiert durch Auth0-Regeln.

Um eine Regel zu erstellen, gehen Sie zum Auth0-Portal Regeln, Drücken Sie Regel erstellen und wählen Sie eine leere Regel aus den Vorlagen aus.

Zurück zu Microservices mit Istio. Teil 3

Kopieren Sie den Code unten und speichern Sie ihn als neue Regel Gruppenanspruch hinzufügen (namespacedGroup.js):

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

Beachten: Dieser Code nimmt die erste in der Autorisierungserweiterung definierte Benutzergruppe und fügt sie dem Zugriffstoken als benutzerdefinierten Anspruch hinzu (unter seinem Namensraum, wie von Auth0 erforderlich).

Zurück zur Seite Regeln und überprüfen Sie, ob Sie zwei Regeln in der folgenden Reihenfolge geschrieben haben:

  • auth0-Autorisierungserweiterung
  • Gruppenanspruch hinzufügen

Die Reihenfolge ist wichtig, da das Gruppenfeld die Regel asynchron empfängt auth0-Autorisierungserweiterung und danach wird es durch die zweite Regel als Anspruch hinzugefügt. Das Ergebnis ist ein Zugriffstoken wie dieser:

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

Jetzt müssen Sie den Envoy-Proxy konfigurieren, um den Benutzerzugriff zu überprüfen, für den die Gruppe aus dem Anspruch gezogen wird (https://sa.io/group) im zurückgegebenen Zugriffstoken. Dies ist das Thema für den nächsten Abschnitt des Artikels.

Autorisierungskonfiguration in Istio

Damit die Autorisierung funktioniert, 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" 

Erklärung:

  • 1 – Aktivieren Sie RBAC nur für die im Feld aufgeführten Dienste und Namespaces Inclusion;
  • 2 – Wir listen eine Liste unserer Dienstleistungen auf.

Wenden wir die Konfiguration mit dem folgenden Befehl an:

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

Alle Dienste erfordern jetzt eine rollenbasierte Zugriffskontrolle. Mit anderen Worten: Der Zugriff auf alle Dienste ist verboten und führt zu einer Reaktion RBAC: access denied. Lassen Sie uns nun autorisierten Benutzern den Zugriff gewähren.

Zugriffskonfiguration für reguläre Benutzer

Alle Benutzer müssen Zugriff auf die Dienste SA-Frontend und SA-WebApp haben. Implementiert mit den folgenden Istio-Ressourcen:

  • ServiceRole — bestimmt die Rechte, die der Benutzer hat;
  • ServiceRoleBinding – bestimmt, wem diese ServiceRole gehört.

Für normale Benutzer ermöglichen 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 durch regular-user-binding ServiceRole auf alle Seitenbesucher anwenden (reguläre-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 Zugriff auf die SA WebApp haben? Nein, die Richtlinie prüft die Gültigkeit des JWT-Tokens.

Wenden wir die Konfigurationen an:

$ 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

Zugangskonfiguration für Moderatoren

Für Moderatoren möchten wir den Zugriff auf alle Dienste ermöglichen (mod-service-role.yaml):

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

Wir möchten solche Rechte jedoch nur für diejenigen Benutzer, deren Zugriffstoken einen Anspruch enthält https://sa.io/group mit Bedeutung 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" 

Wenden wir die Konfigurationen an:

$ 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

Aufgrund der Zwischenspeicherung in Envoys kann es einige Minuten dauern, bis die Autorisierungsregeln wirksam werden. Sie können dann sicherstellen, dass Benutzer und Moderatoren unterschiedliche Zugriffsebenen haben.

Fazit zu diesem Teil

Aber im Ernst: Haben Sie jemals einen einfacheren, müheloseren, skalierbaren und sicheren Ansatz zur Authentifizierung und Autorisierung gesehen?

Nur drei Istio-Ressourcen (RbacConfig, ServiceRole und ServiceRoleBinding) waren erforderlich, um eine detaillierte Kontrolle über die Authentifizierung und Autorisierung des Endbenutzerzugriffs auf Dienste zu erreichen.

Darüber hinaus haben wir uns im Rahmen unserer Gesandtschaftsdienste um diese Probleme gekümmert und Folgendes erreicht:

  • Reduzierung der Menge an generischem Code, der Sicherheitsprobleme und Fehler enthalten kann;
  • Reduzierung der dummen Situationen, in denen sich herausstellte, dass ein Endpunkt von außen zugänglich war und man vergaß, dies zu melden;
  • Es entfällt die Notwendigkeit, alle Dienste jedes Mal zu aktualisieren, wenn eine neue Rolle oder ein neues Recht hinzugefügt wird.
  • dass neue Dienste einfach, sicher und schnell bleiben.

Abschluss

Istio ermöglicht es Teams, ihre Ressourcen auf geschäftskritische Aufgaben zu konzentrieren, ohne den Mehraufwand für die Dienste zu erhöhen und diese auf den Mikrostatus zurückzusetzen.

Der Artikel (in drei Teilen) vermittelte grundlegendes Wissen und vorgefertigte praktische Anleitungen für den Einstieg in Istio in realen Projekten.

PS vom Übersetzer

Lesen Sie auch auf unserem Blog:

Source: habr.com

Kommentar hinzufügen