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. L'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 le limitazioni in base al nome host e al percorso di un URL 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 bilanciatore del carico Google Cloud. Il bilanciamento del carico ad alte prestazioni offre protezione integrata contro gli attacchi DDoS (distributed denial of service) e il supporto per l'indirizzamento IP anycast globale.
Prerequisiti
Segui i passaggi descritti in Installare gli strumenti dipendenti e convalidare il cluster a:- Installare gli strumenti richiesti
- Scarica
asmcli
- Concedi le autorizzazioni di amministratore del cluster
- Convalida il progetto e il cluster
Inoltre, questa guida presuppone che tu abbia:
Configurazione di un cluster con Anthos 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
Attiva
iap.googleapis.com
. Nel comando seguente, sostituisciPROJECT_ID
con il progetto in cui installerai Cloud Service Mesh:gcloud services enable \ --project=PROJECT_ID \ iap.googleapis.com
Il cluster da aggiornare deve avere l'opzione
--addons=HttpLoadBalancing
impostata. Il componente aggiuntivoHttpLoadBalancing
attiva un controller di bilanciamento del carico HTTP (L7) per il cluster. Esegui il comando seguente 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
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 quanto segue per impostare un'altra porta HTTP:
kpt cfg set asm gcloud.container.cluster.ingress.httpPort HTTP_PORT
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 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
Quando installi Cloud Service Mesh,
iap-operator.yaml
imposta il campotype
del servizioistio-ingressgateway
suNodePort
, 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.Se stai installando Cloud Service Mesh gestito, completa anche i seguenti passaggi:
Aggiungi l'etichetta di revisione allo spazio dei nomi
istio-system
.Scarica Specifiche del servizio Istio Ingress Gateway per IAP e assegnagli il nome
iap_operator.yaml
.Installa Ingress come servizio NodePort. Per maggiori informazioni, consulta la pagina Eseguire 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 vai alla sezione successiva per configurare l'integrazione con IAP.
Upgrade
Questa sezione riguarda i seguenti casi d'uso di upgrade:
Hai già configurato l'integrazione di IAP e stai eseguendo l'upgrade di Cloud Service Mesh. In questo caso, hai già attivato
iap.googleapis.com
nel tuo progetto e il componente aggiuntivoHttpLoadBalancing
nel tuo cluster. Vai al passaggio 3 per scaricare il pacchettoasm
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.
Attiva
iap.googleapis.com
. Nel comando seguente, sostituisciPROJECT_ID
con il progetto in cui installerai Cloud Service Mesh.gcloud services enable \ --project=PROJECT_ID \ iap.googleapis.com
Il cluster da aggiornare deve avere l'opzione
--addons=HttpLoadBalancing
impostata. Il componente aggiuntivoHttpLoadBalancing
abilita un carico HTTP (L7) di bilanciamento del carico per il cluster. Esegui il comando seguente per aggiornare il cluster con le opzioni richieste da Cloud Service Mesh. A meno che 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=ENABLED
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}')
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.yaml
imposta il campotype
del servizioistio-ingressgateway
suNodePort
, che configura il gateway in modo da aprire una porta specifica nel 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.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
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 vai alla sezione successiva per configurare l'integrazione con l'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 rimandi a un indirizzo IP statico. Puoi prenotare un indirizzo IP esterno statico, che assegna l'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 --global
Ottieni l'indirizzo IP statico:
gcloud compute addresses describe example-static-ip --global
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 unA
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 attivare l'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 di Bookinfo per dimostrare come configurare il HTTP(S) e abilitare IAP.
Segui i passaggi per eseguire il deployment di Bookinfo. Fino a quando non 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 nel service mesh.
Sebbene i nodi del cluster abbiano indirizzi IP esterni, le richieste provenienti dall'esterno del cluster vengono bloccate dalle regole del firewall di Google Cloud. Con IAP, il modo corretto per esporre le applicazioni alla rete internet pubblica è utilizzare un bilanciatore del carico. Non esporre gli indirizzi dei nodi utilizzando
firewall, che ignorano IAP.
Per inoltrare le richieste a Bookinfo, devi configurare un bilanciatore del carico HTTP(S) nel tuo 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 aver configurato il bilanciatore del carico con l'indirizzo IP statico e il nome di dominio, puoi inviare richieste al nome di dominio, che il bilanciatore del carico inoltra ai nodi del cluster.
Attivazione di IAP
I passaggi seguenti spiegano come attivare IAP.
Configurazione della schermata per il consenso in corso...
Verifica se hai già un brand utilizzando il 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
Se non esiste alcun brand, utilizza Comando create:
gcloud iap oauth-brands create --application_title=APPLICATION_TITLE --support_email=SUPPORT_EMAIL
I campi sopra indicati sono obbligatori quando si chiama 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. Anche gli account di servizio hanno un indirizzo email, ma non sono indirizzi email validi e non possono essere utilizzati per creare 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 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
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]
Utilizza l'ID client (
CLIENT_ID
nel passaggio precedente) eCLIENT_SECRET
per attivare gli acquisti in-app. 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
Implementazione 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 vengono eseguiti in provisioning, rinnovati e gestiti per il tuo dominio.
Creare una risorsa ManagedCertificate. Questa risorsa specifica il dominio per il certificato SSL. L'elenco
spec.domains
deve contenere un solo dominio. I domini con caratteri jolly non sono supportati. Nel seguente codice YAML,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
Crea una risorsa BackendConfig. Questa risorsa indica a GCLB come eseguire controlli di integrità su Ingress Gateway e come configurare Identity-Aware Proxy. Innanzitutto, raccogli alcuni valori da Ingress Gateway relativi ai controlli di salute:
Porta di ingresso del controllo di integrità: questa è la porta di 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 EOF
Aggiungi un'annotazione al 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-certificates
sul nome del certificato 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
suistio-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
Nella console Google Cloud, vai alla pagina Kubernetes Engine > Servizi & Ingress.
Vai alla sezione Servizi e Pagina Ingress
Nella colonna Stato dovresti vedere il messaggio "Creazione di un ingresso". 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 UNHEALTHY". Una delle risorse di cui GKE esegue il provisioning è un integrità predefinito verifica. 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 visualizzi lo stato "Ok" o l'errore, vai alla sezione successiva per configurare i controlli di salute per il bilanciatore del carico.
Configurare l'elenco di accesso IAP
Aggiungi un utente al criterio di accesso per l'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
.
Testa il bilanciatore del carico. Indirizza il browser a:
http://DOMAIN_NAME/productpage
dove
DOMAIN_NAME
è il nome di dominio che configurato con l'indirizzo IP statico esterno.Dovresti vedere
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.Dovresti anche testare l'accesso di
https
a Bookinfo.
Attiva il supporto di RCToken sulla rete mesh di servizi
Per impostazione predefinita, IAP genera un token web JSON (JWT) che ha come ambito il client OAuth. Per Cloud Service Mesh, puoi configurare l'IAP in modo da generare un RequestContextToken (RCToken), che è un JWT, ma con un segmento di 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:
Crea una variabile di ambiente per il pubblico RCToken. Può essere con qualsiasi stringa tu voglia.
export RCTOKEN_AUD="your-rctoken-aud"
(Facoltativo) Il passaggio seguente richiede
BACKEND_SERVICE_ID
. Se hai bisogno di conoscereBACKEND_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\"}"
. IlBACKEND_SERVICE_ID
in 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.json
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
Attiva 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: ["*"] EOF
Assicurati che le richieste inviate a
productpage
di Bookinfo vengano comunque andate a buon fine:http://DOMAIN_NAME/productpage
Per testare il criterio:
Crea un oggetto richiesta
IapSettings
, ma impostarctokenAud
su una stringa diversa:cat iapSettings.json | jq --arg RCTOKEN_AUD_STR wrong-rctoken-aud \ '. + {applicationSettings: {csmSettings: {rctokenAud: $RCTOKEN_AUD_STR}}}' \ > wrongIapSettings.json
Chiama l'API
IapSettings
per impostare il segmento di pubblico RCtoken.gcloud beta iap settings set wrongIapSettings.json --project=PROJECT_ID --resource-type=compute --service=BACKEND_SERVICE
Se invii una richiesta a
productpage
di Bookinfo, l'operazione dovrebbe non andare a buon fine:http://DOMAIN_NAME/productpage
Pulizia
Dopo aver completato questo tutorial, rimuovi le seguenti risorse per evitare addebiti indesiderati sul tuo account:
Elimina il certificato gestito:
kubectl delete managedcertificates example-certificate
Elimina Ingress, che disalloca 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
In questo caso, assicurati di eliminare l'indirizzo IP dal tuo registrar di domini.
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