Panoramica dei criteri di autorizzazione
A differenza di un'applicazione monolitica che potrebbe essere eseguita in un'unica posizione, le app di microservizi distribuite a livello globale effettuano chiamate oltre i confini di rete. Ciò significa più punti di accesso alle tue applicazioni e più opportunità per attacchi dannosi. Poiché i pod Kubernetes hanno IP temporanei, le regole firewall convenzionali basate su IP non sono adeguate per proteggere l'accesso tra i carichi di lavoro. In un'architettura di microservizi, è necessario un nuovo approccio alla sicurezza. Basandosi su funzionalità di sicurezza come gli account di servizio Kubernetes e i criteri di sicurezza Istio, Cloud Service Mesh offre ancora più funzionalità per aiutarti a proteggere le tue applicazioni.
Questa pagina fornisce agli operatori delle applicazioni una panoramica della AuthorizationPolicy
risorsa personalizzata (CR). I criteri di autorizzazione consentono di attivare il controllo dell'accesso ai carichi di lavoro nei livelli applicazione (L7) e trasporto (L3/4). Configuri
i criteri di autorizzazione per specificare le autorizzazioni: cosa può fare questo servizio o utente?
Criteri di autorizzazione
Le richieste tra i servizi nel mesh (e tra gli utenti finali e i servizi) sono consentite per impostazione predefinita. Utilizzi la CR AuthorizationPolicy
per definire criteri granulari per i tuoi carichi di lavoro. Dopo aver applicato i criteri di autorizzazione,
Cloud Service Mesh li distribuisce ai proxy sidecar. Quando le richieste arrivano a un
carico di lavoro, il proxy sidecar controlla i criteri di autorizzazione per determinare se
la richiesta deve essere consentita o rifiutata.
Per informazioni dettagliate sui campi della AuthorizationPolicy
CR supportati dalla piattaforma, consulta Funzionalità supportate.
Ambito dei criteri
Puoi applicare un criterio all'intera mesh di servizi, a uno spazio dei nomi o a un singolo carico di lavoro.
Per applicare un criterio a tutta la mesh, specifica lo spazio dei nomi radice,
istio-system
, nel campometadata:namespace
:apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "mesh-wide" namespace: istio-system spec: ...
Per applicare un criterio a uno spazio dei nomi, specifica lo spazio dei nomi nel campo
metadata:namespace
:apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "currencyservice" namespace: currencyservice spec: ...
Per limitare una policy a un workload specifico, includi un campo
selector
.apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "frontend" namespace: demo spec: selector: matchLabels: app: frontend ...
Struttura di base
Un criterio di autorizzazione include l'ambito del criterio, un action
e un elenco di
rules
:
Come descritto nella sezione precedente, l'ambito del criterio può essere l'intero mesh, uno spazio dei nomi o un carico di lavoro specifico. Se lo includi, il campo
selector
specifica il target del criterio.Il campo
action
specifica seALLOW
oDENY
la richiesta. Se non specifichi un'azione, per impostazione predefinita viene impostata suALLOW
. Per chiarezza, ti consigliamo di specificare sempre l'azione. (Le norme di autorizzazione supportano anche le azioniAUDIT
eCUSTOM
. L'azioneAUDIT
è supportata solo su alcune piattaforme. Per maggiori dettagli, vedi Funzionalità supportate.rules
specifica quando attivare l'azione.Il campo
from
inrules
specifica le origini della richiesta.Il campo
to
inrules
specifica le operazioni della richiesta.Il campo
when
specifica le condizioni aggiuntive necessarie per applicare la regola.
Nel seguente esempio:
Il criterio viene applicato alle richieste al servizio
frontend
nello spazio dei nomidemo
.Le richieste sono consentite quando "hello:world" è nell'intestazione della richiesta; altrimenti, le richieste vengono rifiutate.
apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
name: "hello-world"
namespace: demo
spec:
selector:
matchLabels:
app: frontend
action: ALLOW
rules:
- when:
- key: request.headers[hello]
values: ["world"]
Controllo dell'accesso all'operazione di richiesta
Puoi controllare l'accesso a operazioni
specifiche
come metodi HTTP o porte TCP aggiungendo una sezione to
in rules
.
Nell'esempio seguente, solo i metodi HTTP GET
e POST
sono consentiti
per currencyservice
nello spazio dei nomi demo
.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: currencyservice
namespace: demo
spec:
selector:
matchLabels:
app: currencyservice
action: ALLOW
rules:
- to:
- operation:
methods: ["GET", "POST"]
Controllo dell'accesso all'identità autenticata
Negli esempi precedenti, le policy consentono richieste da carichi di lavoro non autenticati. Se hai abilitato l'autenticazione TLS reciproca (mTLS), puoi limitare l'accesso in base all'identità del workload o dello spazio dei nomi da cui proviene la richiesta nella sezione source
.STRICT
Utilizza il campo
principals
onotPrincipal
per controllare l'accesso a livello di carico di lavoro.Utilizza il campo
namespaces
onotNamespaces
per controllare l'accesso a livello di spazio dei nomi.
Tutti i campi precedenti richiedono l'abilitazione di STRICT
mTLS. Se non riesci a impostare mTLS STRICT
, consulta Rifiutare le richieste in testo normale per una soluzione alternativa.
Workload identificato
Nell'esempio seguente, le richieste a currencyservice
sono consentite solo
dal servizio frontend
. Le richieste a currencyservice
provenienti da altri
carichi di lavoro vengono rifiutate.
apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
name: "currencyservice"
namespace: demo
spec:
selector:
matchLabels:
app: currencyservice
action: ALLOW
rules:
- from:
- source:
principals: ["example-project-1234.svc.id.goog/ns/demo/sa/frontend-sa"]
Per specificare un account di servizio, principals
deve essere nel seguente formato:
principals: ["PROJECT_ID.svc.id.goog/ns/NAMESPACE/sa/SERVICE_ACCOUNT_NAME"]
Se utilizzi Cloud Service Mesh in-cluster con Citadel CA, allora
cluster.local
è il dominio di attendibilità. In tutti gli altri casi,
PROJECT_ID.svc.id.goog
è il dominio attendibile per la mesh.
Un dominio di attendibilità corrisponde alla radice di attendibilità di un sistema e fa parte di un'identità del carico di lavoro.
Cloud Service Mesh utilizza un dominio attendibile per creare tutte le identità all'interno di un mesh. Ad esempio, nell'ID SPIFFE
spiffe://mytrustdomain.com/ns/default/sa/myname
, la sottostringa
mytrustdomain.com
specifica che il workload proviene da un dominio di trust chiamato
mytrustdomain.com
.
Quando utilizzi l'autorità di certificazione Cloud Service Mesh, il dominio di attendibilità viene generato automaticamente da Cloud Service Mesh. Si basa sul pool di workload del cluster.
Puoi avere uno o più domini attendibili in un mesh multicluster, a condizione che i cluster condividano la stessa radice di attendibilità.
Spazio dei nomi identificato
L'esempio seguente mostra un criterio che nega le richieste se l'origine non è
lo spazio dei nomi foo
:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: httpbin-deny
namespace: foo
spec:
selector:
matchLabels:
app: httpbin
version: v1
action: DENY
rules:
- from:
- source:
notNamespaces: ["foo"]
Corrispondenza dei valori
La maggior parte dei campi nelle norme di autorizzazione supporta tutti i seguenti schemi di corrispondenza:
- Corrispondenza esatta: corrispondenza esatta della stringa.
- Corrispondenza con caratteri jolly utilizzando il carattere jolly
"*"
:- Corrispondenza del prefisso: una stringa che termina con
"*"
. Ad esempio,"test.example.*"
corrisponde a"test.example.com"
o"test.example.com.cn"
. - Corrispondenza del suffisso: una stringa che inizia con
"*"
. Ad esempio,"*.example.com"
corrisponde a"eng.example.com"
o"test.eng.example.com"
.
- Corrispondenza del prefisso: una stringa che termina con
- Corrispondenza di presenza: per specificare che un campo deve essere presente e non vuoto, utilizza
il formato
fieldname: ["*"]
. Questa opzione è diversa dal lasciare un campo non specificato, il che significa che corrisponde a qualsiasi valore, incluso quello vuoto.
Esistono alcune eccezioni. Ad esempio, i seguenti campi supportano solo la corrispondenza esatta:
- Il campo
key
nella sezionewhen
ipBlocks
nella sezionesource
- Il campo
ports
nella sezioneto
Il seguente criterio di esempio consente l'accesso ai percorsi con il prefisso /test/*
o il suffisso */info
:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: tester
namespace: default
spec:
selector:
matchLabels:
app: products
action: ALLOW
rules:
- to:
- operation:
paths: ["/test/*", "*/info"]
Corrispondenza delle esclusioni
Per trovare corrispondenze con condizioni negative come notValues
nel campo when
,
notIpBlocks
nel campo source
, notPorts
nel campo to
, Cloud Service Mesh
supporta la corrispondenza di esclusione. L'esempio seguente richiede una richiesta valida
principals
, derivata dall'autenticazione JWT, se il percorso della richiesta non è
/healthz
. Pertanto, il criterio esclude le richieste al percorso /healthz
dall'autenticazione JWT:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: disable-jwt-for-healthz
namespace: default
spec:
selector:
matchLabels:
app: products
action: ALLOW
rules:
- to:
- operation:
notPaths: ["/healthz"]
from:
- source:
requestPrincipals: ["*"]
Rifiutare le richieste in testo normale
In Cloud Service Mesh, mTLS automatico è abilitato per impostazione predefinita. Con mTLS automatico, un proxy sidecar lato client rileva automaticamente se il server ha un sidecar. Il sidecar client invia mTLS ai workload con sidecar e testo normale ai workload senza sidecar. Per una sicurezza ottimale, ti consigliamo di attivare mTLS STRICT.
Se non riesci ad attivare mTLS con la modalità STRICT
per un workload o
uno spazio dei nomi, puoi:
- crea una policy di autorizzazione per consentire esplicitamente il traffico con
namespaces
non vuoto oprincipals
non vuoto oppure - rifiutare il traffico con
namespaces
oprincipals
vuoti.
Poiché namespaces
e principals
possono essere estratti solo con una richiesta mTLS, questi criteri rifiutano effettivamente qualsiasi traffico in testo normale.
La seguente policy nega la richiesta se l'entità nella richiesta è
vuota (come nel caso delle richieste in testo normale). La policy consente
le richieste se l'entità non è vuota. ["*"]
indica una corrispondenza non vuota e
l'utilizzo con notPrincipals
indica la corrispondenza con un principal vuoto.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: require-mtls
namespace: NAMESPACE
spec:
action: DENY
rules:
- from:
- source:
notPrincipals: ["*"]
Precedenza dei criteri di autorizzazione
Puoi configurare criteri di autorizzazione ALLOW
e DENY
separati, ma devi comprendere la precedenza dei criteri e il comportamento predefinito per assicurarti che i criteri facciano ciò che vuoi. Il seguente diagramma descrive la precedenza delle norme.
Le norme di esempio nelle sezioni seguenti illustrano alcuni dei comportamenti predefiniti e le situazioni in cui potresti trovarle utili.
Non consentire nulla
L'esempio seguente mostra un criterio ALLOW
che non corrisponde a nulla. Per
impostazione predefinita, se non sono presenti altri criteri ALLOW
, le richieste vengono sempre rifiutate.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-nothing
spec:
action: ALLOW
È una buona pratica di sicurezza iniziare con la policy che non consente nulla e
aggiungere in modo incrementale altre policy ALLOW
per aprire più accessi a un workload.
Nega ogni accesso
L'esempio seguente mostra un criterio DENY
che corrisponde a tutto. Poiché i criteri
DENY
vengono valutati prima di quelli ALLOW
, tutte le richieste vengono rifiutate
anche se esiste un criterio ALLOW
che corrisponde alla richiesta.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: deny-all
spec:
action: DENY
rules:
- {}
Un criterio di negazione totale è utile se vuoi disattivare temporaneamente l'accesso a un carico di lavoro.
Consenti tutti gli accessi
L'esempio seguente mostra un criterio ALLOW
che corrisponde a tutto e consente l'accesso completo a un carico di lavoro. Il criterio allow-all rende inutili gli altri criteri ALLOW
perché consente sempre la richiesta.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-all
spec:
action: ALLOW
rules:
- {}
Una policy di tipo "consenti tutto" è utile se vuoi esporre temporaneamente l'accesso completo a un workload. Se sono presenti criteri DENY
, le richieste potrebbero comunque essere rifiutate
poiché i criteri DENY
vengono valutati prima dei criteri ALLOW
.
Best practice
Crea un account di servizio Kubernetes per ogni servizio e specifica ilaccount di serviziot nel deployment. Ad esempio:
apiVersion: v1 kind: ServiceAccount metadata: name: frontend-sa namespace: demo --- apiVersion: apps/v1 kind: Deployment metadata: name: frontend namespace:demo spec: selector: matchLabels: app: frontend template: metadata: labels: app: frontend spec: serviceAccountName: frontend-sa ...
Inizia con una policy che non consente nulla e aggiungi in modo incrementale altre policy
ALLOW
per aprire un maggiore accesso ai workload.Se utilizzi JWT per il tuo servizio:
Crea un criterio
DENY
per bloccare le richieste non autenticate, ad esempio:apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: requireJWT namespace: admin spec: action: DENY rules: - from: - source: notRequestPrincipals: ["*"]
Applica un criterio che non consente nulla.
Definisci le policy
ALLOW
per ogni carico di lavoro. Per esempi, vedi Token JWT.
Passaggi successivi
Scopri di più sulle funzionalità di sicurezza di Cloud Service Mesh:
- Configurazione dell'autenticazione utente di Cloud Service Mesh
- Configurazione dei criteri di audit per i tuoi servizi
- Configurazione della sicurezza del livello di trasporto
- Integrazione di Identity-Aware Proxy con Cloud Service Mesh
- Best practice per l'utilizzo dei gateway in uscita di Cloud Service Mesh su cluster GKE
Scopri di più sui criteri di autorizzazione nella documentazione di Istio: