5 passi per integrare Istio con OPA

L’autenticazione ed autorizzazione sono grandi parti del puzzle della sicurezza che devono essere risolte dagli architetti cloud e dagli ingegneri DevOps. In questo blog, consideriamo specificamente come ottenere l’autorizzazione/controllo dell’accesso, ossia quali azioni l’entità autenticata può compiere all’interno della rete di servizi Istio. Contribuisce a proteggere l’infrastruttura impedendo azioni con intenti maligni.

L’autorizzazione in una rete di servizi può essere definita utilizzando le politiche OPA. OPA è un meccanismo che aiuta gli ingegneri DevOps a definire e applicare le politiche di autorizzazione per i carichi di lavoro di Kubernetes. In questo pezzo, vedremo:

  • Cos’è OPA
  • Perché dovreste integrare OPA con la rete di servizi Istio
  • Come Istio e OPA autorizzano le richieste
  • I passaggi esatti da seguire per integrare OPA con Istio

Cos’è OPA?

OPA (acronimo di “Open Policy Agent”) è un motore di enforzamento di politiche open-source, adatto a molti scopi, che permette agli ingegneri DevOps di definire le politiche come codice utilizzando una linguaggio declarativo altamente estratto chiamato Rego. OPA aiuta a definire e applicare le politiche in modo centralizzato lungo tutto il stack, risparmiando ai sviluppatori la scrittura di politiche di autorizzazione nel codice dell’applicazione. Ecco come funziona OPA (si veda la Figura 1):

  1. L’applicazione/servizio riceve una richiesta.
  2. Il servizio invia una richiesta di autorizzazione JSON all’OPA.
  3. L’OPA verifica la richiesta in base alle politiche di autorizzazione definite.
  4. L’OPA prende la decisione e restituisce la risposta di autorizzazione (ALLOW/DENY) nel formato JSON al servizio.

Figura 1: Flusso di richiesta di autorizzazione con OPA

Nota che non è necessario che sia un’applicazione scritta da un sviluppatore a inviare la richiesta di autorizzazione: può essere Argo CD, resource API del Gateway di Kubernetes, Terraform, Prometheus o qualcos’altro, poiché OPA è di tipo generico. (Ho menzionato e disegnato una applicazione in un cluster Kubernetes qui per comodità e per una migliore comprensione.)

Perché integrare OPA con Istio?

Istio ha un robusto meccanismo di autorizzazione. Tuttavia, avere una macchina di enforcer politiche dedicata come OPA insieme al service mesh di Istio ha i suoi benefici:

  • Sistema di gestione centralizzato per definire e applicare le politiche: OPA rende più semplice per i DevOps la gestione centralizzata delle politiche di autorizzazione per l’intero stack. Questo include i carichi di lavoro meschi, gli stack non meschi e anche le verifiche di autorizzazione (ad esempio, una politica che impedisce la distribuzione nei venerdì). 
  • Più flessibilità e granularità nella definizione delle politiche: Se osservate la tabella qui sotto (Figura 2), è chiaro che l’autorizzazione di Istio può fare molto e corrispondere a una richiesta in base a una varietà di campi da diversi dati di origine. Tuttavia, la CRD AuthorizationPolicy di Istio può essere limitata nella configurazione del corpo della richiesta HTTP o qualsiasi dato contestuale nei campi, per il quale può essere utilizzato OPA. A differenza di Istio, OPA può usare qualsiasi dato per l’esame delle politiche.
  • Configurazione semplificata di AuthZ: Può essere noioso per i DevOps configurare regole di autorizzazione complesse in Istio. OPA è configurato usando Rego, che è più vicino ad un linguaggio di programmazione. È relativamente più semplice impostare regole di politica dalla semplice alla complessa usando Rego.

Figura 2: Confronto tabellare tra Istio e l’autorizzazione OPA (fonte)

Come Istio e OPA autorizzano le richieste

Il personale DevOps può deployare OPA come servizio separato o come container sidecar accanto al proxy Envoy e al container dell’applicazione all’interno di un pod. L’approccio del container sidecar è migliore per ridurre la latenza.

I container sidecar OPA devono essere iniettati nel pod dell’applicazione proprio come i container sidecar del proxy Envoy di Istio. Possiamo configurare i container OPA iniettati per montare ConfigMaps che contengono le regole di autorizzazione; ogni container sidecar OPA nel namespace monterà quindi la stessa configurazione e le stesse regole di AuthZ definite nella ConfigMap.

Una volta iniettato il sidecar OPA, il proxy Envoy invierà richieste di autorizzazione a OPA per prendere decisioni di autorizzazione quando il servizio riceve una richiesta:

Figura 3: Flusso di lavoro di autorizzazione Istio-OPA

Supponiamo che il personale DevOps non voglia che ogni container OPA iniettato nello stesso namespace segua le stesse configurazioni e voglia applicare regole diverse. In questo caso, dovranno fare una delle seguenti cose:

  • Rimuovere la codifica statica che permette alla politica di iniezione corrente di utilizzare una specifica ConfigMap
  • Configurare il mutating webhook e disabilitare l’iniezione del sidecar a livello di pod
  • Servire i pacchetti di politiche da un server HTTP remoto
  • Distribuire l’applicazione e i sidecar in un namespace differente con un ConfigMap diverso

Step per l’integrazione di Opa con Istio: Demo

L’idea qui è far diventare OPA l’autorizzatore esterno invece degli sidecar del proxy Envoy — per fare decisioni sull’accesso.

Userò il classico applicazione Bookinfo dalla documentazione di Istio per la demo. Configurerò OPA con Istio per l’accesso in modo controllato e verificherò che sia applicato sparando richieste a bookinfo/productpage:

Figure 4: Diagramma tutorial integrazione Istio-OPA

Nota che /productpage è l’interfaccia utente, che fa chiamate interne ad altri servizi, come i servizi di recensioni e valutazioni (diagramma). Inserirò OPA in ogni pod nel namespace bookinfo; tutti i contenitori OPA montano lo stesso ConfigMap e hanno le stesse politiche di autorizzazione a causa di ciò. Il comportamento predefinito dell’applicazione Bookinfo non fa forward di alcuna autenticazione HTTP, quindi le chiamate interne falliranno l’autenticazione e quindi l’autorizzazione.

Seguiremo i passi forniti nell’ordine:

  1. Configurare l’iniezione del sidecar OPA
  2. Abilita la comunicazione tra il proxy Istio e OPA
  3. Deploy OPA configuration
  4. Applicare la configurazione Istio
  5. Deploy the application and test the Istio-OPA authorization setup

La prerequisito per la demo è avere installato Istio v1.19+ nel tuo cluster. qui sto usando Istio v1.21.0.

OPA fornisce un file quickstart.yaml per un installazione facile. L’ho diviso in tre per facilitare la comprensione: IMESH GitHub repo

Step 1: Configure OPA Sidecar Injection

Applicare il file opa_controller.yaml:

YAML

 

kubectl apply -f opa_controller.yaml

Il file opa_controller.yaml deploys everything — TLS certificates, ConfigMap containing injection policy, admission controller deployment, e configurazione del webhook mutante — nel namespace opa-istio (si riveda la Figura 5):

  1. The mutating webhook controller (opa-istio-admission-controller) quindi ascolterà un particolare label (opa-istio-injection) con il valore impostato su enabled.
  2. Il controller webhook chiama l’admission-controller, che ha la politica di iniezione.
  3. La politica di iniezione dice all’admission-controller come iniettare il container sidecar OPA nel pod.

Figura 5: Configurazione di iniezione del sidecar OPA

Ora, prima di distribuire l’applicazione Bookinfo, creiamo lo spazio di nome bookinfo e seguiamo le altre operazioni:

Creare lo spazio di nome bookinfo applicando bookinfo-ns.yaml:

YAML

 

kubectl apply -f bookinfo-ns.yaml

You can see the namespace has the label opa-istio-injection: enabled, to auto-inject OPA sidecars.

Step 2: Abilita la Comunicazione Tra Proxy Istio e OPA

Modifica il ConfigMap Istio nellaNamespace istio-system e aggiungi extensionProviders (opa-ext-authz-grpc), in modo da abilitare l’autorizzazione esterna nella mesh:

  • Copia extensionProviders dalla commentazione in opa_controller.yaml.
  • Modifica il ConfigMap Istio e aggiungi extensionProviders nel campo mesh.
  • Assicurarsi che l’indentazione sia corretta.
  • Salva la configurazione.

Il passo rende possibile per istio-proxy parlare con il container opa-istio nel pod per richieste di autorizzazione.

Se guardi gli extensionProviders, è un filtro di tipo ExtAuthzGrpc in Envoy con un servizio specificato e un porto:

YAML

 

...

extensionProviders:
- name: opa-ext-authz-grpc
envoyExtAuthzGrpc:
service: opa-ext-authz-grpc.local
       port: "9191"

...

Il nome, l’indirizzo del servizio e il porto degli extensionProviders dovrebbero essere gli stessi nel opa_authz.yaml e nel opa_config.yaml.

Step 3: Distribuzione Configurazione OPA

Il opa_config.yaml definisce le configurazioni relative alle politiche aperte. Include opa-istio-config e opa-policy ConfigMaps — che definiscono rispettivamente l’implementazione del servizio gRPC (envoy_ext_authz_grpc) e le politiche di autorizzazione reali.

Le politiche di autorizzazione possono essere divise in due parti: la prima parte definisce le condizioni sotto le quali l’autorizzazione è consentita o negata; la seconda parte definisce i ruoli utente e i permessi per ogni ruolo.

Le politiche di autorizzazione richiedono un po’ di tempo per essere adattate, in quanto Rego non utilizza molti keyword qui. Abilita una versione più recente di Rego per ottenere keyword (ad esempio, il keyword allow if condition).

Applicare la configurazione OPA nel namespace bookinfo, poiché va a fianco all’applicazione:

YAML

 

kubectl apply -f opa_config.yaml -n bookinfo

Step 4: Applicare Configurazione Istio

Il file opa_authz.yaml contiene le configurazioni di Istio. Contiene una AuthorizationPolicy e un ServiceEntry. Notare che il provider di Policy di Autorizzazione è opa-ext-authz-grpc, che è l’extensionProvider che abbiamo configurato nel ConfigMap all’ step 2.

Allo stesso modo, il hostname definito nell’ServiceEntry è lo stesso dell’indirizzo del servizio fornito nell’extensionProvider (opa-ext-authz-grpc.local). Il servizio gRPC si avvia sulla porta 9191 dell’host 127.0.0.1, che il ServiceEntry rende accessibili agli opa-istio sidecar all’interno del pod dal contenitore istio-proxy.

Distribuisci la configurazione:

YAML

 

kubectl apply -f opa_authz.yaml -n bookinfo

Step 5: Distribuisci l’Applicazione e Testa la Configurazione di Autorizzazione Istio-OPA

Distribuisci l’applicazione Bookinfo e il gateway:

YAML

 

kubectl apply -f /your_Istio_directory/samples/bookinfo/platform/kube/bookinfo.yaml -n bookinfo
kubectl apply -f /your_Istio_directory/samples/bookinfo/networking/bookinfo-gateway.yaml -n bookinfo

Controlla i pod nel namespace bookinfo:

YAML

 

kubectl get pods -n bookinfo

Potete vedere che ogni pod ha 3 container in esecuzione all’interno: l’applicazione, il proxy Envoy (istio-proxy) e OPA (opa-istio).

Ottieni l’IP del gateway Istio per accedere al servizio:

YAML

 

kubectl get svc -n istio-system

Ora tutto è pronto e siamo pronti a testare le politiche di autorizzazione. Le politiche che abbiamo definito in opa_config.yaml sono le seguenti:

YAML

 

...

user_roles = {
"alice": ["guest"],
"bob": ["admin"]
}

role_perms = {
"guest": [
{"method": "GET", "path": "/productpage"},
],
"admin": [
{"method": "GET", "path": "/productpage"},
{"method": "GET", "path": "/api/v1/products"},
        ],

...

Alice è un utente ospite che può accedere solo a /productpage; Bob è un amministratore che può accedere ai percorsi /productpage e /api/v1/products. Verifichiamo le politiche.

Prova ad accedere a /api/v1/products da Alice:

YAML

 

curl -vvv your_istio_gateway_ip/api/v1/products -u alice:password

Puoi vedere che la risposta 403 Forbidden da Alice perché non ha accesso alla path. Proviamo lo stesso path come Bob:

YAML

 

curl -vvv your_istio_gateway_ip/api/v1/products -u bob:password

Mostra l’HTTP status 200 OK e il contenuto della pagina alla fine della risposta.

Esempio di scenario per il controllo d’accesso con OPA

Puoi usare la CRD AuthorizationPolicy di Istio per applicare la politica mostrata nel demo soprastante. Non hai bisogno di OPA. tuttavia, ci sono casi in cui il controllo d’accesso di Istio può essere limitato, come menzionato nella tabella iniziale. Forniscimi un semplice esempio.

Supponiamo che ci sia un’applicazione di BookReviews, che è un servizio GraphQL, dove i recensori inviano recensioni, gli editori le modificano e le pubblicano, e gli utenti leggono le recensioni pubblicate.

Quando un recensore aggiunge una recensione del libro al servizio, la richiesta include il JWT del recensore, che contiene i gruppi e i ruoli (recensore o editore) a cui appartiene il recensore. Il corpo della richiesta contiene anche una query di mutazione GraphQL con i nuovi dati della recensione creata.

Diciamo che vuoi garantire le seguenti condizioni:

  • Solo i recensori possono inviare recensioni.
  • Un editore può modificare una recensione solo se è scritta da un recensore che appartiene allo stesso gruppo gestito da loro.
  • Solo gli editori possono segnare una recensione come “pronta per la pubblicazione”.

Ecco il diagramma che include le politiche sopra indicate:

L’AuthorizationPolicy di Istio sarà in difficoltà ad applicare le condizioni sopra indicate. La ragione è che Istio non può utilizzare il body della richiesta GraphQL per le autorizzazioni, che è un oggetto JSON insieme al JWT necessario per l’valutazione della politica.

OPA non ha limitazioni di questo genere. Può caricare qualsiasi dato per le verifiche di politica, e i DevOps possono scrivere queste regole in un modo più ergonomico usando Rego.

Video: Demo in Azione

Se preferisci guardare la demo in azione, per favore controlla il video sottostante:S

Supporto aziendale per l’integrazione di Istio

La maggior parte delle aziende utilizza OPA per definire e enforcare le politiche di autorizzazione per l’intero stack. Un meccanismo centrale per il controllo dell’accesso migliora la sicurezza complessiva e l’agilità delle squadre IT. Altrimenti, i sviluppatori perderanno tempo nell’implementare politiche di autorizzazione nel loro codice applicativo scritto in una determinata lingua, che impedisce la scalabilità e l’introduzione più rapida della logica aziendale.

Source:
https://dzone.com/articles/5-steps-to-integrate-istio-with-opa