Panoramica delle policy 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 della rete. Ciò significa più punti di accesso alle applicazioni e più opportunità per attacchi dannosi. Poiché i pod Kubernetes hanno IP temporanei, le regole firewall tradizionali basate su IP non sono adeguate per proteggere l'accesso tra i workload. In un'architettura di microservizi, è necessario un nuovo approccio alla sicurezza. Basandosi su funzionalità di sicurezza come i service account Kubernetes e le policy di sicurezza Istio, Cloud Service Mesh offre ancora più funzionalità per proteggere le applicazioni.
Questa pagina fornisce agli operatori delle applicazioni una panoramica della risorsa personalizzata AuthorizationPolicy. Le policy di autorizzazione consentono di abilitare il controllo dell'accesso sui workload nei livelli di applicazione (L7) e trasporto (L3/4). Devi configurare le policy di autorizzazione per specificare le autorizzazioni, ovvero cosa può fare un servizio o utente.
Policy di autorizzazione
Le richieste tra i servizi nel mesh (e tra gli utenti finali e i servizi) sono
consentite per impostazione predefinita. Utilizza la risorsa personalizzata AuthorizationPolicy per definire policy granulari per i tuoi workload. Dopo aver applicato le policy di autorizzazione, Cloud Service Mesh le distribuisce ai proxy sidecar. Quando le richieste arrivano a un workload, il proxy sidecar controlla le policy di autorizzazione per determinare se la richiesta deve essere consentita o negata.
Per informazioni dettagliate sui campi della risorsa personalizzata AuthorizationPolicy supportati dalla piattaforma, consulta Funzionalità supportate.
Ambito delle policy
Puoi applicare una policy all'intero mesh di servizi, a uno spazio dei nomi o a un singolo workload.
Per applicare una policy a livello di 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 una policy a uno spazio dei nomi, specificalo 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
Una policy di autorizzazione include l'ambito della policy, una risorsa action e un elenco di rules:
Come descritto nella sezione precedente, l'ambito della policy può essere l'intero mesh, uno spazio dei nomi o un workload specifico. Se lo includi, il campo
selectorspecifica il target della policy.Il campo
actionspecifica se consentire (ALLOW) o negare (DENY) la richiesta. Se non specifichi un'azione, il campo viene preimpostato suALLOW. Per chiarezza, consigliamo di specificare sempre l'azione. Le policy di autorizzazione supportano anche le azioniAUDITeCUSTOM. L'azioneAUDITè supportata solo su alcune piattaforme. Per ulteriori dettagli, vedi Funzionalità supportate.rulesspecifica quando attivare l'azione.Il campo
frominrulesspecifica le origini della richiesta.Il campo
toinrulesspecifica le operazioni della richiesta.Il campo
whenspecifica le condizioni aggiuntive necessarie per applicare la regola.
Nel seguente esempio:
La policy viene applicata alle richieste inviate al servizio
frontendnello spazio dei nomidemo.Le richieste sono consentite quando "hello:world" è nell'intestazione della richiesta; in caso contrario, 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 di richiesta 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 le richieste da workload non autenticati. Se hai abilitato mutual TLS (mTLS) in modalità STRICT, puoi limitare l'accesso in base all'identità del workload o dello spazio dei nomi da cui proviene la richiesta nella sezione source.
Utilizza il campo
principalsonotPrincipalper controllare l'accesso a livello di workload.Utilizza il campo
namespacesonotNamespacesper controllare l'accesso a livello di spazio dei nomi.
Tutti i campi precedenti richiedono l'abilitazione di mTLS STRICT. Se non riesci
a impostare mTLS STRICT, consulta
Rifiuta le richieste in testo non crittografato 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
workload 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 service account, 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 attendibile. In tutti gli altri casi,
PROJECT_ID.svc.id.googè il dominio attendibile per il mesh.
Spazio dei nomi identificato
L'esempio seguente mostra una policy 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 policy di autorizzazione supporta tutti i seguenti schemi di corrispondenza:
- Corrispondenza esatta: corrispondenza esatta della stringa.
- Corrispondenza con carattere 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 rispetto a lasciare un campo non specificato, che significa che qualsiasi valore è corrisponde, inclusi quelli vuoti.
Esistono alcune eccezioni. Ad esempio, i seguenti campi supportano solo la corrispondenza esatta:
- Il campo
keynella sezionewhen ipBlocksnella sezionesource- Il campo
portsnella sezioneto
La seguente policy 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 delle esclusioni. L'esempio seguente richiede una richiesta valida
principals, derivata dall'autenticazione JWT, se il percorso della richiesta non è
/healthz. Di conseguenza, la policy 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: ["*"]
Rifiuta le richieste in testo non crittografato
In Cloud Service Mesh, auto mTLS è abilitato per impostazione predefinita. Con auto mTLS, un proxy sidecar lato client rileva automaticamente se il server ha un sidecar. Il sidecar client invia mTLS ai workload con sidecar e invia testo non crittografato ai workload senza sidecar. Per una maggiore sicurezza, ti consigliamo di abilitare mTLS STRICT.
Se non puoi abilitare mTLS in modalità STRICT per un workload o
uno spazio dei nomi, puoi:
- creare una policy di autorizzazione per consentire esplicitamente il traffico con
namespacesnon vuoto oprincipalsnon vuoto oppure - rifiutare il traffico con
namespacesoprincipalsvuoti.
Poiché namespaces e principals possono essere estratti solo con una richiesta mTLS, queste policy rifiutano effettivamente qualsiasi traffico in testo non crittografato.
La seguente policy nega la richiesta se l'entità nella richiesta è
vuota (come nel caso delle richieste in testo non crittografato). 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'entità vuoto.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: require-mtls
namespace: NAMESPACE
spec:
action: DENY
rules:
- from:
- source:
notPrincipals: ["*"]
Precedenza delle policy di autorizzazione
Puoi configurare policy di autorizzazione ALLOW e DENY separate, ma devi comprendere la precedenza delle policy e il comportamento predefinito per assicurarti che le policy facciano ciò che vuoi. Il seguente diagramma descrive la precedenza delle policy.
Le policy 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 una policy ALLOW che non fa corrispondere nulla. Per impostazione predefinita, se non sono presenti altre policy 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 una policy DENY che fa corrispondere tutto. Poiché le policy DENY vengono valutate prima delle policy ALLOW, tutte le richieste vengono rifiutate, anche se esiste una policy ALLOW che corrisponde alla richiesta.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: deny-all
spec:
action: DENY
rules:
- {}
Una policy per negare tutto è utile se vuoi disabilitare temporaneamente l'accesso a un workload.
Consenti tutti gli accessi
L'esempio seguente mostra una policy ALLOW che fa corrispondere tutto e consente l'accesso completo a un workload. La policy "allow-all" rende inutili le altre policy 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 "allow-all" è utile se vuoi esporre temporaneamente l'accesso completo a un workload. Se esistono policy DENY, le richieste potrebbero comunque essere rifiutate in quanto le policy DENY vengono valutate prima delle policy ALLOW.
Best practice
Crea un service account Kubernetes per ogni servizio e specifica il service account 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
ALLOWper aprire un maggiore accesso ai workload.Se utilizzi JWT per il servizio:
Crea una policy
DENYper 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 una policy che non consente nulla.
Definisci le policy
ALLOWper ogni workload. Per gli 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 delle policy di audit per i 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ù sulle policy di autorizzazione nella documentazione di Istio: