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 Gateway-Ressource manuell 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. Erstellen Sie mithilfe der Zertifikate und der Schlüssel Geheimnisse in Azure Key Vault.

    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
    
  5. Verwenden Sie das folgende Manifest, um SecretProviderClass bereitzustellen, um für Azure Key Vault spezifische Parameter für den CSI-Treiber bereitzustellen.

    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
    

    Verwenden Sie alternativ das folgende Manifest, um direkt über Azure Key Vault auf einen Zertifikatobjekttyp zu verweisen, um SecretProviderClass bereitzustellen. In diesem Beispiel test-httpbin-cert-pfx ist der Name des Zertifikatobjekts in Azure Key Vault. Weitere Informationen finden Sie im Abschnitt zum Abrufen von Zertifikaten und Schlüsseln .

    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
    
  6. Verwenden Sie das folgende Manifest, um einen Beispielpod bereitzustellen. Der CSI-Treiber für den Geheimnisspeicher erfordert, dass ein Pod auf die SecretProviderClass-Ressource verweist, um die Synchronisierung der Geheimnisse von Azure Key Vault mit dem Cluster sicherzustellen.

    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.