Cloud Service Mesh tramite esempi: mTLS


In Cloud Service Mesh 1.5 e versioni successive, la funzionalità auto mutual TLS (auto mTLS) è abilitata per impostazione predefinita. Con auto mTLS, un proxy sidecar lato client rileva automaticamente se il server ha un sidecar. Il sidecar client invia mTLS ai workload con sidecar e invia testo non crittografato ai workload senza sidecar. Tieni presente, tuttavia, che i servizi accettano sia il traffico in testo non crittografato che mTLS. Quando inserisci proxy sidecar nei tuoi pod, ti consigliamo di configurare i servizi in modo che accettino solo il traffico mTLS.

Con Cloud Service Mesh, puoi applicare mTLS, al di fuori del codice dell'applicazione, applicando un singolo file YAML. Cloud Service Mesh ti offre la flessibilità di applicare una policy di autenticazione al mesh di servizi, a uno spazio dei nomi o a un singolo workload.

mTLS reciproca

Costi

In questo documento vengono utilizzati i seguenti componenti fatturabili di Google Cloud:

Per generare una stima dei costi in base all'utilizzo previsto, utilizza il calcolatore prezzi.

I nuovi utenti di Google Cloud potrebbero avere diritto a una prova senza costi.

Al termine di questo tutorial, puoi evitare costi continui eliminando le risorse che hai creato. Per ulteriori informazioni, vedi Pulizia.

Prima di iniziare

  • Verifica che la fatturazione sia attivata per il tuo progetto Cloud. Scopri come confermare che la fatturazione sia attivata per il tuo progetto.

  • Installa Cloud Service Mesh su un cluster GKE ed esegui il deployment di un gateway in entrata. Se devi configurare un cluster per questo tutorial, consulta la guida rapida di Cloud Service Mesh, che ti offre assistenza su quanto segue:

    • Creazione di un cluster GKE.
    • Provisioning di Cloud Service Mesh gestito.
    • Deployment di un gateway in entrata.
    • Deployment dell'applicazione di esempio Online Boutique dal repository anthos-service-mesh-packages, che è stato modificato rispetto al set originale di manifest nel repository microservices-demo. Seguendo le best practice, ogni servizio viene implementato in uno spazio dei nomi separato con un service account univoco.
  • Crea un pod TestCurl per inviare traffico in testo normale per i test.

      apiVersion: v1
      kind: Pod
      metadata:
        name: testcurl
        namespace: default
        annotations:
          sidecar.istio.io/inject: "false"
      spec:
        containers:
        - name: curl
          image: curlimages/curl
          command: ["sleep", "600"]
    

Accedere a Online Boutique

  1. Imposta il contesto attuale per kubectl sul cluster in cui hai eseguito il deployment di Online Boutique:

    gcloud container clusters get-credentials CLUSTER_NAME  \
        --project=PROJECT_ID \
        --zone=CLUSTER_LOCATION 
    
  2. Elenca i servizi nello spazio dei nomi frontend:

    kubectl get services -n frontend
    

    Tieni presente che frontend-external è un LoadBalancer e ha un indirizzo IP esterno. L'applicazione di esempio include un servizio che è un bilanciatore del carico in modo che possa essere distribuito su GKE senza Cloud Service Mesh.

  3. Visita l'applicazione nel browser utilizzando l'indirizzo IP esterno del servizio frontend-external:

    http://FRONTEND_EXTERNAL_IP/
    
  4. Cloud Service Mesh ti offre la possibilità di eseguire il deployment di un gateway in entrata. Puoi accedere a Online Boutique anche utilizzando l'indirizzo IP esterno del gateway in entrata. Ottieni l'IP esterno del gateway. Sostituisci i segnaposto con le seguenti informazioni:

    • GATEWAY_SERVICE_NAME: il nome del servizio del gateway in entrata. Se hai eseguito il deployment del gateway di esempio senza modifiche o se hai eseguito il deployment del gateway di ingresso predefinito, il nome è istio-ingressgateway.
    • GATEWAY_NAMESPACE: lo spazio dei nomi in cui hai eseguito il deployment del gateway in entrata. Se hai eseguito il deployment del gateway di ingresso predefinito, lo spazio dei nomi è istio-system.
    kubectl get service GATEWAY_NAME -n GATEWAY_NAMESPACE
    
  5. Apri un'altra scheda del browser e visita l'applicazione utilizzando l'indirizzo IP esterno del gateway in entrata:

    http://INGRESS_GATEWAY_EXTERNAL_IP/
    
  6. Esegui questo comando per eseguire il curl del servizio frontend con HTTP semplice da un altro pod. Poiché i servizi si trovano in spazi dei nomi diversi, devi eseguire il comando curl sul nome DNS del servizio frontend.

    kubectl debug --image istio/base --target istio-proxy -it \
      $(kubectl get pod -l app=productcatalogservice -n product-catalog -o jsonpath={.items..metadata.name}) \
      -n product-catalog -- \
      curl http://frontend.frontend.svc.cluster.local:80/ -o /dev/null -s -w '%{http_code}\n'
    

    La tua richiesta ha esito positivo con lo stato 200 perché, per impostazione predefinita, vengono accettati sia il traffico TLS sia quello in testo non crittografato.

Abilitare mutual TLS per spazio dei nomi

Applichi mTLS applicando una policy PeerAuthentication con kubectl.

  1. Salva la seguente policy di autenticazione come mtls-namespace.yaml.

    cat <<EOF > mtls-namespace.yaml
    apiVersion: "security.istio.io/v1beta1"
    kind: "PeerAuthentication"
    metadata:
      name: "namespace-policy"
    spec:
      mtls:
        mode: STRICT
    EOF
    

    La riga mode: STRICT nel file di configurazione YAML configura i servizi in modo che accettino solo mTLS. Per impostazione predefinita, mode è PERMISSIVE, che configura i servizi in modo che accettino sia testo non crittografato sia mTLS.

  2. Applica la policy di autenticazione per configurare tutti i servizi Online Boutique in modo che accettino solo mTLS:

    for ns in ad cart checkout currency email frontend loadgenerator \
         payment product-catalog recommendation shipping; do
    kubectl apply -n $ns -f mtls-namespace.yaml
    done
    

    Output previsto:

    peerauthentication.security.istio.io/namespace-policy created
    peerauthentication.security.istio.io/namespace-policy created
    peerauthentication.security.istio.io/namespace-policy created
    peerauthentication.security.istio.io/namespace-policy created
    peerauthentication.security.istio.io/namespace-policy created
    peerauthentication.security.istio.io/namespace-policy created
    peerauthentication.security.istio.io/namespace-policy created
    peerauthentication.security.istio.io/namespace-policy created
    peerauthentication.security.istio.io/namespace-policy created
    peerauthentication.security.istio.io/namespace-policy created
    peerauthentication.security.istio.io/namespace-policy created

  3. Vai alla scheda del browser che accede a Online Boutique utilizzando l'indirizzo IP esterno del servizio frontend-external:

    http://FRONTEND_EXTERNAL_IP/
    
  4. Aggiorna la pagina. Il browser mostra il seguente errore:

    Impossibile raggiungere il sito

    L'aggiornamento della pagina comporta l'invio di testo non crittografato al servizio frontend. A causa della policy di autenticazione STRICT, il proxy sidecar blocca la richiesta al servizio.

  5. Vai alla scheda del browser che accede a Online Boutique utilizzando l'indirizzo IP esterno di istio-ingressgateway e aggiorna la pagina, che viene visualizzata correttamente. Quando accedi a Online Boutique utilizzando il gateway in entrata, la richiesta segue il seguente percorso:

    mTLS reciproca

    Flusso di autenticazione mTLS:

    1. Il browser invia una richiesta HTTP in testo non crittografato al server.
    2. Il container proxy del gateway in entrata intercetta la richiesta.
    3. Il proxy del gateway in entrata esegue unTLS handshake con il proxy lato server (il servizio frontend in questo esempio). Questo handshake include uno scambio di certificati. Questi certificati vengono precaricati nei container proxy da Cloud Service Mesh.
    4. Il proxy del gateway in entrata esegue un controllo sicuro dei nomi sul certificato del server, verificando che un'identità autorizzata stia eseguendo il server.
    5. Il gateway in entrata e i proxy del server stabiliscono una connessione mutual TLS reciproca e il proxy del server inoltra la richiesta al container dell'applicazione server (il servizio frontend).
  6. Esegui questo comando per eseguire il curl del servizio frontend con HTTP semplice da un altro pod.

    kubectl exec testcurl -n default -- curl \
      http://frontend.frontend.svc.cluster.local:80/ -o /dev/null -s -w '%{http_code}\n'
    

    La tua richiesta non va a buon fine perché inviamo traffico in testo normale dal workload senza sidecar in cui viene applicata la norma STRICT peerAuthentication.

Trovare ed eliminare le policy di autenticazione

  1. Per un elenco di tutte le policy PeerAuthentication nel mesh di servizi:

    kubectl get peerauthentication --all-namespaces
    

    L'output è simile al seguente:

    NAMESPACE         NAME               MODE     AGE
    ad                namespace-policy   STRICT   17m
    cart              namespace-policy   STRICT   17m
    checkout          namespace-policy   STRICT   17m
    currency          namespace-policy   STRICT   17m
    email             namespace-policy   STRICT   17m
    frontend          namespace-policy   STRICT   17m
    loadgenerator     namespace-policy   STRICT   17m
    payment           namespace-policy   STRICT   17m
    product-catalog   namespace-policy   STRICT   17m
    recommendation    namespace-policy   STRICT   17m
    shipping          namespace-policy   STRICT   17m
    
  2. Elimina la policy di autenticazione da tutti gli spazi dei nomi di Online Boutique:

    for ns in ad cart checkout currency email frontend loadgenerator payment \
      product-catalog recommendation shipping; do
        kubectl delete peerauthentication -n $ns namespace-policy
    done;
    

    Output previsto:

    peerauthentication.security.istio.io "namespace-policy" deleted
    peerauthentication.security.istio.io "namespace-policy" deleted
    peerauthentication.security.istio.io "namespace-policy" deleted
    peerauthentication.security.istio.io "namespace-policy" deleted
    peerauthentication.security.istio.io "namespace-policy" deleted
    peerauthentication.security.istio.io "namespace-policy" deleted
    peerauthentication.security.istio.io "namespace-policy" deleted
    peerauthentication.security.istio.io "namespace-policy" deleted
    peerauthentication.security.istio.io "namespace-policy" deleted
    peerauthentication.security.istio.io "namespace-policy" deleted
    peerauthentication.security.istio.io "namespace-policy" deleted
    
  3. Accedi a Online Boutique utilizzando l'indirizzo IP esterno del servizio frontend-external e aggiorna la pagina. La pagina viene visualizzata come previsto.

  4. Esegui questo comando per eseguire il curl del servizio frontend con HTTP semplice da un altro pod.

    kubectl debug --image istio/base --target istio-proxy -it \
      $(kubectl get pod -l app=productcatalogservice -n product-catalog -o jsonpath={.items..metadata.name}) \
      -n product-catalog -- \
      curl http://frontend.frontend.svc.cluster.local:80/ -o /dev/null -s -w '%{http_code}\n'
    

    La tua richiesta ha esito positivo con lo stato 200 perché, per impostazione predefinita, vengono accettati sia il traffico TLS sia quello in testo non crittografato.

Se aggiorni la pagina nella Google Cloud console che mostra l'elenco Workload, ora viene visualizzato lo stato mTLS Permissive.

Abilitare mutual TLS per workload

Per impostare una policy PeerAuthentication per un workload specifico, devi configurare la sezione selector e specificare le etichette che corrispondono al workload desiderato. Tuttavia, Cloud Service Mesh non può aggregare le policy a livello di workload per il traffico mTLS in uscita verso un servizio. Per gestire questo comportamento, devi configurare una regola di destinazione.

  1. Applica una policy di autenticazione a un workload specifico. Nota come la policy seguente utilizza etichette e selettori per scegliere come target il deployment frontend specifico.

    cat <<EOF | kubectl apply -n frontend -f -
    apiVersion: "security.istio.io/v1beta1"
    kind: "PeerAuthentication"
    metadata:
      name: "frontend"
      namespace: "frontend"
    spec:
      selector:
        matchLabels:
          app: frontend
      mtls:
        mode: STRICT
    EOF
    

    Output previsto:

    peerauthentication.security.istio.io/frontend created
  2. Configura una regola di destinazione corrispondente.

    cat <<EOF | kubectl apply -n frontend -f -
    apiVersion: "networking.istio.io/v1alpha3"
    kind: "DestinationRule"
    metadata:
      name: "frontend"
    spec:
      host: "frontend.demo.svc.cluster.local"
      trafficPolicy:
        tls:
          mode: ISTIO_MUTUAL
    EOF
    

    Output previsto:

    destinationrule.networking.istio.io/frontend created
  3. Accedi a Online Boutique utilizzando l'indirizzo IP esterno del servizio frontend-external e aggiorna la pagina. La pagina non viene visualizzata perché frontend service è impostato su mTLS STRICT e il proxy sidecar blocca la richiesta.

  4. Esegui questo comando per eseguire il curl del servizio frontend con HTTP semplice da un altro pod.

    kubectl exec testcurl -n default -- curl \
      http://frontend.frontend.svc.cluster.local:80/ -o /dev/null -s -w '%{http_code}\n'
    

    La tua richiesta non va a buon fine perché inviamo traffico in testo normale dal workload senza sidecar in cui viene applicata la norma STRICT peerAuthentication.

  5. Elimina la policy di autenticazione:

    kubectl delete peerauthentication -n frontend frontend
    

    Output previsto:

    peerauthentication.security.istio.io "frontend" deleted
    
  6. Elimina la regola di destinazione:

    kubectl delete destinationrule -n frontend frontend
    

    Output previsto:

    destinationrule.networking.istio.io "frontend" deleted
    

Applicazione di mTLS a livello di mesh

Per impedire a tutti i servizi nel mesh di accettare il traffico in testo non crittografato, imposta una policy PeerAuthentication a livello di mesh con la modalità mTLS impostata su STRICT. La policy PeerAuthentication a livello di mesh non deve avere un selettore e deve essere applicata nello spazio dei nomi radice, istio-system. Quando esegui il deployment della policy, il control plane esegue automaticamente il provisioning dei certificati TLS in modo che i workload possano autenticarsi a vicenda.

  1. Applica mTLS a tutto il mesh:

    kubectl apply -f - <<EOF
    apiVersion: "security.istio.io/v1beta1"
    kind: "PeerAuthentication"
    metadata:
      name: "mesh-wide"
      namespace: "istio-system"
    spec:
      mtls:
        mode: STRICT
    EOF
    

    Output previsto:

    peerauthentication.security.istio.io/mesh-wide created

  2. Accedi a Online Boutique utilizzando l'indirizzo IP esterno del servizio frontend-external e aggiorna la pagina. La pagina non viene visualizzata.

  3. Esegui questo comando per eseguire il curl del servizio frontend con HTTP semplice da un altro pod.

    kubectl exec testcurl -n default -- curl \
      http://frontend.frontend.svc.cluster.local:80/ -o /dev/null -s -w '%{http_code}\n'
    

    La tua richiesta non va a buon fine perché inviamo traffico in testo normale dal workload senza sidecar in cui viene applicata la norma STRICT peerAuthentication.

  4. Elimina la policy mesh-wide:

    kubectl delete peerauthentication -n istio-system mesh-wide
    

    Output previsto:

    peerauthentication.security.istio.io "mesh-wide" deleted
    

Esegui la pulizia

Per evitare che al tuo account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo tutorial, elimina il progetto che contiene le risorse oppure mantieni il progetto ed elimina le singole risorse.

  • Se vuoi evitare addebiti aggiuntivi, elimina il cluster:

    gcloud container clusters delete  CLUSTER_NAME  \
        --project=PROJECT_ID \
        --zone=CLUSTER_LOCATION 
    
  • Se vuoi mantenere il cluster e rimuovere l'esempio Online Boutique:

    1. Elimina gli spazi dei nomi dell'applicazione:
    kubectl delete -f online-boutique/kubernetes-manifests/namespaces
    

    Output previsto:

    namespace "ad" deleted
    namespace "cart" deleted
    namespace "checkout" deleted
    namespace "currency" deleted
    namespace "email" deleted
    namespace "frontend" deleted
    namespace "loadgenerator" deleted
    namespace "payment" deleted
    namespace "product-catalog" deleted
    namespace "recommendation" deleted
    namespace "shipping" deleted
    
    1. Elimina le voci di servizio:
    kubectl delete -f online-boutique/istio-manifests/allow-egress-googleapis.yaml
    

    Output previsto:

    serviceentry.networking.istio.io "allow-egress-googleapis" deleted
    serviceentry.networking.istio.io "allow-egress-google-metadata" deleted
    

Passaggi successivi