Integrazione di IAP con Cloud Service Mesh
Questa guida descrive come integrare Identity-Aware Proxy (IAP) con Cloud Service Mesh. L'integrazione di IAP con Cloud Service Mesh consente di accedere in modo sicuro ai servizi in base ai principi di BeyondCorp di Google. IAP verifica l'identità dell'utente e il contesto della richiesta per determinare se a un utente deve essere consentito l'accesso a un'applicazione o a una risorsa. L'integrazione di IAP con Cloud Service Mesh offre i seguenti vantaggi:
Controllo completo dell'accesso sensibile al contesto ai workload in esecuzione su Cloud Service Mesh. Puoi impostare policy di accesso granulari in base ad attributi della richiesta di origine, come l'identità dell'utente, l'indirizzo IP e il tipo di dispositivo. Puoi combinare le tue policy di accesso con limitazioni basate sul nome host e sul percorso di un URL di richiesta.
Abilita il supporto per le rivendicazioni sensibili al contesto nell'autorizzazione Cloud Service Mesh.
Accesso scalabile, sicuro e ad alta affidabilità alla tua applicazione tramite un bilanciatore del carico Google Cloud. Il bilanciamento del carico ad alte prestazioni offre una protezione integrata dagli attacchi DDoS (Distributed Denial of Service) e il supporto per l'indirizzamento IP anycast globale.
Prerequisiti
Segui i passaggi descritti in Installa gli strumenti dipendenti e convalida il cluster per:- Installare gli strumenti richiesti
- Scarica
asmcli - Concedere le autorizzazioni amministrative del cluster
- Convalidare il progetto e il cluster
Inoltre, questa guida presuppone che tu abbia:
Configurazione di un cluster con Cloud Service Mesh
Questa sezione spiega come configurare l'integrazione di IAP sia per le nuove installazioni di Cloud Service Mesh sia per gli upgrade.
Nuove installazioni
Attiva
iap.googleapis.com. Nel comando seguente, sostituisciPROJECT_IDcon il progetto in cui installerai Cloud Service Mesh:gcloud services enable \ --project=PROJECT_ID \ iap.googleapis.comIl cluster che stai aggiornando deve avere l'opzione
--addons=HttpLoadBalancingimpostata. Il componente aggiuntivoHttpLoadBalancingabilita un controller di bilanciamento del carico HTTP (L7) per il cluster. Esegui questo comando per aggiornare il cluster con le opzioni richieste da Cloud Service Mesh. A meno che tu non abbia impostato una zona o una regione predefinita, devi fornire la regione (--region=REGION) o la zona (--zone=ZONE) nel comando.gcloud container clusters update CLUSTER_NAME \ --project=PROJECT_ID \ --update-addons=HttpLoadBalancing=ENABLEDPer impostazione predefinita, il file
iap-operator.yamlha la porta 31223 impostata come porta di stato e la porta 31224 impostata come porta HTTP. Se la porta 31223 è già in uso nel tuo cluster, esegui questo comando per impostare un'altra porta di stato:kpt cfg set asm gcloud.container.cluster.ingress.statusPort STATUS_PORTSe la porta 31224 è già in uso nel tuo cluster, esegui questo comando per impostare un'altra porta HTTP:
kpt cfg set asm gcloud.container.cluster.ingress.httpPort HTTP_PORTSegui i passaggi descritti in Installa le funzionalità predefinite e Mesh CA per utilizzare uno script fornito da Google per installare Cloud Service Mesh. Quando esegui lo script, includi l'opzione seguente:
--option iap-operatorAd 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-operatorQuando installi Cloud Service Mesh, il file
iap-operator.yamlimposta il campotypesul servizioistio-ingressgatewaysuNodePort, che configura il gateway in modo che apra una porta specifica sul mesh di servizi. In questo modo puoi configurare un bilanciatore del carico che indirizza il traffico inviato al tuo nome di dominio a questa porta.Se stai installando Cloud Service Mesh gestito, completa anche i seguenti passaggi:
Aggiungi l'etichetta di revisione allo spazio dei nomi
istio-system.Scarica la specifica del servizio gateway in entrata Istio per IAP e chiamala
iap_operator.yaml.Installa l'ingresso come servizio NodePort.
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 la sezione successiva per configurare l'integrazione con IAP.
Upgrade
Questa sezione illustra i seguenti casi d'uso dell'upgrade:
Hai già configurato l'integrazione di IAP ed eseguito l'upgrade di Cloud Service Mesh. In questo caso, hai già abilitato
iap.googleapis.comsul tuo progetto e il componente aggiuntivoHttpLoadBalancingsul tuo cluster. Vai al passaggio 3 per scaricare il pacchettoasmed 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, eseguire l'upgrade di Cloud Service Mesh e tornare a questa guida dopo l'upgrade per completare l'integrazione.
Attiva
iap.googleapis.com. Nel comando seguente, sostituisciPROJECT_IDcon il progetto in cui installerai Cloud Service Mesh.gcloud services enable \ --project=PROJECT_ID \ iap.googleapis.comIl cluster che stai aggiornando deve avere l'opzione
--addons=HttpLoadBalancingimpostata. Il componente aggiuntivoHttpLoadBalancingabilita un controller di bilanciamento del carico HTTP (L7) per il cluster. Esegui questo comando per aggiornare il cluster con le opzioni richieste da Cloud Service Mesh. A meno che tu non abbia impostato una zona o una regione predefinita, devi fornire la regione (--region=REGION) o la zona (--zone=ZONE) nel comando.gcloud container clusters update CLUSTER_NAME \ --project=PROJECT_ID --update-addons=HttpLoadBalancing=ENABLEDSe stai aggiornando un bilanciatore del carico HTTP Cloud esistente e funzionante, esegui il seguente comando 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}')Segui i passaggi descritti in Eseguire l'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.yamlimposta il campotypedel servizioistio-ingressgatewaysuNodePort, che configura il gateway in modo che apra una porta specifica sul mesh di servizi. In questo modo puoi configurare un bilanciatore del carico che instrada il traffico inviato al tuo nome di dominio a questa porta.Per impostazione predefinita, il file
iap-operator.yamlha la porta 31223 impostata come porta di stato e la porta 31224 impostata come porta HTTP.Quando esegui lo script, includi la seguente opzione:
--option iap-operatorAd 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-operatorCompleta l'upgrade attivando l'inserimento automatico del proxy sidecar nei tuoi workload. Per maggiori dettagli, vedi Deployment e redeployment dei carichi di lavoro.
Dopo aver completato l'upgrade, torna a questa guida e continua con la 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 Google Cloud bilanciatore del carico HTTP(S), che richiede un nome di dominio che punti a un indirizzo IP statico. Puoi prenotare un indirizzo IP esterno statico, il che determina l'assegnazione di quell'indirizzo al tuo progetto per un tempo indeterminato finché non lo rilasci esplicitamente.
Prenota un indirizzo IP esterno statico:
gcloud compute addresses create example-static-ip --globalOttieni l'indirizzo IP statico:
gcloud compute addresses describe example-static-ip --globalNel registrar del nome di dominio, configura un nome di dominio completo (FQDN) con l'indirizzo IP statico. In genere, si aggiunge un record
Aalle impostazioni DNS. I passaggi di configurazione e la terminologia per l'aggiunta di un recordAper un FQDN variano a seconda del registrar del nome di dominio.La propagazione dell'impostazione DNS può richiedere da 24 a 48 ore. Puoi continuare a configurare tutto in questa guida, ma non potrai testare la configurazione finché le impostazioni DNS non vengono propagate.
Deployment di un'applicazione di esempio
Prima di abilitare IAP, devi avere un'applicazione in esecuzione sul tuo cluster GKE per poter verificare che tutte le richieste abbiano un'identità. Questa guida utilizza l'esempio Bookinfo per mostrare come configurare il bilanciamento del carico HTTP(S) e attivare IAP.
Segui i passaggi per eseguire il deployment di Bookinfo. Finché non esegui il deployment del bilanciatore del carico, l'applicazione Bookinfo non è accessibile al di fuori del cluster GKE (ad esempio da un browser).
Richieste esterne
La risorsa Gateway di Bookinfo (definita in
samples/bookinfo/networking/bookinfo-gateway.yaml) utilizza il
istio-ingressgateway preconfigurato.
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 del cluster hanno indirizzi IP esterni, le richieste provenienti dall'esterno del cluster vengono bloccate dalle regole firewall di Google Cloud . Con
IAP, il modo corretto per esporre le applicazioni a internet
pubblico è utilizzare un bilanciatore del carico. Non esporre gli indirizzi dei nodi utilizzando regole firewall, che bypasserebbero IAP.
Per instradare le richieste a Bookinfo, configura un bilanciatore del carico HTTP(S) nel tuo progettoGoogle Cloud . Poiché il bilanciatore del carico si trova nel tuo progetto, è all'interno del firewall e può accedere ai nodi del cluster. Dopo aver configurato 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 le richieste ai nodi del cluster.
Abilitazione di IAP
I seguenti passaggi descrivono come abilitare IAP.
Configurare la schermata per il consenso
Controlla se hai già un brand esistente utilizzando il comando list. Puoi avere un solo brand per progetto.
gcloud iap oauth-brands list
Di seguito è riportato un esempio di risposta di gcloud, se il brand esiste:
name: projects/[PROJECT_NUMBER]/brands/[BRAND_ID] applicationTitle: [APPLICATION_TITLE] supportEmail: [SUPPORT_EMAIL] orgInternalOnly: trueSe non esiste un brand, utilizza il comando create:
gcloud iap oauth-brands create --application_title=APPLICATION_TITLE --support_email=SUPPORT_EMAIL
I campi sopra indicati sono obbligatori quando chiami questa API:
supportEmail: l'indirizzo email di assistenza visualizzato nella schermata per il consenso OAuth. Questo indirizzo email può essere l'indirizzo di un utente o un alias di Google Gruppi. Anche se gli account di servizio hanno un indirizzo email, non sono indirizzi email validi e non possono essere utilizzati per creare un brand. Tuttavia, unaccount di serviziot può essere il proprietario di un gruppo Google. Crea un nuovo gruppo Google o configurane uno esistente e imposta il service account desiderato come proprietario del gruppo.applicationTitle: il nome dell'applicazione visualizzato nella schermata per il consenso OAuth.
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
Utilizza il comando create per creare un client. Utilizza il brand
namedel 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]Utilizza l'ID client (
CLIENT_IDnel passaggio precedente) eCLIENT_SECRETper attivare IAP. Crea un secret di Kubernetes con i materiali del 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 una risorsa Ingress per creare un bilanciatore del carico HTTP(S) con certificati SSL configurati automaticamente. I certificati SSL gestiti vengono forniti, rinnovati e gestiti per il tuo dominio.
Crea una risorsa ManagedCertificate. Questa risorsa specifica il dominio per il certificato SSL. L'elenco
spec.domainsdeve contenere un solo dominio. I domini con caratteri jolly non sono supportati. Nel seguente YAML, sostituisciDOMAIN_NAMEcon 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 EOFCrea una risorsa BackendConfig. Questa risorsa indica a GCLB come eseguire i controlli di integrità sul gateway in entrata, nonché come configurare Identity-Aware Proxy. Innanzitutto, raccogli alcuni valori dal gateway Ingress relativi ai controlli di integrità:
Porta di ingresso del controllo di integrità: questa è la porta del 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 di ingresso del controllo di integrità: questo è il 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 EOFAnnota il servizio di ingresso 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}'Crea il bilanciatore del carico definendo la risorsa Ingress.
Imposta l'annotazione
networking.gke.io/managed-certificatessul nome del certificato creato nel passaggio precedente,example-certificate.Imposta l'annotazione
kubernetes.io/ingress.global-static-ip-namesul nome dell'indirizzo IP statico che hai prenotato,example-static-ip.Imposta
serviceNamesuistio-ingressgateway, che viene utilizzato nella 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 EOFNella console Google Cloud , vai alla pagina Kubernetes Engine > Servizi e Ingress.
Vai alla pagina Servizi e Ingress
Dovresti visualizzare il messaggio "Creazione ingresso" nella colonna Stato. Attendi che GKE esegua completamente il provisioning dell'ingresso prima di continuare. Aggiorna la pagina ogni pochi minuti per ottenere lo stato più aggiornato dell'ingresso. Dopo il provisioning dell'ingresso, potresti visualizzare lo stato "Ok" o l'errore "Tutti i servizi di backend sono in stato NON INTEGRO". Una delle risorse di cui GKE esegue il provisioning è un controllo di integrità predefinito. Se visualizzi il messaggio di errore, significa che è stato eseguito il provisioning dell'Ingress e che è stato eseguito il controllo di integrità predefinito. Quando vedi lo stato "Ok" o l'errore, continua con la sezione successiva per configurare i controlli di integrità per il bilanciatore del carico.
Configura l'elenco per gli accessi IAP
Aggiungi un utente alla policy di accesso per IAP:
gcloud beta iap web add-iam-policy-binding \
--member=user:EMAIL_ADDRESS \
--role=roles/iap.httpsResourceAccessordove EMAIL_ADDRESS è l'indirizzo email completo dell'utente,
ad esempio alice@example.com.
Testa il bilanciatore del carico. Indirizza il browser a:
http://DOMAIN_NAME/productpage
dove
DOMAIN_NAMEè il nome di dominio che hai configurato con l'indirizzo IP statico esterno.Dovresti vedere il
productpagedell'applicazione Bookinfo. Se aggiorni la pagina più volte, dovresti visualizzare diverse versioni delle recensioni, presentate in stile round robin: stelle rosse, stelle nere, nessuna stella.Dovresti anche testare l'accesso di
httpsa Bookinfo.
Abilita il supporto di RCToken sul mesh di servizi
Per impostazione predefinita, IAP genera un token web JSON (JWT) con ambito limitato al client OAuth. Per Cloud Service Mesh, puoi configurare IAP in modo che generi un RequestContextToken (RCToken), che è un JWT, ma con un pubblico configurabile. RCToken ti consente di configurare il pubblico del JWT su una stringa arbitraria, che può essere utilizzata nelle policy Cloud Service Mesh per l'autorizzazione granulare.
Per configurare l'RCToken:
Cesta una variabile di ambiente per il pubblico RCToken. Può essere qualsiasi stringa che preferisci.
export RCTOKEN_AUD="your-rctoken-aud"(Facoltativo) Il passaggio successivo richiede
BACKEND_SERVICE_ID. Se devi scoprire il valore diBACKEND_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\"}".BACKEND_SERVICE_IDin questo esempio èk8s-be-31224--51f3b55cd1457fb6.Recupera le impostazioni IAP esistenti.
gcloud iap settings get --format json \ --project=${PROJECT_ID} --resource-type=compute --service=BACKEND_SERVICE_ID > iapSettings.jsonAggiorna
IapSettingscon il pubblico RCToken.cat iapSettings.json | jq --arg RCTOKEN_AUD_STR $RCTOKEN_AUD \ '. + {applicationSettings: {csmSettings: {rctokenAud: $RCTOKEN_AUD_STR}}}' \ > updatedIapSettings.jsongcloud iap settings set updatedIapSettings.json --format json \ --project=${PROJECT_ID} --resource-type=compute --service=BACKEND_SERVICE_IDAbilita 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(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: ["*"] EOFAssicurati che le richieste a Bookinfo
productpagevadano ancora a buon fine:http://DOMAIN_NAME/productpage
Per testare la policy:
Crea un oggetto richiesta
IapSettings, ma impostarctokenAudsu una stringa diversa:cat iapSettings.json | jq --arg RCTOKEN_AUD_STR wrong-rctoken-aud \ '. + {applicationSettings: {csmSettings: {rctokenAud: $RCTOKEN_AUD_STR}}}' \ > wrongIapSettings.jsonChiama l'API
IapSettingsper impostare il pubblico RCtoken.gcloud beta iap settings set wrongIapSettings.json --project=PROJECT_ID --resource-type=compute --service=BACKEND_SERVICE
Invia una richiesta a Bookinfo
productpagee dovrebbe non riuscire:http://DOMAIN_NAME/productpage
Pulizia
Dopo aver completato questo tutorial, rimuovi le seguenti risorse per evitare che vengano addebitati costi indesiderati sul tuo account:
Elimina il certificato gestito:
kubectl delete managedcertificates example-certificate
Elimina la risorsa Ingress, che dealloca le risorse di bilanciamento del carico:
kubectl -n istio-system delete ingress example-ingress
Elimina l'indirizzo IP statico:
gcloud compute addresses delete example-static-ip --global
Se lo fai, assicurati di eliminare l'indirizzo IP dal registrar del dominio.
Elimina il cluster, che elimina le risorse che lo compongono, come le istanze di computing, i dischi e le risorse di rete:
gcloud container clusters delete CLUSTER_NAME