Questo tutorial descrive come utilizzare la federazione delle identità per i carichi di lavoro per autenticare i carichi di lavoro eseguiti all'esterno di Google Cloud, in modo che possano accedere ai microservizi ospitati da Cloud Run. Questo tutorial è destinato agli amministratori che vogliono integrare la federazione delle identità per i carichi di lavoro con il proprio provider di identità (IdP) esistente. La federazione delle identità per i carichi di lavoro ti consente di connettere carichi di lavoro esterni ai carichi di lavoro eseguiti in Google Cloud. Cloud Run ti consente di eseguire microservizi containerless stateless.
Questo tutorial fornisce istruzioni su come configurare Jenkins come carico di lavoro esterno, Keycloak come IdP, Cloud Run e federazione di identità dei carichi di lavoro. Quando completi questo tutorial, potrai vedere come la federazione delle identità per i carichi di lavoro ti consente di autenticare la tua applicazione Jenkins con Google Cloud utilizzando l'autenticazione OpenID Connect.
Autenticazione esterna del carico di lavoro utilizzando chiavi dell'account di servizio
Se hai un carico di lavoro eseguito all'esterno di Google Cloud, devi autenticare in modo sicuro tale carico di lavoro in modo che possa interagire con il tuo microservizio ospitato da Cloud Run. Tradizionalmente, si potrebbe usare uno strumento come Librerie client Cloud per autenticare e passare una chiave dell'account di servizio per eseguire l'autenticazione con un carico di lavoro esterno. Le librerie client di Cloud utilizzano una libreria denominata Application Default Credentials (ADC) per trovare automaticamente le credenziali del tuo account di servizio. Questa libreria imposta una variabile di ambiente denominata GOOGLE_APPLICATION_CREDENTIALS. ADC utilizza la chiave o il file di configurazione dell'account di servizio a cui rimanda la variabile per autenticare automaticamente l'account.
Tuttavia, questo approccio presenta i seguenti rischi per la sicurezza:
- Per impostazione predefinita, una chiave dell'account di servizio non include una data di scadenza. Se il tuo codice viene divulgato, devi esporre ogni autorizzazione collegata alla chiave.
- Poiché le chiavi degli account di servizio sono statiche, devi creare una strategia per gestirle e ruotarle.
Anche se la creazione di una chiave dell'account di servizio è un processo abbastanza semplice, potresti sacrificare la sicurezza per la semplicità.
Autenticazione esterna del carico di lavoro utilizzando la federazione delle identità per i carichi di lavoro
La federazione di Workload Identity gestisce i rischi per la sicurezza derivanti dalla creazione e dal download delle chiavi statiche dell'account di servizio. La federazione delle identità per i carichi di lavoro ti consente di autenticare i carichi di lavoro al di fuori di Google Cloud senza utilizzare una chiave statica dell'account di servizio. Qualsiasi carico di lavoro esterno che deve utilizzare servizi in Google Cloud può trarre vantaggio da questa funzionalità.
La federazione delle identità per i carichi di lavoro ti consente di utilizzare il tuo IdP per l'autenticazione direttamente con Google Cloud. Per eseguire l'autenticazione, utilizza OpenID Connect. Cloud Run accetta token OpenID Connect dal tuo IdP per l'autenticazione.
Il processo di autenticazione quando si utilizza la federazione delle identità per i carichi di lavoro è il seguente:
- La libreria di autenticazione (AUTHN) invia una richiesta JWT (JSON Web Token) all'IdP.
- Il tuo IdP firma i token web JSON (JWT). La libreria AUTHN legge questi dati da una variabile.
- La libreria invia un comando POST al servizio token di sicurezza che include il token firmato.
- Il servizio token di sicurezza esamina il provider di pool di federazione per i carichi di lavoro che hai configurato per la creazione del trust e verifica l'identità della credenziale.
- Il servizio Token di sicurezza restituisce un token federato.
- La libreria invia il token a IAM.
- IAM lo scambia con un token OpenID Connect di un account di servizio. Per maggiori informazioni, consulta la pagina Generazione di token ID OpenID Connect.
- La libreria fornisce il token OpenID Connect a Jenkins.
- Jenkins utilizza questo token per l'autenticazione con Cloud Run.
Il seguente diagramma mostra il flusso di autenticazione:
Obiettivi
- Configura Jenkins come carico di lavoro esterno.
- Configura Keycloak come IdP compatibile con OpenID Connect.
- Collega Jenkins a Keycloak.
- Installa le librerie client di Cloud per recuperare il token JWT da Keycloak a Google Cloud.
- Connetti Google Cloud a Keycloak e Jenkins.
- Recupera il JWT per l'utente autenticato da Keycloak.
Anche se questo tutorial utilizza Keycloak, puoi utilizzare qualsiasi provider di identità che supporti OpenID Connect, ad esempio GitLab, Okta o OneLogin.
Costi
Questo tutorial utilizza i seguenti componenti fatturabili di Google Cloud:
Per generare una stima dei costi in base all'utilizzo previsto,
utilizza il Calcolatore prezzi.
Al termine di questo tutorial, puoi evitare una fatturazione continua eliminando le risorse che hai creato. Per scoprire di più, vedi Pulizia.
Prima di iniziare
-
In Google Cloud Console, vai alla pagina del selettore dei progetti.
-
Seleziona o crea un progetto Google Cloud.
-
Assicurati che la fatturazione sia attivata per il tuo progetto Cloud. Scopri come verificare se la fatturazione è abilitata su un progetto.
- Configura un microservizio su Cloud Run. Per saperne di più, consulta la guida rapida: deployment di un container su Cloud Run.
Configura Jenkins
Completa queste attività in un ambiente non Google Cloud, ad esempio nel tuo ambiente on-premise o su un altro cloud.
Se hai già un provider di identità che supporta OpenID Connect e un carico di lavoro esterno, puoi saltare questo passaggio e andare a Installare le librerie client di Cloud.
Per simulare un carico di lavoro esterno, puoi utilizzare una VM con Jenkins installato. Puoi eseguire Jenkins come immagine Docker o installarla direttamente sul tuo server. I passaggi seguenti mostrano come installarlo direttamente sul server.
- Apri una riga di comando su una VM a tua scelta.
Installa Java:
$ sudo apt update $ sudo apt install openjdk-11-jre $ java -version
Installa Jenkins:
curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo tee \ /usr/share/keyrings/jenkins-keyring.asc > /dev/null echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \ https://pkg.jenkins.io/debian-stable binary/ | sudo tee \ /etc/apt/sources.list.d/jenkins.list > /dev/null sudo apt-get update sudo apt-get install jenkins
Verifica di poter accedere al server Jenkins sulla porta 8080. Se utilizzi una VM protetta da un firewall, assicurati che le porte appropriate siano aperte.
Procurati la password di amministratore e configura Jenkins. Per le istruzioni, consulta la procedura guidata di configurazione successiva all'installazione.
Completa le seguenti azioni per configurare SSL:
- Se hai un provider di dominio, puoi utilizzare la sua autorità di certificazione (CA) per richiedere un certificato firmato. In alternativa, puoi ottenere un certificato firmato gratuito che dura 90 giorni da zerossl.com.
Scarica il file ZIP del certificato e trasferiscilo al server che esegue Jenkins:
scp -i CERTFILE.pem -r CERTFILE.zip VM_FQDN:/home/USERNAME
Sostituisci quanto segue:
CERTFILE
con il nome del file del certificato che include la chiave pubblica.VM_FQDN
con il nome di dominio completo del server all'esterno di Google Cloud.USERNAME
con il tuo nome utente.
Rinomina i file e genera un file .pkcs12 che Jenkins può utilizzare:
openssl rsa -in KEYFILE.com.key -out KEYFILE.com.key
Sostituisci
KEYFILE
con il nome del file del certificato.
Aggiorna il file
/etc/sysconfig/jenkins
:Apri il file in un editor di testo:
vi /etc/sysconfig/jenkins
Imposta
JENKINS_PORT
su-1
.Imposta
JENKINS_HTTPS_PORT
su8443
.Nella parte inferiore del file, aggiungi i seguenti argomenti:
JENKINS_ARGS="--httpsCertificate=/var/lib/jenkins/.ssl/CERTFILE.crt --httpsPrivateKeys=/var/lib/jenkins/.ssl/KEYFILE.pkcs1.key"
Sostituisci quanto segue:
CERTFILE
con il nome file del file del certificato utilizzando il formato .crt.KEYFILE
con il nome file della chiave PKCS.
Riavvia il server Jenkins.
Verifica di avere aperto la porta 8443 nel firewall e accedi a Jenkins sulla porta 8443.
Installa un plug-in di Jenkins che ti serve per integrare Keycloak con Jenkins. Puoi scegliere una delle seguenti opzioni:
Per installare il plug-in, procedi nel seguente modo:
- Nella dashboard di Jenkins, vai a Manage Jenkins > Manage Plugins (Gestisci Jenkins > Gestisci plug-in).
Seleziona Available (Disponibile) e cerca il plug-in che preferisci. Lo screenshot che segue mostra la pagina di gestione dei plug-in in cui è selezionata la scheda Disponibile.
Installa il plug-in.
Configura Keycloak
In questo tutorial, Keycloak gestisce gli utenti, i gruppi e i ruoli. Keycloak utilizza i regni per gestire gli utenti.
Installa il server Keycloak sulla VM in esecuzione all'esterno di Google Cloud. Per questo tutorial, ti consigliamo di installare Keycloak da un container Docker.
Apri la Console di amministrazione Keycloak.
Vai a Impostazioni di Realm.
Nella scheda General (Generale), verifica che i campi siano impostati come segue:
- Attivata: ON
- Accesso gestito dall'utente: OFF
- Endpoint: Configurazione degli endpoint OpenID e Metadati del provider di identità SAML 2.0
Il seguente screenshot mostra i campi da configurare.
Creare un client in modo da avere un'entità in grado di richiedere Keycloak per l'autenticazione di un utente. Spesso i client sono applicazioni e servizi che utilizzano Keycloak per fornire una soluzione Single Sign-On (SSO).
- Nella Console di amministrazione di Keycloak, fai clic su Clienti > Crea.
Inserisci quanto segue:
- Client-ID: jenkins
- Protocollo client: openid-connect
- URL principale: http://JENKINS_IP_ADDRESS:8080, dove JENKINS_IP_ADDRESS è l'indirizzo IP del server Jenkins.
Il seguente screenshot mostra i campi da configurare.
Fai clic su Salva.
Nella scheda Installazione, verifica che il formato del token sia Keycloak OIDC JSON. Crea una copia di questo token perché ti servirà per completare la configurazione di Jenkins.
Per creare un gruppo di test, procedi nel seguente modo:
- Nella Console di amministrazione di Keycloak, fai clic su Gruppi > Nuovo.
- Inserisci un nome per il gruppo e fai clic su Salva.
- Crea un altro gruppo di test. Puoi assegnare ruoli ai tuoi gruppi, ma questo tutorial non richiede alcun ruolo.
Per creare un utente di prova da aggiungere al gruppo:
- Nella Console di amministrazione di Keycloak, fai clic su Gestisci utente > Aggiungi utenti.
Inserisci le informazioni sull'utente e fai clic su Salva.
Il seguente screenshot mostra alcuni esempi di informazioni per un account utente.
Fai clic sulla scheda Credenziali e verifica che l'opzione Temporanea sia impostata su Off.
Reimpostare la password.
Utilizzerai questo account in seguito in JWT per l'autenticazione.
Il seguente screenshot mostra la scheda Credenziali con i campi da configurare.
Fai clic sulla scheda Gruppi e seleziona uno dei gruppi creati in precedenza.
Fai clic su Partecipa.
Ripeti questo passaggio per creare altri utenti di test.
Configura la configurazione di Jenkins per OpenID Connect
Questa sezione descrive come configurare il plug-in OpenID Connect per Jenkins.
- Sul server Jenkins, vai a Manage Jenkins > Configure Global Security.
In Security Realm, seleziona Keycloak Authentication Plugin. Fai clic su Salva.
Fai clic su Configura sistema.
Nelle impostazioni Global Keycloak, copia il file JSON di installazione di Keycloak che hai creato in Configura Keycloak. Se hai bisogno di recuperare i dati JSON, completa quanto segue:
Nella Console di amministrazione di Keycloak, vai a Clients (Clienti).
Fai clic sul nome del cliente.
Nella scheda Installazione, fai clic su Opzione formato e seleziona Keycloak OIDC JSON.
Di seguito è riportato un esempio di Keycloak JSON:
{ "realm":"master" "auth-server-url":"AUTHSERVERURL" "ssl-required":"none" "resource":"jenkins" "public-client":true "confidential-port":0 }
AUTHSERVERURL è l'URL del server di autenticazione.
Per salvare la configurazione OIDC, fai clic su Salva.
Jenkins può ora eseguire il reindirizzamento a Keycloak per ricevere informazioni sugli utenti.
Installare librerie client di Cloud
Per inviare un JWT da Keycloak a Google Cloud, devi installare le librerie client di Cloud sul server di Jenkins. Questo tutorial utilizza Python per interagire con Google Cloud utilizzando l'SDK.
Installa Python sul server Jenkins. I passaggi seguenti mostrano come installare Python 3:
sudo apt update sudo apt install software-properties-common sudo add-apt-repository ppa:deadsnakes/ppa sudo apt update sudo apt install python3.8
Installa pip3 per scaricare e importare le librerie client Cloud:
pip3 –version sudo apt update sudo apt install python3-pip pip3 –version
Installa le librerie client Cloud per Python utilizzando pip3:
pip3 install –upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib
Ad esempio:
pip3 install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib Collecting google-api-python-client Downloading google_api_python_client-2.42.0-py2.py3-none-any.whl (8.3 MB) USERNAME | 8.3 MB 19.9 MB/s Collecting google-auth-httplib2 Downloading google_auth_httplib2-0.1.0-py2.py3-none-any.whl (9.3 MB) Collecting google-auth-oauthlib Downloading google_auth_oauthlib-0.5.1-py2.py3-non-any.whl (19 KB)
Sostituisci USERNAME con il tuo nome utente.
Installa Google Cloud CLI sul tuo server Jenkins. Per le istruzioni, consulta la Guida rapida: installazione dell'interfaccia a riga di comando gcloud.
Configura l'ambiente Google Cloud
Questa sezione descrive i passaggi da completare per garantire che l'ambiente Google Cloud che ospita il container serverless possa connettersi con Jenkins e Keycloak.
In Google Cloud, crea un account di servizio in modo che il microservizio su Cloud Run possa accedere alle autorizzazioni associate. Ad esempio, per creare un account di servizio utilizzando gcloud CLI, procedi come segue:
gcloud iam service-accounts create cloudrun-oidc \ –-description="cloud run oidc sa" \ –-display-name="cloudrun-oidc"
Per impostazione predefinita, Cloud Run crea un account di servizio predefinito per te. Tuttavia, l'utilizzo dell'account di servizio predefinito non è una best practice di sicurezza perché l'account ha un ampio set di autorizzazioni. Di conseguenza, ti consigliamo di creare un account di servizio separato per il tuo microservizio. Per istruzioni sulla creazione di un account di servizio per Cloud Run, consulta Creazione e gestione degli account di servizio.
Crea un pool di federazione delle identità per i carichi di lavoro. Per creare un pool utilizzando gcloud CLI, esegui il comando seguente:
gcloud iam workload-identity-pools create cloudrun-oidc-pool \ --location="global" \ —-description="cloudrun-oidc" \ —-display-name="cloudrun-oidc"
Crea un provider di pool di federazione delle identità per i carichi di lavoro per OpenID Connect:
gcloud iam workload-identity-pools providers create-oidc cloud-run-provider \ --workload-identity-pool="cloudrun-oidc-pool" \ --issuer-uri="VAR_LINK_TO_ENDPOINT" \ --location="global" \ --attribute-mapping ="google.subject=assertion.sub,attribute.isadmin-assertion.isadmin,attribute.aud=assertion.aud" \ --attribute-condition="attribute.isadmin=='true'"
Sostituisci
VAR_LINK_TO_ENDPOINT
con una variabile che contiene il link all'endpoint OIDC di Keycloak. Per trovare questo link, nella finestra Realm di Cloud Console di amministrazione, fai clic sulla scheda General. L'endpoint deve essere HTTPS, il che significa che devi configurare il tuo server Keycloak con HTTPS.
Recupera il JWT per l'utente autenticato da Keycloak
Nella VM che esegue Keycloak, scarica il token in un file di testo. Ad esempio, su Linux, esegui il comando seguente:
curl -L -X POST 'https://IP_FOR_KEYCLOAK:8080/auth/realms/master/protocol/openid-connect/token' -H 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'client_id=jenks' \ --data-urlencode 'grant_type=password' \ --data-urlencode 'client_secret=CLIENT_SECRET \ --data-urlencode 'scope=openid' \ --data-urlencode 'username=USERNAME' \ --data-urlencode 'password=PASSWORD' | grep access_token | cut -c18-1490 > token.txt
Sostituisci quanto segue:
IP_FOR_KEYCLOAK
con l'indirizzo IP del server Keycloak.CLIENT_SECRET
con il client secret di Keycloak.USERNAME
con un utente Keycloak.PASSWORD
con la password dell'utente Keycloak.
Questo comando include l'ID client, il client secret, il nome utente e la password. Come best practice per la sicurezza, consigliamo di utilizzare le variabili ambientali per mascherare questi valori anziché utilizzare la riga di comando. Il comando di esempio reindirizza le credenziali a un file denominato
token.txt
.In via facoltativa, per automatizzare questo passaggio, puoi creare uno script bash.
Convalida il token all'indirizzo jwt.io.
Sulla VM, crea il file delle credenziali:
gcloud iam workload-identity-pools create-cred config \ projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/cloudrun-oidc-pool/providers/cloud-run/provider \ --output-file=sts-creds.json \ --credential-source-file=token.txt
Per ulteriori informazioni, consulta gcloud iam Workload-identity-pools create-cred-config.
Il file di output dovrebbe avere l'aspetto seguente:
{ "type": "external_account", "audience": "//iam.google.apis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/cloudrun-oidc-pool/subject/USER_EMAIL", "subject_token_type": "urn:ietf:params:oauth:token-type:jwt", "token_url": "https://sts.googleapis.com/v1/token", "credential_source": { "file" "token.txt" } }
PROJECT_NUMBER
è il numero del tuo progetto.Sulla VM, imposta il file
sts.creds.json
come variabile per ADC:export GOOGLE_APPLICATION_CREDENTIALS=/Users/USERNAME/sts-creds.json
Sostituisci USERNAME con il tuo nome utente UNIX.
Prima del lancio della federazione delle identità per i carichi di lavoro, questo valore era la chiave dell'account di servizio. Con la federazione delle identità per i carichi di lavoro, questo valore è il file delle credenziali appena creato.
Crea un'associazione dei ruoli da parte dell'utente per impersonare l'account di servizio:
gcloud iam service-accounts add-iam-policy-binding SERVICE_ACCOUNT \ --role roles/iam.workloadIdentityUser \ --member "principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/cloudrun-oidc-pool/subject/USER_EMAIL
Sostituisci quanto segue:
SERVICE_ACCOUNT
con l'indirizzo email dell'account di servizio che hai creato in Configurare l'ambiente Google Cloud. Per maggiori informazioni, consulta gcloud iam service-accounts add-iam-policy-binding.USER_EMAIL
con il tuo indirizzo email.
Consenti all'account di servizio di accedere al servizio Cloud Run:
gcloud run services add-iam-policy-binding SERVICE_NAME --member-"serviceAccount:SERVICE_ACCOUNT" \ --role="roles/run.invoker"
Sostituisci quanto segue:
SERVICE_NAME
con il nome del microservizio in esecuzione su Cloud Run.SERVICE_ACCOUNT
con l'indirizzo email dell'account di servizio per Cloud Run.
Per maggiori informazioni, consulta gcloud run services add-iam-policy-binding.
Genera un token ID:
#!/usr/bin/python from google.auth import credentials from google.cloud import iam_credentials_v1 import google.auth import google.oauth2.credentials from google.auth.transport.requests import AuthorizedSession, Request url = "https://WORKLOAD_FQDN" aud = "https://WORKLOAD_FQDN" service_account = 'SERVICE_ACCOUNT' name = "projects/-/serviceAccounts/{}".format(service_account) id_token = client.generate_id_token(name=name,audience=aud, include_email=True) print(id_token.token) creds = google.oauth2.credentials.Credentials(id_token.token) authed_session = AuthorizedSession(creds) r = authed_session.get(url) print(r.status_code) print(r.text)
Sostituisci quanto segue:
WORKLOAD_FQDN
con il nome di dominio completo per il carico di lavoro.SERVICE_ACCOUNT
con l'indirizzo email dell'account di servizio per Cloud Run.
Il token che utilizzi può chiamare l'API Identity and Access Management, che ti fornirà il nuovo JWT necessario per richiamare il servizio Cloud Run.
Puoi utilizzare il tuo token all'interno di una pipeline Jenkins per richiamare il container serverless in esecuzione in Cloud Run. Tuttavia, questi passaggi non rientrano nell'ambito di questo tutorial.
Esegui la pulizia
Per evitare che al tuo account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo tutorial, puoi eliminare il progetto.
Elimina il progetto
- In Google Cloud Console, vai alla pagina Gestisci risorse.
- Nell'elenco dei progetti, seleziona il progetto che vuoi eliminare, quindi fai clic su Elimina.
- Nella finestra di dialogo, digita l'ID del progetto e fai clic su Chiudi per eliminare il progetto.
Passaggi successivi
- Scopri di più sulla federazione delle identità per i carichi di lavoro.
- Per ulteriori architetture di riferimento, diagrammi e best practice, esplora il Centro architettura cloud.