Übersicht über Autorisierungsrichtlinien

Im Gegensatz zu einer monolithischen Anwendung, die an einem Ort ausgeführt werden kann, senden global verteilte Mikrodienstanwendungen Aufrufe über Netzwerkgrenzen hinweg. Dies bedeutet mehr Einstiegspunkte in Ihre Anwendungen und mehr Möglichkeiten für böswillige Angriffe. Da Kubernetes-Pods temporäre IP-Adressen haben, sind herkömmliche IP-basierte Firewallregeln nicht für den sicheren Zugriff zwischen Arbeitslasten geeignet. In einer Mikrodienstarchitektur ist ein neuer Sicherheitsansatz erforderlich. Cloud Service Mesh baut auf Sicherheitsfeatures wie Kubernetes-Dienstkonten und Istio-Sicherheitsrichtlinien auf und bietet noch mehr Funktionen zum Schutz Ihrer Anwendungen.

Auf dieser Seite erhalten Anwendungsoperatoren eine Übersicht über die benutzerdefinierte Ressource AuthorizationPolicy (CR). Mit Autorisierungsrichtlinien können Sie die Zugriffssteuerung für Arbeitslasten auf den Anwendungs- (L7) und Transport-Ebenen (L3/4) aktivieren. Sie konfigurieren Autorisierungsrichtlinien, um Berechtigungen festzulegen. Was darf dieser Dienst oder Nutzer tun?

Autorisierungsrichtlinien

Anfragen zwischen Diensten in Ihrem Mesh (und zwischen Endnutzern und Diensten) sind standardmäßig zulässig. Mit der AuthorizationPolicy-CR definieren Sie detaillierte Richtlinien für Ihre Arbeitslasten. Nachdem Sie die Autorisierungsrichtlinien angewendet haben, verteilt Cloud Service Mesh sie an die Sidecar-Proxys. Wenn Anfragen bei einer Arbeitslast eintreffen, prüft der Sidecar-Proxy die Autorisierungsrichtlinien, um festzustellen, ob die Anfrage zugelassen oder abgelehnt werden soll.

Richtlinienbereich

Eine Richtlinie kann auf das gesamte Service Mesh, auf einen Namespace oder auf eine einzelne Arbeitslast angewendet werden.

  • Geben Sie den Stamm-Namespace istio-system im Feld metadata:namespace an, um eine Mesh-netzwerkweite Richtlinie anzuwenden:

    apiVersion: "security.istio.io/v1beta1"
    kind: "AuthorizationPolicy"
    metadata:
      name: "mesh-wide"
      namespace: istio-system
    spec:
    ...
    
  • Geben Sie den Namespace im Feld metadata:namespace an, um eine Richtlinie auf einen Namespace anzuwenden:

    apiVersion: "security.istio.io/v1beta1"
    kind: "AuthorizationPolicy"
    metadata:
      name: "currencyservice"
      namespace: currencyservice
    spec:
    ...
    
  • Wenn Sie eine Richtlinie auf eine bestimmte Arbeitslast beschränken möchten, fügen Sie das Feld selector ein.

    apiVersion: "security.istio.io/v1beta1"
    kind: "AuthorizationPolicy"
    metadata:
      name: "frontend"
      namespace: demo
    spec:
      selector:
        matchLabels:
          app: frontend
       ...
    

Grundstruktur

Eine Autorisierungsrichtlinie enthält den Richtlinienbereich, einen action und eine Liste von rules:

  • Wie im vorherigen Abschnitt beschrieben, kann der Richtlinienbereich das gesamte Mesh-Netzwerk, ein Namespace oder eine bestimmte Arbeitslast sein. Wenn Sie ihn angeben, gibt das Feld selector das Ziel der Richtlinie an.

  • Das Feld action gibt an, ob die Anfrage den Status ALLOW oder DENY hat. Wenn Sie keine Aktion angeben, wird die Aktion standardmäßig auf ALLOW gesetzt. Aus Gründen der Übersichtlichkeit empfehlen wir, immer die Aktion anzugeben. Autorisierungsrichtlinien unterstützen auch Aktionen vom Typ AUDIT und CUSTOM.

  • In rules wird angegeben, wann die Aktion ausgelöst werden soll.

    • Das Feld from in rules gibt die Quellen der Anfrage an.

    • Das Feld to in rules gibt die Vorgänge der Anfrage an.

    • Das Feld when gibt zusätzliche Bedingungen an, die zum Anwenden der Regel erforderlich sind.

Im folgenden Beispiel gilt:

  • Die Richtlinie wird auf Anfragen an den Dienst frontend im Namespace demo angewendet.

  • Anfragen werden zugelassen, wenn sich „hello:world“ im Anfrage-Header befindet. Andernfalls werden Anfragen abgelehnt.

apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
  name: "hello-world"
  namespace: demo
spec:
  selector:
    matchLabels:
      app: frontend
  action: ALLOW
  rules:
  - when:
    - key: request.headers[hello]
      values: ["world"]

Zugriffssteuerung für Anfragevorgang

Sie können den Zugriff auf bestimmte Anfragevorgänge wie HTTP-Methoden oder TCP-Ports steuern, indem Sie unter rules den Abschnitt to hinzufügen. Im folgenden Beispiel sind nur die HTTP-Methoden GET und POST für currencyservice im Namespace demo zulässig.

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: currencyservice
 namespace: demo
spec:
 selector:
   matchLabels:
     app: currencyservice
 action: ALLOW
 rules:
 - to:
   - operation:
       methods: ["GET", "POST"]

Zugriffssteuerung für authentifizierte Identität

In den vorherigen Beispielen lassen die Richtlinien Anfragen von nicht authentifizierten Arbeitslasten zu. Wenn das gegenseitige STRICT TLS (mTLS) aktiviert ist, können Sie den Zugriff anhand der Identität der anfragenden Arbeitslast oder des anfragenden Namespace im Abschnitt source einschränken.

  • Verwenden Sie das Feld principals oder notPrincipal, um den Zugriff auf Arbeitslastebene zu steuern.

  • Verwenden Sie das Feld namespaces oder notNamespaces, um den Zugriff auf Namespcae-Ebene zu steuern.

Für alle obigen Felder muss STRICT mTLS aktiviert sein. Wenn Sie STRICT mTLS nicht festlegen können, finden Sie unter Klartextanfragen ablehnen eine alternative Lösung.

Identifizierte Arbeitslast

Im folgenden Beispiel sind Anfragen an currencyservice nur vom Dienst frontend zulässig. Anfragen an currencyservice von anderen Arbeitslasten werden abgelehnt.

apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
  name: "currencyservice"
  namespace: demo
spec:
  selector:
    matchLabels:
      app: currencyservice
  action: ALLOW
  rules:
  - from:
    - source:
        principals: ["example-project-1234.svc.id.goog/ns/demo/sa/frontend-sa"]

Zum Angeben eines Dienstkontos müssen die principals für die Cloud Service Mesh-Zertifizierungsstelle (Mesh CA) und für Certificate Authority Service (CA Service) folgendes Format haben:

principals: ["PROJECT_ID.svc.id.goog/ns/NAMESPACE/sa/SERVICE_ACCOUNT_NAME"]

PROJECT_ID.svc.id.goog ist die Vertrauensdomain für Mesh CA. Wenn Sie die Istio-Zertifizierungsstelle (ehemals Citadel) verwenden, lautet die Standardvertrauensdomain cluster.local.

Identifizierter Namespace

Das folgende Beispiel zeigt eine Richtlinie, die Anfragen ablehnt, wenn die Quelle nicht der Namespace foo ist:

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: httpbin-deny
 namespace: foo
spec:
 selector:
   matchLabels:
     app: httpbin
     version: v1
 action: DENY
 rules:
 - from:
   - source:
       notNamespaces: ["foo"]

Werteabgleich

Die meisten Felder in Autorisierungsrichtlinien unterstützen alle folgenden Abgleichschemen:

  • Exakte Übereinstimmung: Exakte Übereinstimmung des Strings.
  • Platzhalterübereinstimmung mit dem Platzhalterzeichen "*":
    • Präfixübereinstimmung: Ein String mit der abschließenden Zeichenfolge "*". Beispielsweise führt "test.example.*" zu Übereinstimmungen mit "test.example.com" oder "test.example.com.cn".
    • Suffix-Übereinstimmung: Ein String mit einer anfänglichen Zeichenfolge "*". Beispielsweise führt "*.example.com" zu Übereinstimmungen mit "eng.example.com" oder "test.eng.example.com".
  • Präsenzübereinstimmung: Verwenden Sie das Format fieldname: ["*"], um anzugeben, dass ein Feld vorhanden sein muss und nicht leer sein darf. Dies unterscheidet sich davon, ein Feld unspezifiziert zu lassen, was bedeutet, dass es mit allem übereinstimmt, einschließlich „leer“.

Es gibt jedoch einige Ausnahmen. Die folgenden Felder unterstützen beispielsweise nur die genaue Übereinstimmung:

  • Das Feld key im Abschnitt when
  • Das Feld ipBlocks im Abschnitt source
  • Das Feld ports im Abschnitt to

Die folgende Beispielrichtlinie lässt den Zugriff auf Pfade mit dem Präfix /test/* oder dem Suffix */info zu:

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: tester
  namespace: default
spec:
  selector:
    matchLabels:
      app: products
  action: ALLOW
  rules:
  - to:
    - operation:
        paths: ["/test/*", "*/info"]

Ausschlussabgleich

Zum Abgleichen negativer Bedingungen wie notValues im Feld when, notIpBlocks im Feld source, notPorts im Feld to, unterstützt Cloud Service Mesh den Ausschlussabgleich. Im folgenden Beispiel ist eine gültige Anfrage principals erforderlich, die von der JWT-Authentifizierung abgeleitet wurde, wenn der Anfragepfad nicht /healthz ist. Daher schließt die Richtlinie Anfragen an den Pfad /healthz von der JWT-Authentifizierung aus:

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: disable-jwt-for-healthz
  namespace: default
spec:
  selector:
    matchLabels:
      app: products
  action: ALLOW
  rules:
  - to:
    - operation:
        notPaths: ["/healthz"]
    from:
    - source:
        requestPrincipals: ["*"]

Klartext-Anfragen ablehnen

In Cloud Service Mesh 1.5 und höher ist automatisches mTLS standardmäßig aktiviert. Bei „automTLS“ erkennt ein Client-Sidecar-Proxy automatisch, ob der Server einen Sidecar hat. An Arbeitslasten mit Sidecars sendet der Client-Sidecar-Proxy mTLS und an Arbeitslasten ohne Sidecars sendet er Nur-Text-Traffic. Für die beste Sicherheit wird empfohlen, STRICT mTLS zu aktivieren.

Wenn Sie mTLS nicht mit dem Modus STRICT für eine Arbeitslast oder einen Namespace aktivieren können, haben Sie folgende Möglichkeiten:

  • Erstellen Sie eine Autorisierungsrichtlinie, um Traffic mit nicht leeren namespaces oder nicht leeren principals explizit zuzulassen, oder
  • lehnen Sie Traffic mit leeren namespaces oder principals ab.

Da namespaces und principals nur mit einer mTLS-Anfrage extrahiert werden können, wird Klartext-Traffic durch diese Richtlinien quasi abgelehnt.

Die folgende Richtlinie lehnt die Anfrage ab, wenn das Hauptkonto in der Anfrage leer ist (trifft auf Klartext-Anfragen zu). Die Richtlinie lässt Anfragen zu, wenn das Hauptkonto nicht leer ist. ["*"] bedeutet, dass es sich um eine nicht leere Übereinstimmung handelt. Die Verwendung von notPrincipals bedeutet eine Übereinstimmung auf leerem Hauptkonto.

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: require-mtls
  namespace: NAMESPACE
spec:
  action: DENY
  rules:
  - from:
    - source:
        notPrincipals: ["*"]

Vorrang der Autorisierungsrichtlinie

Sie können separate ALLOW- und DENY-Autorisierungsrichtlinien konfigurieren. Dazu müssen Sie jedoch die Richtlinienpriorität und das Standardverhalten verstehen, damit die Richtlinien das tun, was Sie möchten. Im folgenden Diagramm wird die Priorisierung der Richtlinien beschrieben.

Vorrang der Autorisierungsrichtlinie

Die Beispielrichtlinien in den folgenden Abschnitten veranschaulichen einige Standardverhalten und die Situationen, in denen sie für Sie nützlich sein könnten.

Nichts zulassen

Das folgende Beispiel zeigt eine ALLOW-Richtlinie, die nichts zulässt. Wenn keine anderen ALLOW-Richtlinien vorhanden sind, werden Anfragen grundsätzlich abgelehnt.

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: allow-nothing
spec:
  action: ALLOW

Es empfiehlt sich, mit der Richtlinie „Allow-Nothing“ zu beginnen und schrittweise weitere ALLOW-Richtlinien hinzuzufügen, um zusätzlichen Zugriff auf eine Arbeitslast zu ermöglichen.

Gesamten Zugriff verweigern

Das folgende Beispiel zeigt eine DENY-Richtlinie, die alles ablehnt. Da DENY-Richtlinien vor ALLOW-Richtlinien ausgewertet werden, werden alle Anfragen auch dann abgelehnt, wenn eine ALLOW-Richtlinie die Anfrage zulässt.

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: deny-all
spec:
  action: DENY
  rules:
  - {}

Eine Deny-All-Richtlinie ist nützlich, wenn Sie den gesamten Zugriff auf eine Arbeitslast vorübergehend deaktivieren möchten.

Gesamten Zugriff zulassen

Das folgende Beispiel zeigt eine ALLOW-Richtlinie, die alles abgleicht und den vollständigen Zugriff auf eine Arbeitslast ermöglicht. Die Richtlinie "Allow-All" macht andere ALLOW-Richtlinien nutzlos, da die Anfrage immer zugelassen wird.

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: allow-all
spec:
  action: ALLOW
  rules:
  - {}

Eine Richtlinie "Alles zulassen" ist nützlich, wenn Sie vorübergehend den vollständigen Zugriff auf eine Arbeitslast verfügbar machen möchten. Wenn DENY-Richtlinien vorhanden sind, können Anfragen weiterhin abgelehnt werden, da DENY-Richtlinien vor ALLOW-Richtlinien ausgewertet werden.

Best Practices

  1. Erstellen Sie ein Kubernetes-Dienstkonto für jeden Dienst und geben Sie das Dienstkonto im Deployment an. Beispiel:

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: frontend-sa
      namespace: demo
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: frontend
      namespace:demo
    spec:
      selector:
        matchLabels:
          app: frontend
      template:
        metadata:
          labels:
            app: frontend
        spec:
          serviceAccountName: frontend-sa
        ...
    
  2. Beginnen Sie mit einer Richtlinie, die nichts zulässt, und fügen Sie schrittweise weitere ALLOW-Richtlinien hinzu, um den Zugriff auf Arbeitslasten zu erweitern.

  3. Wenn Sie JWTs für Ihren Dienst verwenden:

    1. Erstellen Sie eine DENY-Richtlinie, um nicht authentifizierte Anfragen zu blockieren. Beispiel:

      apiVersion: security.istio.io/v1beta1
      kind: AuthorizationPolicy
      metadata:
        name: requireJWT
        namespace: admin
      spec:
        action: DENY
        rules:
        -  from:
          - source:
              notRequestPrincipals: ["*"]
      
    2. Wenden Sie eine "Allow-Nothing"-Richtlinie an.

    3. Definieren Sie ALLOW-Richtlinien für jede Arbeitslast. Beispiele finden Sie unter JWT-Token.

Nächste Schritte

Weitere Informationen zu den Sicherheitsfunktionen von Cloud Service Mesh:

Weitere Informationen zu Autorisierungsrichtlinien finden Sie in der Istio-Dokumentation: