Gateway sichern

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

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

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

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

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

Hinweise

Führen Sie die folgenden Schritte durch, 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 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:

  • TLS-Konfigurationen mit einem SSL-Zertifikat auf Gateways werden von GKE-Version 1.28.4-gke.1083000 nicht unterstützt. Verwenden Sie als Umgehungslösung für diese GKE-Version ein Kubernetes-Secret.
  • 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.
  • Sie können nicht denselben Dienst als Backend für ein regionales und ein globales Gateway verwenden, wenn Sie in Ihrer GCPBackendPolicy auf eine Google Cloud Armor-Backend-Sicherheitsrichtlinie verweisen. Sie müssen für diesen Anwendungsfall zwei separate Dienste und Richtlinien erstellen.

  • 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.

Eine Liste der unterstützten Gateway API-Felder und Funktionen der GatewayClass-Ressourcen, die in GKE verfügbar sind, finden Sie unter GatewayClass-Funktionen.

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 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"
      # 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.

Load-Balancer zu Anwendungstraffic mit TLS sichern

Mit dem Feld ports[].appProtocol können Sie Traffic vom Load Balancer an Backend-Pods 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 in den Backend-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.

Backends 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.

Nächste Schritte