Integrazione di IAP con Cloud Service Mesh

Questa guida descrive come integrare Identity-Aware Proxy (IAP) con Cloud Service Mesh. La Integrazione IAP con Cloud Service Mesh ti consente di accedere in sicurezza ai servizi basati sulla principi di BeyondCorp. IAP verifica l'identità dell'utente e il contesto della richiesta per determinare se un utente può essere autorizzato ad accedere a un'applicazione o una risorsa. Integrazione di IAP con Cloud Service Mesh offre i seguenti vantaggi:

  • Completa il controllo dell'accesso sensibile al contesto al in esecuzione su Cloud Service Mesh. Puoi impostare livelli criteri di accesso in base agli attributi della richiesta di origine, come l'identità dell'utente e l'IP indirizzo e tipo di dispositivo. Puoi combinare i criteri di accesso con limitazioni basate nome host e percorso di un URL di richiesta.

  • Attiva il supporto per le attestazioni sensibili al contesto nell'autorizzazione Cloud Service Mesh.

  • Accesso scalabile, sicuro e ad alta disponibilità alla tua applicazione tramite un con il bilanciatore del carico di Google Cloud. Il bilanciamento del carico ad alte prestazioni offre degli attacchi DDoS (Distributed Denial-of-Service) e del supporto indirizzi IP anycast globali.

Prerequisiti

Segui i passaggi descritti in Installare gli strumenti dipendenti e convalidare il cluster a:

Inoltre, questa guida presuppone che tu abbia:

Configurazione di un cluster con Cloud Service Mesh

Questa sezione spiega come eseguire la configurazione per l'integrazione di IAP. sia per le nuove installazioni di Cloud Service Mesh sia per gli upgrade.

Nuove installazioni

  1. Attiva iap.googleapis.com. Nel comando seguente, sostituisci PROJECT_IDcon il progetto che installerai Cloud Service Mesh in:

    gcloud services enable \
      --project=PROJECT_ID \
      iap.googleapis.com
    
  2. Il cluster che stai aggiornando deve avere l'oggetto --addons=HttpLoadBalancing insieme di opzioni. Il componente aggiuntivo HttpLoadBalancing abilita un carico HTTP (L7) di bilanciamento del carico per il cluster. Esegui questo comando per aggiornare il cluster con le opzioni richieste da Cloud Service Mesh. A meno che tu non abbia devi impostare una zona o una regione predefinite, devi fornire la regione (--region=REGION) o zona (--zone=ZONE) nel comando.

    gcloud container clusters update CLUSTER_NAME \
      --project=PROJECT_ID \
      --update-addons=HttpLoadBalancing=ENABLED
    
  3. Per impostazione predefinita, il file iap-operator.yaml ha la porta 31223 impostata come stato e la porta 31224 impostata come porta HTTP. Se la porta 31223 è già in uso nel cluster, esegui questo comando per impostare un'altra porta di stato:

    kpt cfg set asm gcloud.container.cluster.ingress.statusPort STATUS_PORT
    

    Se la porta 31224 è già in uso nel cluster, esegui questo comando per impostare un'altra porta http:

    kpt cfg set asm gcloud.container.cluster.ingress.httpPort HTTP_PORT
    
  4. Segui i passaggi in Installare le funzionalità predefinite e Mesh CA per utilizzare uno script fornito da Google per installare Cloud Service Mesh. Quando esegui il comando includi la seguente opzione:

    --option iap-operator
    

    Ad esempio:

    ./asmcli install \
      --project_id "PROJECT_ID" \
      --cluster_name "CLUSTER_NAME" \
      --cluster_location "CLUSTER_LOCATION" \
      --fleet_id FLEET_PROJECT_ID \
      --output_dir DIR_PATH \
      --enable_all \
      --option iap-operator
    

    Quando installi Cloud Service Mesh, iap-operator.yaml imposta il campo type del servizio istio-ingressgateway su NodePort, che configura il gateway in modo che apra una porta specifica sul mesh di servizi. Ciò ti permette di configurare un bilanciatore del carico, che instrada traffico inviato al tuo nome di dominio a questa porta.

  5. Se installi Cloud Service Mesh gestito, completa anche seguenti passaggi:

    1. Aggiungere l'etichetta di revisione allo spazio dei nomi istio-system.

    2. Scarica il Specifiche del servizio Istio Ingress Gateway per IAP e assegnagli il nome iap_operator.yaml.

    3. Installa Ingress come servizio NodePort. Per ulteriori informazioni, vedi Esegui la migrazione da IstioOperator.

      asmcli experimental mcp-migrate-check -f iap_operator.yaml
      
      istioctl install -f /asm-generated-configs/gateways-istiooperator/"GATEWAY_NAME".yaml
      

Dopo aver installato Cloud Service Mesh, torna a questa guida e continua con il sezione successiva per configurare l'integrazione con IAP.

Upgrade

Questa sezione riguarda i seguenti casi d'uso di upgrade:

  • Hai già configurato l'integrazione IAP e stai eseguendo l'upgrade di Cloud Service Mesh. In questo caso, hai già attivato iap.googleapis.com del progetto e il componente aggiuntivo HttpLoadBalancing sul tuo cluster. Vai al passaggio 3 per scaricare il pacchetto asm e eseguire l'upgrade di Cloud Service Mesh.

  • Stai eseguendo l'upgrade di Cloud Service Mesh e vuoi configurare l'integrazione con IAP per la prima volta. In questo caso, devi completare tutti i passaggi seguenti, esegui l'upgrade di Cloud Service Mesh e torna a questa guida dopo l'upgrade per completare l'integrazione.

  1. Attiva iap.googleapis.com. Nel comando seguente, sostituisci PROJECT_IDcon il progetto che installerai Cloud Service Mesh.

    gcloud services enable \
      --project=PROJECT_ID \
      iap.googleapis.com
    
  2. Il cluster che stai aggiornando deve avere l'oggetto --addons=HttpLoadBalancing insieme di opzioni. Il componente aggiuntivo HttpLoadBalancing abilita un carico HTTP (L7) di bilanciamento del carico per il cluster. Esegui questo comando per aggiornare il cluster con le opzioni richieste da Cloud Service Mesh. A meno che tu non abbia devi impostare una zona o una regione predefinite, devi fornire la regione (--region=REGION) o zona (--zone=ZONE) nel comando.

    gcloud container clusters update CLUSTER_NAME \
      --project=PROJECT_ID
      --update-addons=HttpLoadBalancing=ENABLED
    
  3. Se stai aggiornando un bilanciatore del carico HTTP Cloud funzionante esistente, esegui procedi come segue per conservare le porte HTTP e di stato esistenti:

    kpt cfg set asm gcloud.container.cluster.ingress.httpPort $(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
    
    kpt cfg set asm gcloud.container.cluster.ingress.statusPort $(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="status-port")].nodePort}')
    
  4. Segui i passaggi in Upgrade di Cloud Service Mesh per utilizzare uno script fornito da Google per eseguire l'upgrade di Cloud Service Mesh.

    Quando esegui l'upgrade di Cloud Service Mesh, il file iap-operator.yaml imposta la type sul servizio istio-ingressgateway per NodePort, che configura il gateway in modo che apra una porta specifica sul mesh di servizi. Questo ti permette di configurare un bilanciatore del carico, che instrada il traffico inviato al tuo a questa porta.

    Per impostazione predefinita, il file iap-operator.yaml ha la porta 31223 impostata come stato e la porta 31224 impostata come porta HTTP.

    Quando esegui lo script, includi la seguente opzione:

    --option iap-operator
    

    Ad esempio:

    ./asmcli install \
      --project_id "PROJECT_ID" \
      --cluster_name "CLUSTER_NAME" \
      --cluster_location "CLUSTER_LOCATION" \
      --fleet_id FLEET_PROJECT_ID \
      --output_dir DIR_PATH \
      --enable_all \
      --option iap-operator
    
  5. Completa l'upgrade attivando l'inserimento automatico del proxy sidecar su per i carichi di lavoro. Per maggiori dettagli, vedi Deployment e rideployment dei carichi di lavoro.

    Una volta completato l'upgrade, torna a questa guida e continua con i sezione successiva per configurare l'integrazione con IAP.

Prenotazione di un indirizzo IP statico e configurazione del DNS

Per integrare Identity-Aware Proxy con Cloud Service Mesh, devi configurare un Bilanciatore del carico HTTP(S) di Google Cloud, che richiede un nome di dominio che punti a un indirizzo IP statico. Puoi riservare un indirizzo IP esterno statico, che assegna l'indirizzo al tuo progetto a tempo indeterminato finché non esplicitamente rilascialo.

  1. Prenota un indirizzo IP esterno statico:

    gcloud compute addresses create example-static-ip --global
    
  2. Ottieni l'indirizzo IP statico:

    gcloud compute addresses describe example-static-ip --global
    
  3. Configura un nome di dominio completo nel tuo registrar dei nomi di dominio. (FQDN) con l'indirizzo IP statico. In genere, aggiungi un record A al tuo Impostazioni DNS. I passaggi di configurazione e la terminologia per aggiungere un A per un nome di dominio completo variano a seconda del registrar dei nomi di dominio.

    La propagazione dell'impostazione DNS può richiedere da 24 a 48 ore. Puoi configurare tutti gli elementi di questa guida, ma non potrai e testarla finché le impostazioni DNS non si propagano.

Deployment di un'applicazione di esempio

Prima di abilitare IAP, è necessaria un'applicazione in esecuzione del tuo cluster GKE, in modo da poter verificare che tutte le richieste abbiano e identità di base. Questa guida utilizza l'esempio di Bookinfo per dimostrare come configurare il il bilanciatore del carico HTTP(S) e abilitare IAP.

Segui i passaggi per eseguire il deployment di Bookinfo. Fino al giorno esegui il deployment del bilanciatore del carico, l'applicazione Bookinfo non è accessibile dall'esterno del cluster GKE (ad esempio da un browser).

Richieste esterne

Risorsa Gateway di Bookinfo (definita in samples/bookinfo/networking/bookinfo-gateway.yaml) utilizza lo stato preconfigurato istio-ingressgateway. Ricorda che, quando hai eseguito il deployment di Cloud Service Mesh, hai specificato NodePort per istio-ingressgateway, che apre una porta specifica sul mesh di servizi. Anche se i nodi nel tuo cluster hanno indirizzi IP esterni, le richieste dall'esterno del cluster sono bloccate dalle regole firewall di Google Cloud. Con IAP, il modo corretto per esporre le applicazioni al pubblico e internet è usare un bilanciatore del carico. Non esporre gli indirizzi dei nodi utilizzando firewall, che ignorano IAP.

Per instradare le richieste a Bookinfo, devi configurare un bilanciatore del carico HTTP(S) nel progetto Google Cloud. Poiché il bilanciatore del carico si trova nel tuo progetto, all'interno del firewall e di poter accedere ai nodi nel tuo cluster. Dopo configurare il bilanciatore del carico con l'indirizzo IP statico e il nome di dominio, puoi inviare richieste al nome di dominio e il bilanciatore del carico inoltra richieste ai nodi nel cluster.

Attivazione di IAP

I passaggi seguenti spiegano come attivare IAP.

  1. Verifica se hai già un brand utilizzando la sezione Comando list. Puoi avere un solo brand per progetto.

    gcloud iap oauth-brands list
    

    Di seguito è riportato un esempio di risposta gcloud, se il brand esiste:

    name: projects/[PROJECT_NUMBER]/brands/[BRAND_ID]
    applicationTitle: [APPLICATION_TITLE]
    supportEmail: [SUPPORT_EMAIL]
    orgInternalOnly: true
    
  2. Se non esiste alcun brand, utilizza Comando create:

    gcloud iap oauth-brands create --application_title=APPLICATION_TITLE --support_email=SUPPORT_EMAIL
    

    I campi precedenti sono obbligatori quando chiami questa API:

    • supportEmail: l'email di assistenza visualizzata nella schermata per il consenso OAuth. Questo indirizzo email può essere l'indirizzo di un utente o un alias di Google Gruppi. Sebbene anche gli account di servizio abbiano un indirizzo email, non sono indirizzi email validi e non possono essere utilizzati durante la creazione di un brand. Tuttavia, un account di servizio può essere il proprietario di un gruppo Google. Crea un'istanza nuovo gruppo Google o configurare un gruppo esistente e impostare il servizio desiderato dell'account come proprietario del gruppo.

    • applicationTitle: il nome dell'applicazione visualizzato sul consenso OAuth schermo.

    La risposta contiene i seguenti campi:

    name: projects/[PROJECT_NUMBER]/brands/[BRAND_ID]
    applicationTitle: [APPLICATION_TITLE]
    supportEmail: [SUPPORT_EMAIL]
    orgInternalOnly: true
    

Creazione di un client OAuth IAP

  1. Usa il comando create per crea un client. Utilizza le funzionalità di il brand name del passaggio precedente.

    gcloud iap oauth-clients create projects/PROJECT_NUMBER/brands/BRAND-ID --display_name=NAME
    

    La risposta contiene i seguenti campi:

    name: projects/[PROJECT_NUMBER]/brands/[BRAND_NAME]/identityAwareProxyClients/[CLIENT_ID]
    secret: [CLIENT_SECRET]
    displayName: [NAME]
    
  2. Utilizza l'ID client (CLIENT_ID nel passaggio precedente) e CLIENT_SECRET per abilitare IAP. crea un secret Kubernetes con i materiali dal tuo client OAuth:

    kubectl create secret generic -n istio-system my-secret --from-literal=client_id=CLIENT_ID \
    --from-literal=client_secret=CLIENT_SECRET
    

Deployment del bilanciatore del carico

Puoi utilizzare un Risorsa in entrata per creare un'istanza Bilanciatore del carico HTTP(S) con configurazione automatica Certificati SSL. I certificati SSL gestiti di cui è stato eseguito il provisioning, rinnovato e gestito per il tuo dominio.

  1. Creare una risorsa ManagedCertificate. Questa risorsa specifica il dominio il certificato SSL. L'elenco spec.domains deve contenere un solo dominio. I domini con caratteri jolly non sono supportati. Nel seguente YAML, sostituisci DOMAIN_NAME con il nome di dominio che hai configurato per l'indirizzo IP statico esterno.

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.gke.io/v1
    kind: ManagedCertificate
    metadata:
      name: example-certificate
      namespace: istio-system
    spec:
      domains:
        - DOMAIN_NAME
    EOF
  2. Creare una risorsa BackendConfig. Questa risorsa indica a GCLB come eseguire Controlli di integrità sul gateway Ingress e configura Identity-Aware proxy. Innanzitutto, raccogli alcuni valori relativi all'integrità dal gateway Ingress controlli:

    • Porta in entrata per il controllo di integrità: questa è la porta per il controllo di integrità di istio-ingress.

      export HC_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="status-port")].nodePort}')

    • Percorso in entrata del controllo di integrità: si tratta del percorso del controllo di integrità di istio-ingress.

      export HC_INGRESS_PATH=$(kubectl get pods -n istio-system -l app=istio-ingressgateway -o jsonpath='{.items[0].spec.containers[?(@.name=="istio-proxy")].readinessProbe.httpGet.path}')

    cat <<EOF | kubectl apply -n istio-system -f -
    apiVersion: cloud.google.com/v1
    kind: BackendConfig
    metadata:
      name: http-hc-config
    spec:
      healthCheck:
        checkIntervalSec: 2
        timeoutSec: 1
        healthyThreshold: 1
        unhealthyThreshold: 10
        port: ${HC_INGRESS_PORT}
        type: HTTP
        requestPath: ${HC_INGRESS_PATH}
      iap:
        enabled: true
        oauthclientCredentials:
          secretName: my-secret
    EOF
  3. Annota il servizio in entrata con BackendConfig.

        kubectl annotate -n istio-system service/istio-ingressgateway --overwrite \
          cloud.google.com/backend-config='{"default": "http-hc-config"}' \
          cloud.google.com/neg='{"ingress":false}'
    
  4. Crea il bilanciatore del carico definendo la risorsa Ingress.

    • Imposta l'annotazione networking.gke.io/managed-certificates sul nome del certificato che hai creato nel passaggio precedente, example-certificate.

    • Imposta l'annotazione kubernetes.io/ingress.global-static-ip-name su nome dell'indirizzo IP statico che hai prenotato, example-static-ip.

    • Imposta serviceName su istio-ingressgateway, che viene utilizzato in la risorsa Gateway per l'esempio Bookinfo.

    cat <<EOF | kubectl apply -f -
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: example-ingress
      namespace: istio-system
      annotations:
        kubernetes.io/ingress.global-static-ip-name: example-static-ip
        networking.gke.io/managed-certificates: example-certificate
    spec:
      defaultBackend:
        service:
          name: istio-ingressgateway
          port:
            number: 80
    EOF
  5. Nella console Google Cloud, vai a Kubernetes Engine > Servizi e in entrata.

    Vai alla sezione Servizi e Pagina Ingress

    Dovresti vedere il messaggio "Creazione di un traffico in entrata" nella colonna Stato. Attendi che GKE esegua il provisioning completo di Ingress prima continua. Aggiorna la pagina a intervalli di pochi minuti per ottenere le informazioni più aggiornate nella risorsa Ingress. Dopo aver eseguito il provisioning di Ingress, potresti vedere "OK" o l'errore "Tutti i servizi di backend sono in stato NON HEALTHY". Una delle risorse di cui GKE esegue il provisioning è un integrità predefinito controllo. Se viene visualizzato questo messaggio di errore, significa che il traffico in entrata è di cui è stato eseguito il provisioning e che è stato eseguito il controllo di integrità predefinito. Quando vedi "OK" stato predefinito o l'errore, continua con la sezione successiva per configurare di integrità per il bilanciatore del carico.

Configura l'elenco per gli accessi IAP

Aggiungi un utente al criterio di accesso per IAP:

gcloud beta iap web add-iam-policy-binding \
    --member=user:EMAIL_ADDRESS \
    --role=roles/iap.httpsResourceAccessor

dove EMAIL_ADDRESS è l'indirizzo email completo dell'utente ad esempio alice@example.com.

  1. Testa il bilanciatore del carico. Accedi con il browser a:

    http://DOMAIN_NAME/productpage

    dove DOMAIN_NAME è il nome di dominio che configurato con l'indirizzo IP statico esterno.

    Dovresti vedere il valore productpage dell'applicazione Bookinfo. Se aggiorni pagina più volte, dovresti vedere versioni diverse delle recensioni, in stile round robin: stelle rosse, stelle nere, nessuna stella.

    Devi anche testare l'accesso https a Bookinfo.

Attiva il supporto di RCToken sulla rete mesh di servizi

Per impostazione predefinita, IAP genera JSON Web Token (JWT) che ha come ambito il client OAuth. Per Cloud Service Mesh, puoi configurare IAP per generare una RequestContextToken (RCToken), che è un JWT ma con un pubblico configurabile. RCToken consente di configurare il pubblico del JWT con una stringa arbitraria, che può essere utilizzato nei criteri di Cloud Service Mesh per un'autorizzazione granulare.

Per configurare RCToken:

  1. Crea una variabile di ambiente per il pubblico RCToken. Può essere con qualsiasi stringa tu voglia.

    export RCTOKEN_AUD="your-rctoken-aud"
    
  2. (Facoltativo) Il passaggio seguente richiede BACKEND_SERVICE_ID. Se hai bisogno di conoscere BACKEND_SERVICE_ID, esegui questo comando:

    kubectl -n istio-system get Ingress example-ingress -o json | jq \
     '.metadata.annotations."ingress.kubernetes.io/backends"'
    

    L'output previsto è simile a "{\"BACKEND_SERVICE_ID\":\"HEALTHY\"}". Ad esempio: "ingress.kubernetes.io/backends": "{\"k8s-be-31224--51f3b55cd1457fb6\":\"HEALTHY\"}". Il BACKEND_SERVICE_ID in questo esempio è k8s-be-31224--51f3b55cd1457fb6.

  3. Recupera le impostazioni IAP esistenti.

    gcloud iap settings get --format json \
    --project=${PROJECT_ID} --resource-type=compute --service=BACKEND_SERVICE_ID > iapSettings.json
    
  4. Aggiorna IapSettings con il pubblico RCToken.

    cat iapSettings.json | jq --arg RCTOKEN_AUD_STR $RCTOKEN_AUD \
    '. + {applicationSettings: {csmSettings: {rctokenAud: $RCTOKEN_AUD_STR}}}' \
    > updatedIapSettings.json
    
    gcloud iap settings set updatedIapSettings.json --format json \
    --project=${PROJECT_ID} --resource-type=compute --service=BACKEND_SERVICE_ID
    
  5. Abilita l'autenticazione RCToken sul gateway in entrata Istio.

    cat <<EOF | kubectl apply -f -
    apiVersion: "security.istio.io/v1beta1"
    kind: "RequestAuthentication"
    metadata:
      name: "ingressgateway-jwt-policy"
      namespace: "istio-system"
    spec:
      selector:
        matchLabels:
          app: istio-ingressgateway
      jwtRules:
      - issuer: "https://cloud.google.com/iap"
        jwksUri: "https://www.gstatic.com/iap/verify/public_key-jwk"
        audiences:
        - $RCTOKEN_AUD
        fromHeaders:
        - name: ingress-authorization
          prefix: "Istio "
        outputPayloadToHeader: "verified-jwt"
        forwardOriginalToken: true
    EOF
    
  6. (Facoltativo) Assicurati che le richieste che non hanno JWT validi vengano rifiutate:

      cat <<EOF | kubectl apply -f -
      apiVersion: security.istio.io/v1beta1
      kind: AuthorizationPolicy
      metadata:
        name: iap-gateway-require-jwt
        namespace: istio-system
      spec:
        selector:
          matchLabels:
            app: istio-iap-ingressgateway
        action: DENY
        rules:
          - from:
              - source:
                  notRequestPrincipals: ["*"]
      EOF
      

  7. Assicurati che le richieste inviate a productpage di Bookinfo vengano comunque andate a buon fine:

    http://DOMAIN_NAME/productpage

Per testare il criterio:

  1. Crea una richiesta IapSettings ma imposta rctokenAud su una stringa diversa:

    cat iapSettings.json | jq --arg RCTOKEN_AUD_STR wrong-rctoken-aud \
    '. + {applicationSettings: {csmSettings: {rctokenAud: $RCTOKEN_AUD_STR}}}' \
    > wrongIapSettings.json
    
  2. Chiama l'API IapSettings per impostare il pubblico RCtoken.

    gcloud beta iap settings set wrongIapSettings.json --project=PROJECT_ID --resource-type=compute --service=BACKEND_SERVICE
  3. Se invii una richiesta a productpage di Bookinfo, l'operazione dovrebbe non andare a buon fine:

    http://DOMAIN_NAME/productpage

esegui la pulizia

Dopo aver completato questo tutorial, rimuovi le risorse seguenti per evitare addebiti indesiderati sul tuo account:

  1. Elimina il certificato gestito:

    kubectl delete managedcertificates example-certificate
  2. Elimina l'oggetto Ingress, che trasferisce le risorse di bilanciamento del carico:

    kubectl -n istio-system delete ingress example-ingress

  3. Elimina l'indirizzo IP statico:

    gcloud compute addresses delete example-static-ip --global

    In questo caso, assicurati di eliminare l'indirizzo IP dal tuo registrar di domini.

  4. Eliminare il cluster. Questa operazione elimina le risorse che compongono il ad esempio istanze di calcolo, dischi e risorse di rete:

    gcloud container clusters delete CLUSTER_NAME