Gateway sichern


Auf dieser Seite wird erläutert, wie Sie ein Gateway mit verschiedenen Sicherheitsfunktionen sichern können:

  • SSL-Richtlinien, damit das Gateway die erforderlichen sicheren Protokolle und Algorithmen verwendet

  • Zertifikate zum Sichern von Client-zu-Gateway- und Gateway-zu-Backend-Traffic mit TLS

  • Sicherheitsrichtlinie von Google Cloud Armor zum Schutz von Diensten vor DDoS-Angriffen

  • Identity-Aware Proxy (IAP) bietet eine Authentifizierungs- und Autorisierungsebene, bevor der Zugriff auf einen Dienst zugelassen wird.

Weitere Informationen zur Sicherheit von Gateways finden Sie unter Gateway-Sicherheit.

Hinweise

Führen Sie die folgenden Aufgaben aus, bevor Sie beginnen:

  • Aktivieren Sie die Google Kubernetes Engine API.
  • Google Kubernetes Engine API aktivieren
  • Wenn Sie die Google Cloud CLI für diese Aufgabe verwenden möchten, müssen Sie die gcloud CLI installieren und dann initialisieren. Wenn Sie die gcloud CLI bereits installiert haben, rufen Sie die neueste Version mit gcloud components update ab.

Anforderungen für GKE Gateway Controller

  • Für Standard, GKE-Version 1.24 oder höher
  • Für Autopilot, GKE-Version 1.26 oder höher.
  • Google Cloud CLI-Version 407.0.0 oder höher.
  • Die Gateway API wird nur in VPC-nativen Clustern unterstützt.
  • Wenn Sie die internen GatewayClasses verwenden, müssen Sie ein Nur-Proxy-Subnetz aktivieren.
  • Für den Cluster muss das Add-on HttpLoadBalancing aktiviert sein.
  • Wenn Sie Istio verwenden, müssen Sie Istio auf eine der folgenden Versionen aktualisieren:
    • 1.15.2 oder höher
    • 1.14.5 oder höher
    • 1.13.9 oder höher
  • Wenn Sie eine freigegebene VPC verwenden, müssen Sie dem GKE-Dienstkonto für das Dienstprojekt im Hostprojekt die Rolle Compute Network User zuweisen.

Limits und Einschränkungen

Zusätzlich zu den Limits und Einschränkungen für GKE Gateway Controller gelten speziell für die Gateway-Sicherheit die folgenden Einschränkungen:

  • Sie können die Annotation networking.gke.io/certmap nicht mit einem tls.certificateRefs für dieselbe Gateway-Ressource verwenden. Wenn Sie in einem Gateway auf eine CertificateMap verweisen, behandelt GKE dies als Fehler.
  • Certificate Manager unterstützt sowohl selbstverwaltete als auch von Google verwaltete Zertifikate, ist jedoch nicht mit regionalen Gateways kompatibel.
  • Wenn Sie von Google verwaltete SSL-Zertifikate verwenden, müssen Sie die SSL-Zertifikate außerhalb von GKE erstellen, bevor Sie sie an das Gateway anhängen.

  • Von Google verwaltete SSL-Zertifikate sind nicht mit regionalen Gateways kompatibel. Weitere Informationen zu TLS-Terminierungsmethoden für jede GatewayClass finden Sie unter GatewayClass TLS-Unterstützung.

  • Der Gateway-Controller unterstützt die Ressource ManagedCertificate nicht.

  • Der Gateway-Controller unterstützt die Ressource networking.gke.io/managed-certificates nicht.

  • Das Feld appProtocol in der Dienstkonfiguration akzeptiert nur Großbuchstaben für den Protokollwert (HTTP, HTTPS oder HTTP2). Die Verwendung von Kleinbuchstaben führt zur Verwendung von HTTP als Protokoll mit den Back-Ends.

Gateway mit einem Kubernetes Secret sichern

In diesem Beispiel konfigurieren Sie ein Gateway mit einem Kubernetes-Secret.

Zertifikat in einem Kubernetes-Secret speichern

Sie können ein von Ihrer Zertifizierungsstelle ausgestelltes und validiertes Zertifikat verwenden oder ein selbst signiertes Zertifikat erstellen. In den folgenden Schritten wird ein selbst signiertes Zertifikat verwendet.

  1. Privaten Schlüssel erstellen

    openssl genrsa -out PRIVATE_KEY_FILE 2048
    

    Ersetzen Sie PRIVATE_KEY_FILE durch den Namen Ihrer privaten Schlüsseldatei, z. B. private-key.pem. Weitere Informationen finden Sie unter Privaten Schlüssel auswählen oder erstellen.

  2. Erstellen Sie eine OpenSSL-Konfigurationsdatei.

    cat <<EOF >CONFIG_FILE
    [req]
    default_bits              = 2048
    req_extensions            = extension_requirements
    distinguished_name        = dn_requirements
    prompt                    = no
    
    [extension_requirements]
    basicConstraints          = CA:FALSE
    keyUsage                  = nonRepudiation, digitalSignature, keyEncipherment
    subjectAltName            = @sans_list
    
    [dn_requirements]
    0.organizationName        = example
    commonName                = store.example.com
    
    [sans_list]
    DNS.1                     = store.example.com
    EOF
    

    Ersetzen Sie CONFIG_FILE durch den Namen der neuen Konfigurationsdatei, z. B. config-file.cnf.

  3. Erstellen Sie eine CSR-Datei:

    openssl req -new -key PRIVATE_KEY_FILE \
        -out CSR_FILE \
        -config CONFIG_FILE
    

    Ersetzen Sie CSR_FILE durch den Namen der neuen CSR-Datei, z. B. cert.pem. Weitere Informationen finden Sie unter CSR erstellen.

  4. CSR signieren:

    openssl x509 -req \
        -signkey PRIVATE_KEY_FILE \
        -in CSR_FILE \
        -out CERTIFICATE_FILE \
        -extfile CONFIG_FILE \
        -extensions extension_requirements \
        -days 30
    

    Ersetzen Sie CERTIFICATE_FILE durch den Pfad und den Namen der vom Befehl generierten Datei, z. B. cert-file.pem. Weitere Informationen finden Sie unter CSR signieren.

  5. Erstellen Sie mit dem erstellten Schlüssel und der Zertifikatsdatei ein Kubernetes TLS-Secret:

    kubectl create secret tls store-example-com \
        --cert=CERTIFICATE_FILE \
        --key=PRIVATE_KEY_FILE
    

    GKE speichert das Zertifikat und den Schlüssel als Kubernetes-Ressource, die Sie an Ihr Gateway anhängen können.

Gateway und HTTPRoute erstellen

  1. Speichern Sie das folgende Manifest als external-gateway.yaml:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: external-http
    spec:
      gatewayClassName: gke-l7-global-external-managed
      listeners:
      - name: https
        protocol: HTTPS
        port: 443
        tls:
          mode: Terminate
          certificateRefs:
          - name: store-example-com
    

    Dieses Manifest beschreibt ein Gateway mit folgenden Attributen:

    • gatewayClassName: gke-l7-global-external-managed: Stellt einen globalen externen Application Load Balancer bereit.
    • protocol: HTTPS und port: 443: Erforderlich, um TLS zu aktivieren.
    • tls: Verweist auf das im vorherigen Schritt erstellte Kubernetes-Secret.
  2. Wenden Sie das Manifest auf den Cluster an:

    kubectl apply -f external-gateway.yaml
    
  3. Speichern Sie das folgende Manifest als store-external-route.yaml:

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: store-external
      labels:
        gateway: external-http
    spec:
      parentRefs:
      - name: external-http
      hostnames:
      - "store.example.com"
      rules:
      - backendRefs:
        - name: store-v1
          port: 8080
    

    Dieses Manifest beschreibt eine HTTPRoute, die den Traffic mit store.example.com abgleicht und an den Dienst store-v1 sendet.

  4. Wenden Sie das Manifest auf den Cluster an:

    kubectl apply -f store-external-route.yaml
    

Gateway prüfen

Stellen Sie durch Senden einer Anfrage über das Internet sicher, dass das Gateway funktioniert.

  1. Rufen Sie die IP-Adresse des Gateways ab:

    kubectl get gateway external-http -o=jsonpath="{.status.addresses[0].value}"
    

    Die Ausgabe sieht etwa so aus:

    203.0.113.12
    

    Diese Ausgabe ist eine öffentliche IP-Adresse. Das bedeutet, dass jeder Client mit Internetzugriff eine Verbindung zu ihr herstellen kann.

  2. Greifen Sie mit curl auf die Domain des Gateways zu:

    curl https://store.example.com --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert CERTIFICATE_FILE -v
    

    Dabei gilt:

    • GATEWAY_IP_ADDRESS: die IP-Adresse des Gateway-Load-Balancers.
    • CERTIFICATE_FILE: die Zertifikatsdatei, die Sie generiert haben. Speichern Sie diese Datei auf dem Computer, mit dem Sie eine Verbindung zum Gateway herstellen. Das Zertifikat ist für die Authentifizierung des Gateways erforderlich, da das Gateway ein selbst signiertes Zertifikat verwendet.

    Die Option --resolve löst den Domainnamen in die IP-Adresse des Gateways auf. Dies ist erforderlich, da DNS für diese Domain nicht konfiguriert ist.

    Die Ausgabe sieht etwa so aus:

    ...
    * TLSv1.2 (OUT), TLS handshake, Client hello (1):
    * TLSv1.2 (IN), TLS handshake, Server hello (2):
    * TLSv1.2 (IN), TLS handshake, Certificate (11):
    * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    * TLSv1.2 (IN), TLS handshake, Server finished (14):
    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (OUT), TLS handshake, Finished (20):
    * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (IN), TLS handshake, Finished (20):
    * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
    * ALPN, server accepted to use h2
    * Server certificate:
    *  subject: O=example; CN=store.example.com
    *  start date: Apr 19 15:54:50 2021 GMT
    *  expire date: Apr 19 15:54:50 2022 GMT
    *  common name: store.example.com (matched)
    *  issuer: O=example; CN=store.example.com
    *  SSL certificate verify ok.
    ...
    {
      "cluster_name": "gw",
      "host_header": "store.example.com",
      "metadata": "store-v1",
      "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal",
      "pod_name": "store-v1-84b47c7f58-tj5mn",
      "pod_name_emoji": "😍",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-04-19T16:30:08"
      # Several lines of output omitted here.
    }
    

    Diese Ausgabe enthält einen erfolgreichen TLS-Handshake gefolgt von einer Antwort der Anwendung. Die TLS-Verbindung wird am Gateway beendet und die Anwendung antwortet sicher auf den Client.

Gateway mit einem SSL-Zertifikat schützen

In diesem Beispiel konfigurieren Sie ein Gateway mit einem von Google verwalteten SSL-Zertifikat.

SSL-Zertifikat erstellen

  1. Erstellen Sie eine von Google verwaltete globale SslCertificate-Ressource:

    gcloud compute ssl-certificates create store-example-com \
        --domains=store.example.com \
        --global
    

Gateway und HTTPRoute erstellen

  1. Speichern Sie das folgende Manifest als external-gateway.yaml:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: external-http
    spec:
      gatewayClassName: gke-l7-global-external-managed
      listeners:
      - name: https
        protocol: HTTPS
        port: 443
        tls:
          mode: Terminate
          options:
            networking.gke.io/pre-shared-certs: store-example-com
    

    Dieses Manifest beschreibt ein Gateway mit folgenden Attributen:

    • gatewayClassName: gke-l7-global-external-managed: Stellt einen globalen externen Application Load Balancer bereit.
    • protocol:HTTPS und port:443: Erforderlich, um TLS zu aktivieren.
    • tls.mode:Terminate: Beendet TLS mit Ihrem SSL-Zertifikat.
  2. Wenden Sie das Manifest auf Ihren Cluster an:

    kubectl apply -f external-gateway.yaml
    
  3. Speichern Sie das folgende HTTPRoute-Manifest als store-external-route.yaml:

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: store-external
      labels:
        gateway: external-http
    spec:
      parentRefs:
      - name: external-http
      hostnames:
      - "store.example.com"
      rules:
      - backendRefs:
        - name: store-v1
          port: 8080
    
  4. Stellen Sie die HTTPRoute in Ihrem Cluster bereit:

    kubectl apply -f store-external-route.yaml
    

    Es kann einige Minuten dauern, bis GKE das Gateway bereitgestellt hat.

Gateway prüfen

  1. Rufen Sie die IP-Adresse des Gateways ab:

    kubectl get gateway external-http -o=jsonpath="{.status.addresses[0].value}"
    

    Die Ausgabe sieht etwa so aus:

    203.0.113.12
    

    Diese Ausgabe ist eine öffentliche IP-Adresse. Das bedeutet, dass jeder Client mit Internetzugriff eine Verbindung zu ihr herstellen kann.

  2. Aktualisieren Sie einen A- oder AAAA-Eintrag, um Ihre Domain an die IP-Adresse des Gateways weiterzuleiten.

    Dieser Schritt ist nur erforderlich, wenn Sie ein von Google verwaltetes SSL-Zertifikat konfigurieren. Wenn Sie ein selbstverwaltetes Zertifikat konfigurieren, können Sie diesen Schritt überspringen.

    Nach der Aktualisierung der DNS-Einträge kann es bis zu zehn Minuten dauern, bis der Load-Balancer beginnt, das von Google verwaltete Zertifikat zu verwenden.

  3. Prüfen Sie mit curl, ob das Gateway funktioniert,. Senden Sie dazu eine Anfrage über das Internet:

    curl https://store.example.com -v
    

    Die Ausgabe sieht etwa so aus:

    ...
    * TLSv1.2 (OUT), TLS handshake, Client hello (1):
    * TLSv1.2 (IN), TLS handshake, Server hello (2):
    * TLSv1.2 (IN), TLS handshake, Certificate (11):
    * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    * TLSv1.2 (IN), TLS handshake, Server finished (14):
    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (OUT), TLS handshake, Finished (20):
    * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (IN), TLS handshake, Finished (20):
    * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
    * ALPN, server accepted to use h2
    * Server certificate:
    *  subject: O=example; CN=store.example.com
    *  start date: Apr 19 15:54:50 2021 GMT
    *  expire date: Apr 19 15:54:50 2022 GMT
    *  common name: store.example.com (matched)
    *  issuer: O=example; CN=store.example.com
    *  SSL certificate verify ok.
    ...
    {
      "cluster_name": "gw",
      "host_header": "store.example.com",
      "metadata": "store-v1",
      "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal",
      "pod_name": "store-v1-84b47c7f58-tj5mn",
      "pod_name_emoji": "😍",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-04-19T16:30:08",
      "zone": "us-west1-a"
    }
    

    Diese Ausgabe enthält einen erfolgreichen TLS-Handshake und eine Antwort von der Anwendung. TLS wird auf dem Gateway korrekt beendet und die Anwendung antwortet sicher auf den Client.

Gateway mit Certificate Manager sichern

In diesem Beispiel konfigurieren Sie ein Gateway mit dem Zertifikatsmanager.

CertificateMap erstellen

  1. Erstellen Sie ein CertificateMap:

    gcloud certificate-manager maps create store-example-com-map
    
  2. Laden Sie Ihr selbstverwaltetes Zertifikat und Ihren Schlüssel in ein Certificate:

    gcloud certificate-manager certificates create store-example-com-cert \
        --certificate-file="cert.pem" \
        --private-key-file="PRIVATE_KEY_FILE"
    
  3. Erstellen Sie einen CertificateMapEntry, der das Zertifikat CertificateMap zuweist:

    gcloud certificate-manager maps entries create store-example-com-map-entry \
        --map=store-example-com-map \
        --hostname=store.example.com \
        --certificates=store-example-com-cert
    

Gateway und HTTPRoute erstellen

  1. Speichern Sie das folgende Manifest als cert-map-gateway.yaml:

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1beta1
    metadata:
      name: external-http
      annotations:
        networking.gke.io/certmap: store-example-com-map
    spec:
      gatewayClassName: gke-l7-global-external-managed
      listeners:
      - name: https
        protocol: HTTPS
        port: 443
    

    Dieses Manifest beschreibt ein Gateway mit folgenden Attributen:

    • gatewayClassName: gke-l7-global-external-managed: Stellt einen globalen externen Application Load Balancer bereit.
    • protocol: HTTPS und port: 443: Erforderlich, um TLS zu aktivieren.

    Es gibt keinen TLS-Abschnitt, da TLS mit Certificate Manager über die Annotation networking.gke.io/certmap konfiguriert wird.

  2. Wenden Sie das Manifest auf den Cluster an:

    kubectl apply -f cert-map-gateway.yaml
    

    Es kann einige Minuten dauern, bis GKE das Gateway bereitgestellt hat.

  3. Speichern Sie das folgende Manifest als cert-map-http-route.yaml:

    apiVersion: gateway.networking.k8s.io/v1beta1
    kind: HTTPRoute
    metadata:
      name: foo
      namespace: default
    spec:
      parentRefs:
      - name: external-http
      hostnames:
      - foo.example.com
      rules:
      - matches:
        - path:
            value: /
        backendRefs:
        - name: foo-v1
          port: 8080
    
  4. Wenden Sie das Manifest auf den Cluster an:

    kubectl apply -f cert-map-http-route.yaml
    

Gateway prüfen

  1. Rufen Sie die IP-Adresse des Gateways ab:

    kubectl get gateway external-http -o=jsonpath="{.status.addresses[0].value}"
    

    Die Ausgabe sieht etwa so aus:

    203.0.113.12
    

    Diese Ausgabe ist eine öffentliche IP-Adresse. Das bedeutet, dass jeder Client mit Internetzugriff eine Verbindung zu ihr herstellen kann.

  2. Aktualisieren Sie einen A- oder AAAA-Eintrag, um Ihre Domain an die IP-Adresse des Gateways weiterzuleiten.

    Dieser Schritt ist nur erforderlich, wenn Sie ein von Google verwaltetes SSL-Zertifikat konfigurieren. Wenn Sie ein selbstverwaltetes Zertifikat konfigurieren, können Sie diesen Schritt überspringen.

    Nach der Aktualisierung der DNS-Einträge kann es bis zu zehn Minuten dauern, bis der Load-Balancer beginnt, das von Google verwaltete Zertifikat zu verwenden.

  3. Greifen Sie mit curl auf die Domain des Gateways zu:

    curl https://store.example.com -v
    

    Die Ausgabe sieht in etwa so aus:

    ...
    * TLSv1.2 (OUT), TLS handshake, Client hello (1):
    * TLSv1.2 (IN), TLS handshake, Server hello (2):
    * TLSv1.2 (IN), TLS handshake, Certificate (11):
    * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    * TLSv1.2 (IN), TLS handshake, Server finished (14):
    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (OUT), TLS handshake, Finished (20):
    * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (IN), TLS handshake, Finished (20):
    * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
    * ALPN, server accepted to use h2
    * Server certificate:
    *  subject: O=example; CN=store.example.com
    *  start date: Apr 19 15:54:50 2021 GMT
    *  expire date: Apr 19 15:54:50 2022 GMT
    *  common name: store.example.com (matched)
    *  issuer: O=example; CN=store.example.com
    *  SSL certificate verify ok.
    ...
    {
      "cluster_name": "gw",
      "host_header": "store.example.com",
      "metadata": "store-v1",
      "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal",
      "pod_name": "store-v1-84b47c7f58-tj5mn",
      "pod_name_emoji": "😍",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-04-19T16:30:08",
      "zone": "us-west1-a"
    }
    

    Diese Ausgabe enthält einen erfolgreichen TLS-Handshake und eine Antwort von der Anwendung. TLS wird auf dem Gateway korrekt beendet und die Anwendung antwortet sicher auf den Client.

Load-Balancer zu Anwendungstraffic mit TLS sichern

Sie können Traffic vom Load-Balancer zu Back-End-Pods mit dem Feld ports[].appProtocol verschlüsseln. Die unterstützten Felder für appProtocol sind: HTTP, HTTPS und HTTP2.

Das folgende Manifest beschreibt einen Dienst, der den Load-Balancer angibt, der HTTPS-Traffic für die Kommunikation mit den Backend-Pods verwenden muss:

apiVersion: v1
kind: Service
metadata:
  name: store-v2
spec:
  selector:
    app: store
    version: v2
  ports:
  - port: 8080
    targetPort: 8080
    appProtocol: HTTPS

Der Load-Balancer überprüft das von Backend-Pods verwendete Zertifikat nicht. Sie sind dafür verantwortlich, dass das auf den Back-End-Pods verwendete Zertifikat gültig ist.

Traffic vom Client zum Load-Balancer mithilfe von SSL-Richtlinien sichern

Wenn Ihre Anwendungen über ein externes Gateway, das HTTPS verwendet, verfügbar gemacht werden, müssen Sie die neuesten Protokolle verwenden oder die Mindestversion für SSL oder TLS anwenden. Sie können den Client-zu-Load-Balancer-Traffic mithilfe von SSL-Richtlinien sichern.

Weitere Informationen zu SSL-Richtlinien, die an Ihr Gateway angehängt werden können, und wie Sie diese erstellen, finden Sie unter SSL-Richtlinien konfigurieren, um Client-zu-Load-Balancer-Traffic zu sichern.

Back-Ends mit Google Cloud Armor schützen

Mit den Google Cloud Armor-Sicherheitsrichtlinien können Sie Ihre Anwendungen mit Load-Balancing vor Angriffen aus dem Web schützen. Wenn Sie eine Google Cloud Armor-Sicherheitsrichtlinie konfiguriert haben, können Sie in einer GCPBackendPolicy darauf verweisen, die auf Ihre Kubernetes-Dienste angewendet wird.

Informationen zum Konfigurieren von Google Cloud Armor-Richtlinien mit Gateway finden Sie unter Google Cloud Armor-Sicherheitsrichtlinie konfigurieren, um Ihre Backend-Dienste zu sichern.

Anfragen an Back-Ends mit Identity-Aware Proxy authentifizieren

Mit Identity-Aware Proxy können Sie Ihre Back-Ends vor unerwünschtem Traffic schützen. Dazu authentifizieren Sie Clients, die Anfragen an Ihre Anwendungen senden, und erzwingen die rollenbasierte Trafficautorisierung. Nachdem Sie Identity-Aware Proxy für GKE aktiviert haben, können Sie auf Ihre OAuth-Anmeldedaten in einer GCPBackendPolicy verweisen, die auf Ihre Kubernetes-Dienste angewendet wird.

Informationen zum Konfigurieren von Identity-Aware Proxy mit Gateway finden Sie unter Identity-Aware Proxy konfigurieren.

Nächste Schritte