Torniamo ai microservizi con Istio. Parte 3

Torniamo ai microservizi con Istio. Parte 3

Nota. trad.: La prima parte questa serie era dedicata a conoscere le capacità di Istio e a dimostrarle in azione, secondo — routing ottimizzato e gestione del traffico di rete. Ora parleremo di sicurezza: per dimostrare le funzioni base ad essa legate, l'autore utilizza il servizio di identità Auth0, ma altri provider possono essere configurati in modo simile.

Abbiamo configurato un cluster Kubernetes in cui abbiamo distribuito Istio e un'applicazione di microservizi di esempio, Sentiment Analysis, per dimostrare le capacità di Istio.

Con Istio, siamo riusciti a mantenere i nostri servizi di piccole dimensioni perché non necessitano di implementare livelli come tentativi, timeout, interruttori automatici, tracciamento, monitoraggio. . Inoltre, abbiamo utilizzato tecniche avanzate di test e distribuzione: test A/B, mirroring e implementazioni canary.

Torniamo ai microservizi con Istio. Parte 3

Nel nuovo materiale ci occuperemo degli ultimi livelli del percorso verso il valore aziendale: autenticazione e autorizzazione - e in Istio è un vero piacere!

Autenticazione e autorizzazione in Istio

Non avrei mai creduto che mi sarei ispirato all'autenticazione e all'autorizzazione. Cosa può offrire Istio dal punto di vista tecnologico per rendere questi argomenti divertenti e, ancor di più, stimolanti per te?

La risposta è semplice: Istio trasferisce la responsabilità di queste funzionalità dai tuoi servizi al proxy Envoy. Nel momento in cui le richieste raggiungono i servizi, sono già state autenticate e autorizzate, quindi tutto ciò che devi fare è scrivere codice utile per il business.

Suona bene? Diamo un'occhiata dentro!

Autenticazione con Auth0

Come server per la gestione delle identità e degli accessi utilizzeremo Auth0, che ha una versione di prova, è intuitivo da usare e semplicemente mi piace. Tuttavia, gli stessi principi possono essere applicati a qualsiasi altro Implementazioni di OpenID Connect: KeyCloak, IdentityServer e molti altri.

Per iniziare, vai a Portale Auth0 con il tuo account, crea un tenant (tenant - “tenant”, unità logica di isolamento, per maggiori dettagli cfr documentazione - ca. trad.) e vai a Applicazioni > App predefinitascegliendo Dominio, come mostrato nello screenshot qui sotto:

Torniamo ai microservizi con Istio. Parte 3

Specificare questo dominio nel file resource-manifests/istio/security/auth-policy.yaml (codice sorgente):

apiVersion: authentication.istio.io/v1alpha1
kind: Policy
metadata:
  name: auth-policy
spec:
  targets:
  - name: sa-web-app
  - name: sa-feedback
  origins:
  - jwt:
      issuer: "https://{YOUR_DOMAIN}/"
      jwksUri: "https://{YOUR_DOMAIN}/.well-known/jwks.json"
  principalBinding: USE_ORIGIN

Con una tale risorsa, Pilota (uno dei tre componenti base del piano di controllo in Istio - trad. approssimativa) configura Envoy per autenticare le richieste prima di inoltrarle ai servizi: sa-web-app и sa-feedback. Allo stesso tempo, la configurazione non viene applicata al servizio Envoys sa-frontend, permettendoci di lasciare il frontend non autenticato. Per applicare la policy, esegui il comando:

$ kubectl apply -f resource-manifests/istio/security/auth-policy.yaml
policy.authentication.istio.io “auth-policy” created

Torna alla pagina e fai una richiesta: vedrai che termina con lo stato 401 Non autorizzato. Ora reindirizziamo gli utenti frontend all'autenticazione con Auth0.

Autenticazione delle richieste con Auth0

Per autenticare le richieste degli utenti finali, è necessario creare un'API in Auth0 che rappresenterà i servizi autenticati (recensioni, dettagli e valutazioni). Per creare un'API, vai a Portale Auth0 > API > Crea API e compila il modulo:

Torniamo ai microservizi con Istio. Parte 3

Le informazioni importanti qui sono Identifier, che utilizzeremo più avanti nello script. Scriviamolo così:

  • Pubblico: {IL TUO_AUDIENCE}

I restanti dettagli di cui abbiamo bisogno si trovano sul Portale Auth0 nella sezione Applicazioni - Selezionare Applicazione di prova (creato automaticamente insieme all'API).

Qui scriveremo:

  • Dominio: {IL TUO_DOMINIO}
  • Identificativo cliente: {IL TUO_CLIENT_ID}

Scorri fino a Applicazione di prova al campo di testo URL di richiamata consentiti (URL risolti per la richiamata), in cui specifichiamo l'URL a cui inviare la chiamata una volta completata l'autenticazione. Nel nostro caso è:

http://{EXTERNAL_IP}/callback

E per URL di disconnessione consentiti (URL consentiti per la disconnessione) aggiungi:

http://{EXTERNAL_IP}/logout

Passiamo al frontend.

Aggiornamento del frontend

Passa alla filiale auth0 deposito [istio-mastery]. In questo ramo, il codice frontend viene modificato per reindirizzare gli utenti ad Auth0 per l'autenticazione e utilizzare il token JWT nelle richieste ad altri servizi. Quest'ultimo è implementato come segue (App.js):

analyzeSentence() {
    fetch('/sentiment', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${auth.getAccessToken()}` // Access Token
        },
        body: JSON.stringify({ sentence: this.textField.getValue() })
    })
        .then(response => response.json())
        .then(data => this.setState(data));
}

Per modificare il frontend in modo che utilizzi i dati del tenant in Auth0, apri sa-frontend/src/services/Auth.js e sostituisci in esso i valori che abbiamo scritto sopra (Auth.js):

const Config = {
    clientID: '{YOUR_CLIENT_ID}',
    domain:'{YOUR_DOMAIN}',
    audience: '{YOUR_AUDIENCE}',
    ingressIP: '{EXTERNAL_IP}' // Используется для редиректа после аутентификации
}

L'applicazione è pronta. Specifica il tuo ID Docker nei comandi seguenti durante la creazione e la distribuzione delle modifiche apportate:

$ docker build -f sa-frontend/Dockerfile 
 -t $DOCKER_USER_ID/sentiment-analysis-frontend:istio-auth0 
 sa-frontend

$ docker push $DOCKER_USER_ID/sentiment-analysis-frontend:istio-auth0

$ kubectl set image deployment/sa-frontend 
 sa-frontend=$DOCKER_USER_ID/sentiment-analysis-frontend:istio-auth0

Prova l'app! Verrai reindirizzato su Auth0, dove dovrai effettuare il login (o registrarti), dopodiché verrai rimandato alla pagina da cui verranno effettuate le richieste già autenticate. Se provi i comandi menzionati nelle prime parti dell'articolo con curl, otterrai il codice 401 Codice di stato, segnalando che la richiesta non è autorizzata.

Facciamo il passo successivo: autorizzare le richieste.

Autorizzazione con Auth0

L'autenticazione ci consente di capire chi è un utente, ma è necessaria l'autorizzazione per sapere a cosa ha accesso. Istio offre strumenti anche per questo.

Ad esempio, creiamo due gruppi di utenti (vedere il diagramma seguente):

  • Membri (utenti) — con accesso ai soli servizi SA-WebApp e SA-Frontend;
  • moderatori (moderatori) — con accesso a tutti e tre i servizi.

Torniamo ai microservizi con Istio. Parte 3
Il concetto di autorizzazione

Per creare questi gruppi, utilizzeremo l'estensione di autorizzazione Auth0 e utilizzeremo Istio per fornire loro diversi livelli di accesso.

Installazione e configurazione dell'autorizzazione Auth0

Nel portale Auth0, vai alle estensioni (Estensioni) e installare Autorizzazione Auth0. Dopo l'installazione, vai a Estensione dell'autorizzazionee lì - alla configurazione dell'inquilino facendo clic in alto a destra e selezionando l'opzione di menu appropriata (Configurazione). Attiva i gruppi (Gruppi) e fare clic sul pulsante della regola di pubblicazione (Pubblica regola).

Torniamo ai microservizi con Istio. Parte 3

Crea gruppi

In Estensione autorizzazione vai a ATTIVITA' E GRUPPI e creare un gruppo moderatori. Poiché tratteremo tutti gli utenti autenticati come utenti normali, non sarà necessario creare un gruppo aggiuntivo per loro.

Scegli un gruppo moderatori, Premete Aggiungi membri, aggiungi il tuo account principale. Lascia alcuni utenti senza alcun gruppo per assicurarti che venga loro negato l'accesso. (I nuovi utenti possono essere creati manualmente tramite Portale Auth0 > Utenti > Crea utente.)

Aggiungi attestazione di gruppo al token di accesso

Gli utenti sono stati aggiunti ai gruppi, ma queste informazioni devono riflettersi anche nei token di accesso. Per conformarsi a OpenID Connect e allo stesso tempo restituire i gruppi di cui abbiamo bisogno, il token dovrà aggiungere il proprio reclamo personalizzato. Implementato tramite le regole Auth0.

Per creare una regola, vai su Auth0 Portal to Regole, Premete Crea regola e seleziona una regola vuota dai modelli.

Torniamo ai microservizi con Istio. Parte 3

Copia il codice qui sotto e salvalo come nuova regola Aggiungi reclamo di gruppo (namespacedGroup.js):

function (user, context, callback) {
    context.accessToken['https://sa.io/group'] = user.groups[0];
    return callback(null, user, context);
}

Nota: questo codice prende il primo gruppo di utenti definito nell'estensione dell'autorizzazione e lo aggiunge al token di accesso come attestazione personalizzata (sotto il relativo spazio dei nomi, come richiesto da Auth0).

Ritorna alla pagina Regole e controlla di avere due regole scritte nel seguente ordine:

  • auth0-estensione-autorizzazione
  • Aggiungi reclamo di gruppo

L'ordine è importante perché il campo del gruppo riceve la regola in modo asincrono auth0-estensione-autorizzazione e successivamente viene aggiunta come rivendicazione dalla seconda regola. Il risultato è un token di accesso come questo:

{
 "https://sa.io/group": "Moderators",
 "iss": "https://sentiment-analysis.eu.auth0.com/",
 "sub": "google-oauth2|196405271625531691872"
 // [сокращено для наглядности]
}

Ora è necessario configurare il proxy Envoy per verificare l'accesso degli utenti, per il quale il gruppo verrà estratto dalla richiesta (https://sa.io/group) nel token di accesso restituito. Questo è l'argomento della prossima sezione dell'articolo.

Configurazione dell'autorizzazione in Istio

Affinché l'autorizzazione possa funzionare, è necessario abilitare RBAC per Istio. Per fare ciò, utilizzeremo la seguente configurazione:

apiVersion: "rbac.istio.io/v1alpha1"
kind: RbacConfig
metadata:
  name: default
spec:
  mode: 'ON_WITH_INCLUSION'                     # 1
  inclusion:
    services:                                   # 2
    - "sa-frontend.default.svc.cluster.local"
    - "sa-web-app.default.svc.cluster.local"
    - "sa-feedback.default.svc.cluster.local" 

Spiegazione:

  • 1: abilita RBAC solo per i servizi e gli spazi dei nomi elencati nel campo Inclusion;
  • 2 — elenchiamo l'elenco dei nostri servizi.

Applichiamo la configurazione con il seguente comando:

$ kubectl apply -f resource-manifests/istio/security/enable-rbac.yaml
rbacconfig.rbac.istio.io/default created

Tutti i servizi ora richiedono il controllo degli accessi basato sui ruoli. In altre parole, l'accesso a tutti i servizi è vietato e comporterà una risposta RBAC: access denied. Ora consentiamo l'accesso agli utenti autorizzati.

Accedi alla configurazione per gli utenti regolari

Tutti gli utenti devono avere accesso ai servizi SA-Frontend e SA-WebApp. Implementato utilizzando le seguenti risorse Istio:

  • ServiceRole — determina i diritti di cui dispone l'utente;
  • ServiceRoleBinding — determina a chi appartiene questo ServiceRole.

Per gli utenti ordinari consentiremo l'accesso ad alcuni servizi (servicerole.yaml):

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
  name: regular-user
  namespace: default
spec:
  rules:
  - services: 
    - "sa-frontend.default.svc.cluster.local" 
    - "sa-web-app.default.svc.cluster.local"
    paths: ["*"]
    methods: ["*"]

E attraverso regular-user-binding applica ServiceRole a tutti i visitatori della pagina (utente-regolare-servizio-role-binding.yaml):

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
  name: regular-user-binding
  namespace: default
spec:
  subjects:
  - user: "*"
  roleRef:
    kind: ServiceRole
    name: "regular-user"

"Tutti gli utenti" significa che anche gli utenti non autenticati avranno accesso a SA WebApp? No, la policy controllerà la validità del token JWT.

Applichiamo le configurazioni:

$ kubectl apply -f resource-manifests/istio/security/user-role.yaml
servicerole.rbac.istio.io/regular-user created
servicerolebinding.rbac.istio.io/regular-user-binding created

Accedi alla configurazione per i moderatori

Per i moderatori, vogliamo abilitare l'accesso a tutti i servizi (mod-service-role.yaml):

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
  name: mod-user
  namespace: default
spec:
  rules:
  - services: ["*"]
    paths: ["*"]
    methods: ["*"]

Ma vogliamo tali diritti solo per quegli utenti il ​​cui token di accesso contiene attestazioni https://sa.io/group con significato Moderators (mod-service-role-binding.yaml):

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
  name: mod-user-binding
  namespace: default
spec:
  subjects:
  - properties:
      request.auth.claims[https://sa.io/group]: "Moderators"
  roleRef:
    kind: ServiceRole
name: "mod-user" 

Applichiamo le configurazioni:

$ kubectl apply -f resource-manifests/istio/security/mod-role.yaml
servicerole.rbac.istio.io/mod-user created
servicerolebinding.rbac.istio.io/mod-user-binding created

A causa della memorizzazione nella cache di Envoys, potrebbero essere necessari un paio di minuti affinché le regole di autorizzazione abbiano effetto. Puoi quindi assicurarti che utenti e moderatori abbiano livelli di accesso diversi.

Conclusione su questa parte

Seriamente, hai mai visto un approccio più semplice, agevole, scalabile e sicuro all'autenticazione e all'autorizzazione?

Erano necessarie solo tre risorse Istio (RbacConfig, ServiceRole e ServiceRoleBinding) per ottenere un controllo capillare sull'autenticazione e sull'autorizzazione dell'accesso degli utenti finali ai servizi.

Inoltre, ci siamo presi cura di questi problemi attraverso i nostri servizi di invio, ottenendo:

  • ridurre la quantità di codice generico che potrebbe contenere problemi di sicurezza e bug;
  • ridurre il numero di situazioni stupide in cui un endpoint si è rivelato accessibile dall'esterno e si è dimenticato di segnalarlo;
  • eliminando la necessità di aggiornare tutti i servizi ogni volta che viene aggiunto un nuovo ruolo o diritto;
  • che i nuovi servizi restino semplici, sicuri e veloci.

conclusione

Istio consente ai team di concentrare le proprie risorse su attività business-critical senza aggiungere costi generali ai servizi, riportandoli allo stato micro.

L'articolo (in tre parti) fornisce le conoscenze di base e istruzioni pratiche già pronte per iniziare con Istio in progetti reali.

PS da traduttore

Leggi anche sul nostro blog:

Fonte: habr.com

Aggiungi un commento