Sichern Sie den eingehenden Datenverkehr mit der API-Implementierung des Gateways für Anwendungs-Routing.

Hinweis

In diesem Artikel wird beschrieben, wie Sie die TLS-Terminierung auf einer -Ressource Gateway konfigurieren, indem Sie Ihr eigenes SecretProviderClass erstellen, den Azure Key Vault-Anbieter für den Secrets Store CSI-Treiber über einen Beispiel-Pod einbinden und das resultierende Kubernetes-Secret direkt im GatewayListenercertificateRefs referenzieren. Dieser Ansatz ist nützlich, wenn Sie die vollständige Kontrolle über den Zertifikatsynchronisierungsworkflow benötigen oder diese Ressourcen selbst verwalten möchten.

Für die meisten Benutzer ist die empfohlene Vorgehensweise die automatisierte Integration von Azure DNS und Azure Key Vault durch den Application Routing Operator, der das SecretProviderClass, das synchronisierte Kubernetes Secret und den Listener certificateRefs für Sie basierend auf einem Paar von Listener-tls.options bereitstellt und abgleicht. Informationen zum Verwenden des automatisierten Workflows finden Sie unter Konfigurieren von Azure DNS und TLS mit der Gateway-API-Implementierung für Anwendungsrouting.

Das Anwendungsrouting-Add-On unterstützt die Synchronisierung geheimer Schlüssel aus Azure Key Vault (AKV) zum Sichern des Gateway-API-Eingangsdatenverkehrs mit TLS-Beendigung. Führen Sie die folgenden Schritte aus, um Zertifikate und Schlüssel zum Beenden des TLS-Datenverkehrs am Gateway zu erstellen.

Voraussetzungen

Erforderliche Client-/Serverzertifikate und Schlüssel

  1. Erstellen Sie ein Stammzertifikat und einen privaten Schlüssel zum Signieren der Zertifikate für Beispieldienste:
mkdir httpbin_certs
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout httpbin_certs/example.com.key -out httpbin_certs/example.com.crt
  1. Generieren Eines Zertifikats und eines privaten Schlüssels für httpbin.example.com:
openssl req -out httpbin_certs/httpbin.example.com.csr -newkey rsa:2048 -nodes -keyout httpbin_certs/httpbin.example.com.key -subj "/CN=httpbin.example.com/O=httpbin organization"
openssl x509 -req -sha256 -days 365 -CA httpbin_certs/example.com.crt -CAkey httpbin_certs/example.com.key -set_serial 0 -in httpbin_certs/httpbin.example.com.csr -out httpbin_certs/httpbin.example.com.crt

Konfigurieren eines TLS-Eingangsgateways

Einrichten von Azure Key Vault und Synchronisieren geheimer Schlüssel mit dem Cluster

  1. Azure Key Vault erstellen

    Sie benötigen eine Azure Key Vault-Ressource , um das Zertifikat und die Schlüsseleingaben für das Anwendungsrouting-Add-On zu liefern.

    export AKV_NAME=<azure-key-vault-resource-name>  
    az keyvault create --name $AKV_NAME --resource-group $RESOURCE_GROUP --location $LOCATION
    
  2. Aktivieren Sie das Add-On Azure Key Vault-Anbieter für den Geheimnisspeicher-CSI-Treiber in Ihrem Cluster.

    az aks enable-addons --addons azure-keyvault-secrets-provider --resource-group $RESOURCE_GROUP --name $CLUSTER
    
  3. Wenn Ihr Key Vault Azure RBAC für das Berechtigungsmodell verwendet, folgen Sie den Anweisungen hier, um der vom Benutzer zugewiesenen verwalteten Identität des Add-Ons die Azure-Rolle "Key Vault Secrets User" zuzuweisen. Wenn Ihr Schlüsseltresor das Berechtigungsmodell mit Tresorzugriffsrichtlinie verwendet, können Sie alternativ die vom Benutzer zugewiesene verwaltete Identität des Add-Ons zum Zugriff auf die Azure Key Vault-Ressource unter Verwendung der Zugriffsrichtlinie autorisieren:

    OBJECT_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER --query 'addonProfiles.azureKeyvaultSecretsProvider.identity.objectId' -o tsv | tr -d '\r')
    CLIENT_ID=$(az aks show --resource-group $RESOURCE_GROUP --name $CLUSTER --query 'addonProfiles.azureKeyvaultSecretsProvider.identity.clientId')
    TENANT_ID=$(az keyvault show --resource-group $RESOURCE_GROUP --name $AKV_NAME --query 'properties.tenantId')
    
    az keyvault set-policy --name $AKV_NAME --object-id $OBJECT_ID --secret-permissions get list
    
  4. Wählen Sie aus, wie das TLS-Zertifikat bereitgestellt werden soll.

    Azure Key Vault unterstützt verschiedene Objekttypen. Wählen Sie für diese exemplarische Vorgehensweise eine der folgenden End-to-End-Optionen aus, und fahren Sie dann mit den allgemeinen Überprüfungs- und Gatewayschritten fort.

    Option Verwenden Sie diese Option, wenn Key Vault speichert Kubernetes Geheimes Ergebnis
    Option 1: Zertifikat und Schlüssel als Geheimnisse in Key Vault speichern Sie verfügen über separate PEM-Zertifikatdateien (.crt) und private Schlüsseldateien (.key), z. B. die zuvor in diesem Artikel generierten Dateien. Zwei Key Vault-Geheimnisse. Ein synchronisierter Kubernetes TLS-Geheimschlüssel mit dem Namen httpbin-credential.
    Option 2: Direktes Verweisen auf ein Key Vault Zertifikatobjekt Ihr Zertifikat ist bereits in Key Vault als Zertifikatobjekt gespeichert, z. B. ein importiertes .pfxObjekt. Ein Key Vault Zertifikatobjekt. Ein synchronisierter Kubernetes TLS-Geheimschlüssel mit dem Namen httpbin-credential.

    Important

    Folgen Sie nicht beiden Optionen. Wenn Sie Option 1 verwenden, laden Sie die Zertifikats- und Schlüsseldateien als Key-Vault-Geheimnisse hoch und wenden Sie dann das Manifest für Option 1 SecretProviderClass an. Wenn Sie Option 2 verwenden, überspringen Sie den Key Vault geheimen Uploadschritt, und wenden Sie das Option 2-Manifest SecretProviderClass an.

Option 1: Speichern Sie das Zertifikat und den Schlüssel als Key Vault-Geheimnisse

Verwenden Sie diese Option, wenn Sie über separate PEM-Zertifikatdateien (.crt) und private Schlüsseldateien (.key) verfügen, z. B. die zuvor in diesem Artikel generierten Dateien.

  1. Laden Sie die Zertifikats- und Schlüsseldateien als Key-Vault-Geheimnisse hoch:

    az keyvault secret set --vault-name $AKV_NAME --name test-httpbin-key --file httpbin_certs/httpbin.example.com.key
    az keyvault secret set --vault-name $AKV_NAME --name test-httpbin-crt --file httpbin_certs/httpbin.example.com.crt
    

    Hinweis

    Jedes Mal, wenn Sie das Zertifikat oder den Schlüssel drehen (ändern), führen Sie diesen Schritt erneut aus, um die neuen Versionen als geheime Schlüssel hochzuladen. Um die aktualisierten Werte automatisch im Cluster zu synchronisieren, aktivieren Sie die Autorotation beim Azure Key Vault-Anbieter für den Secrets Store CSI Driver. Weitere Informationen finden Sie unter "Autorotation" und "Geheime Synchronisierung" (Übersicht). Wenn Sie lieber Key Vault den Zertifikatlebenszyklus verwalten möchten, verwenden Sie stattdessen Option 2.

  2. Erstellen Sie den SecretProviderClass-Verweis, der auf die beiden Geheimnisse verweist, die Sie in Key Vault erstellt haben:

    cat <<EOF | kubectl apply -f -
    apiVersion: secrets-store.csi.x-k8s.io/v1
    kind: SecretProviderClass
    metadata:
      name: httpbin-credential-spc
    spec:
      provider: azure
      secretObjects:
      - secretName: httpbin-credential
        type: kubernetes.io/tls
        data:
        - objectName: test-httpbin-key
          key: tls.key
        - objectName: test-httpbin-crt
          key: tls.crt
      parameters:
        useVMManagedIdentity: "true"
        userAssignedIdentityID: $CLIENT_ID 
        keyvaultName: $AKV_NAME
        cloudName: ""
        objects:  |
          array:
            - |
              objectName: test-httpbin-key
              objectType: secret
              objectAlias: "test-httpbin-key"
            - |
              objectName: test-httpbin-crt
              objectType: secret
              objectAlias: "test-httpbin-crt"
        tenantId: $TENANT_ID
    EOF
    

Option 2: Direktes Verweisen auf ein Key Vault Zertifikatobjekt

Verwenden Sie diese Option, wenn das Zertifikat bereits in Azure Key Vault als Zertifikatobjekt gespeichert ist. Sie brauchen die .crt- und .key-Dateien nicht als separate Key Vault-Secrets hochzuladen.

In diesem Beispiel test-httpbin-cert-pfx ist der Name des Zertifikatobjekts in Azure Key Vault. Informationen zum Importieren eines vorhandenen Zertifikats in Key Vault als Zertifikatobjekt finden Sie unter Importieren eines Zertifikats in Key Vault. Weitere Informationen zu den Objektparametern finden Sie unter Abrufen von Zertifikaten und Schlüsseln.

  1. Erstellen Sie das SecretProviderClass Objekt, das auf das Key Vault Zertifikatobjekt verweist:

    cat <<EOF | kubectl apply -f -
    apiVersion: secrets-store.csi.x-k8s.io/v1
    kind: SecretProviderClass
    metadata:
      name: httpbin-credential-spc
    spec:
      provider: azure
      secretObjects:
      - secretName: httpbin-credential
        type: kubernetes.io/tls
        data:
        - objectName: test-httpbin-key
          key: tls.key
        - objectName: test-httpbin-crt
          key: tls.crt
      parameters:
        useVMManagedIdentity: "true"
        userAssignedIdentityID: $CLIENT_ID 
        keyvaultName: $AKV_NAME
        cloudName: ""
        objects:  |
          array:
            - |
              objectName: test-httpbin-cert-pfx  #certificate object name from keyvault
              objectType: secret
              objectAlias: "test-httpbin-key"
            - |
              objectName: test-httpbin-cert-pfx #certificate object name from keyvault
              objectType: cert
              objectAlias: "test-httpbin-crt"
        tenantId: $TENANT_ID
    EOF
    

Synchronisieren des geheimen Schlüssels mit dem Cluster

Nachdem Sie option 1 oder Option 2 abgeschlossen haben, stellen Sie einen Beispiel-Pod bereit, um den geheimen Schlüssel mit dem Cluster zu synchronisieren. Der Secrets Store CSI-Treiber setzt voraus, dass ein Pod die Ressource SecretProviderClass referenziert, damit Geheimnisse von Azure Key Vault in den Cluster synchronisiert werden.

  1. Verwenden Sie das folgende Manifest, um einen Beispiel-Pod bereitzustellen:

    cat <<EOF | kubectl apply -f -
    apiVersion: v1
    kind: Pod
    metadata:
      name: secrets-store-sync-httpbin
    spec:
      containers:
        - name: busybox
          image: mcr.microsoft.com/oss/busybox/busybox:1.33.1
          command:
            - "/bin/sleep"
            - "10"
          volumeMounts:
          - name: secrets-store01-inline
            mountPath: "/mnt/secrets-store"
            readOnly: true
      volumes:
        - name: secrets-store01-inline
          csi:
            driver: secrets-store.csi.k8s.io
            readOnly: true
            volumeAttributes:
              secretProviderClass: "httpbin-credential-spc"
    EOF
    
    • Überprüfen Sie, ob das httpbin-credential Secret im default Namespace erstellt wurde, wie in der SecretProviderClass-Ressource definiert.

      kubectl describe secret/httpbin-credential
      

      Beispielausgabe:

      Name:         httpbin-credential
      Namespace:    default
      Labels:       secrets-store.csi.k8s.io/managed=true
      Annotations:  <none>
      
      Type:  kubernetes.io/tls
      
      Data
      ====
      tls.crt:  1180 bytes
      tls.key:  1675 bytes
      

Bereitstellen des TLS-Gateways

  1. Erstellen Sie ein Kubernetes-Gateway, das auf den httpbin-credential geheimen Schlüssel unter der TLS-Konfiguration verweist:

    cat <<EOF | kubectl apply -f -
    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: httpbin-gateway
    spec:
      gatewayClassName: approuting-istio
      listeners:
      - name: https
        hostname: "httpbin.example.com"
        port: 443
        protocol: HTTPS
        tls:
          mode: Terminate
          certificateRefs:
          - name: httpbin-credential
        allowedRoutes:
          namespaces:
            from: Selector
            selector:
              matchLabels:
                kubernetes.io/metadata.name: default
    EOF
    

    Erstellen Sie dann eine entsprechende HTTPRoute um die eingehenden Datenverkehrsrouten des Gateways zu konfigurieren:

    cat <<EOF | kubectl apply -f -
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: httpbin
    spec:
      parentRefs:
      - name: httpbin-gateway
      hostnames: ["httpbin.example.com"]
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /status
        - path:
            type: PathPrefix
            value: /delay
        backendRefs:
        - name: httpbin
          port: 8000
    EOF
    

    Rufen Sie die Gatewayadresse und den Port ab:

    kubectl wait --for=condition=programmed gateways.gateway.networking.k8s.io httpbin-gateway
    export INGRESS_HOST=$(kubectl get gateways.gateway.networking.k8s.io httpbin-gateway -o jsonpath='{.status.addresses[0].value}')
    export SECURE_INGRESS_PORT=$(kubectl get gateways.gateway.networking.k8s.io httpbin-gateway -o jsonpath='{.spec.listeners[?(@.name=="https")].port}')
    
  2. Senden Sie eine HTTPS-Anforderung für den Zugriff auf den httpbin Dienst:

    curl -v -HHost:httpbin.example.com --resolve "httpbin.example.com:$SECURE_INGRESS_PORT:$INGRESS_HOST" \
    --cacert httpbin_certs/example.com.crt "https://httpbin.example.com:$SECURE_INGRESS_PORT/status/418"
    

    Sie sollten sehen, dass der httpbin-Dienst den 418 I'm a Teapot Code zurückgibt.