Visão geral da política de autorização
Ao contrário de um aplicativo monolítico que pode estar em execução em um só lugar, os aplicativos de microsserviços distribuídos globalmente fazem chamadas além dos limites da rede. Isso significa mais pontos de entrada nos seus aplicativos e mais oportunidades de ataques mal-intencionados. Como os pods do Kubernetes têm IPs temporários, as regras de firewall tradicionais baseadas em IP não são adequadas para proteger o acesso entre as cargas de trabalho. Em uma arquitetura de microsserviços, é necessária uma nova abordagem de segurança. Desenvolver recursos de segurança como Contas de serviço do Kubernetes e as políticas de segurança do Istio, o Cloud Service Mesh oferece ainda mais recursos para ajudar você a proteger seus aplicativos conteinerizados.
Nesta página, os operadores do aplicativo têm uma visão geral do recurso personalizado (CR, da sigla em inglês) AuthorizationPolicy
. As políticas de autorização permitem ativar o controle de acesso nas cargas de trabalho nas camadas de aplicativo (L7) e transporte (L3/4). Você configura políticas de autorização para especificar permissões: o que esse serviço ou usuário pode fazer?
Políticas de autorização
As solicitações entre serviços na sua malha (e entre usuários finais e serviços) são
permitidas por padrão. Use o recurso personalizado AuthorizationPolicy
para definir políticas granulares para as cargas de trabalho. Depois de aplicar as políticas de autorização,
O Cloud Service Mesh os distribui para os proxies sidecar. À medida que as solicitações entram em uma carga de trabalho, o proxy sidecar verifica as políticas de autorização para determinar se a solicitação precisa ser permitida ou negada.
Escopo da política
É possível aplicar uma política a toda a malha de serviço, a um namespace ou a uma carga de trabalho individual.
Para aplicar uma política em toda a malha, especifique o namespace raiz,
istio-system
, no campometadata:namespace
:apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "mesh-wide" namespace: istio-system spec: ...
Para aplicar uma política a um namespace, especifique-o no campo
metadata:namespace
:apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "currencyservice" namespace: currencyservice spec: ...
Para restringir uma política a uma carga de trabalho específica, inclua um campo
selector
.apiVersion: "security.istio.io/v1beta1" kind: "AuthorizationPolicy" metadata: name: "frontend" namespace: demo spec: selector: matchLabels: app: frontend ...
Estrutura básica
Uma política de autorização inclui o escopo da política, um action
e uma lista de rules
:
Conforme descrito na seção anterior, o escopo da política pode ser toda a malha, um namespace ou uma carga de trabalho específica. Se você incluí-la, o campo
selector
especificará o destino da política.O campo
action
especifica se iráALLOW
ouDENY
a solicitação. Se você não especificar uma ação, por padrão, ela será definida comoALLOW
. Para maior clareza, recomendamos que você sempre especifique a ação. As políticas de autorização também são compatíveis com açõesAUDIT
eCUSTOM
.O
rules
especificar quando acionar a ação.
No exemplo a seguir:
A política é aplicada às solicitações para o serviço
frontend
no namespacedemo
.As solicitações serão permitidas quando "hello:world" estiver no cabeçalho da solicitação. Caso contrário, as solicitações serão negadas.
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"]
Controle de acesso na operação de solicitação
Controle o acesso a operações de solicitações específicas, como métodos HTTP ou portas TCP, adicionando uma seção to
em rules
.
No exemplo a seguir, apenas os métodos HTTP GET
e POST
são permitidos para o currencyservice
no namespace 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"]
Controle de acesso na identidade autenticada
Nos exemplos anteriores, as políticas permitem solicitações de cargas de trabalho não autenticadas. Se você tiver
TLS mútuo STRICT
(mTLS) ativado,
será possível restringir o acesso com base na identidade da carga de trabalho ou do namespace de origem da solicitação na seção
source
.
Use o campo
principals
ounotPrincipal
para controlar o acesso no nível da carga de trabalho.Use o campo
namespaces
ounotNamespaces
para controlar o acesso no nível do namespace.
Todos os campos acima exigem que você tenha mTLS STRICT
ativado. Se não for possível definir o mTLS STRICT
, consulte Rejeitar solicitações de texto simples para uma solução alternativa.
Carga de trabalho identificada
No exemplo a seguir, as solicitações para currencyservice
são permitidas somente a partir do serviço frontend
. As solicitações para currencyservice
de outras
cargas de trabalho são negadas.
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"]
Para especificar uma conta de serviço, o principals
da
autoridade certificadora do Cloud Service Mesh (CA da malha)
e do Certificate Authority Service
(serviço de CA) precisam ter o seguinte formato:
principals: ["PROJECT_ID.svc.id.goog/ns/NAMESPACE/sa/SERVICE_ACCOUNT_NAME"]
PROJECT_ID.svc.id.goog
é o domínio de confiança para a Mesh CA. Se você estiver
usando a CA do Istio (anteriormente conhecida como Citadel), o domínio de confiança padrão será
cluster.local
.
Namespace identificado
O exemplo a seguir mostra uma política que nega solicitações se a origem não
for o namespace 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"]
Correspondência de valor
A maioria dos campos nas políticas de autorização aceita todos os seguintes esquemas de correspondência:
- Correspondência exata: correspondência de string exata.
- Correspondência de caracteres curinga com o caractere curinga
"*"
:- Correspondência de prefixo: uma string com um
"*"
no final. Por exemplo,"test.example.*"
corresponde a"test.example.com"
ou"test.example.com.cn"
. - Correspondência de sufixo: uma string com um
"*"
no início. Por exemplo,"*.example.com"
corresponde a"eng.example.com"
ou"test.eng.example.com"
.
- Correspondência de prefixo: uma string com um
- Correspondência de presença: para especificar que um campo precisa estar presente e não vazio, use o formato
fieldname: ["*"]
. Isso é diferente de deixar um campo não especificado, o que significa corresponder a qualquer coisa, incluindo vazio.
Existem algumas exceções. Por exemplo, os campos a seguir são compatíveis apenas com correspondência exata:
- O campo
key
na seçãowhen
- O
ipBlocks
na seçãosource
- O campo
ports
na seçãoto
A política de exemplo a seguir permite acesso em caminhos com o prefixo /test/*
ou o sufixo */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"]
Correspondência de exclusão
Para corresponder a condições negativas como notValues
no campo when
,
notIpBlocks
no campo source
, notPorts
no campo to
, Cloud Service Mesh
oferece suporte à correspondência de exclusão. O exemplo a seguir requer um principals
de solicitação válido, que é derivado da autenticação JWT, se o caminho da solicitação não for /healthz
. Assim, a política exclui solicitações para o caminho /healthz
da autenticação 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: ["*"]
Rejeitar solicitações de texto simples
No Cloud Service Mesh 1.5 e mais recente, o mTLS automático é ativado por padrão. Com o mTLS automático, um proxy sidecar do cliente detecta automaticamente se o servidor tem um sidecar. O sidecar do cliente envia o mTLS para as cargas de trabalho que têm sidecars e texto simples para as que não têm. Para ter a melhor segurança, recomendamos ativar o mTLS STRICT.
Se não for possível ativar mTLS com o modo STRICT
para uma carga de trabalho ou
namespace, você pode:
- criar uma política de autorização para permitir explicitamente o tráfego com
namespaces
não vazio ouprincipals
não vazio ou - rejeitar tráfego com
namespaces
ouprincipals
vazios;
Como namespaces
e principals
só podem ser extraídos com uma solicitação mTLS, essas políticas rejeitam efetivamente qualquer tráfego de texto simples.
A política a seguir negará a solicitação se o principal dela estiver vazio, como é o caso das solicitações de texto simples. A política permitirá solicitações se o principal não estiver vazio. O ["*"]
significa uma correspondência não vazia e, quando usado com notPrincipals
, significa correspondência no principal vazio.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: require-mtls
namespace: NAMESPACE
spec:
action: DENY
rules:
- from:
- source:
notPrincipals: ["*"]
Precedência da política de autorização
É possível configurar políticas de autorização ALLOW
e DENY
separadas, mas você precisa entender a precedência da política e o comportamento padrão para garantir que elas façam o que você quer. O diagrama a seguir descreve a precedência da política.
As políticas de exemplo nas seções a seguir ilustram alguns dos comportamentos e situações padrão em que você pode considerá-las úteis.
Não permitir nada
O exemplo a seguir mostra uma política ALLOW
que não corresponde a nada. Por padrão, se não houver outras políticas ALLOW
, as solicitações serão sempre negadas.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-nothing
spec:
action: ALLOW
É uma boa prática de segurança começar com a política de não permitir nada e adicionar gradualmente outras políticas ALLOW
para abrir mais acesso a uma carga de trabalho.
Negar todo o acesso
O exemplo a seguir mostra uma política DENY
que corresponde a tudo. Como as políticas DENY
são avaliadas antes das políticas ALLOW
, todas as solicitações são negadas, mesmo que haja uma política ALLOW
que corresponda à solicitação.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: deny-all
spec:
action: DENY
rules:
- {}
Esse tipo de política é útil se você quiser desativar temporariamente todo o acesso a uma carga de trabalho.
Permitir todo o acesso
O exemplo a seguir mostra uma política ALLOW
que corresponde a tudo e permite acesso total a uma carga de trabalho. A política de permissão total torna outras políticas ALLOW
inúteis, porque sempre permite a solicitação.
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: allow-all
spec:
action: ALLOW
rules:
- {}
Esse tipo de política é útil se você quiser expor temporariamente o acesso total a uma carga de trabalho. Se houver alguma política DENY
, as solicitações ainda poderão ser negadas
porque as políticas DENY
são avaliadas antes das políticas ALLOW
.
Práticas recomendadas
Crie uma conta de serviço do Kubernetes para cada serviço e especifique-a na implantação. Exemplo:
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 ...
Comece com uma política de não permitir nada e adicione progressivamente outras políticas
ALLOW
para abrir mais acesso às cargas de trabalho.Se você estiver usando JWTs para o serviço:
Crie uma política
DENY
para bloquear solicitações não autenticadas, por exemplo:apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: requireJWT namespace: admin spec: action: DENY rules: - from: - source: notRequestPrincipals: ["*"]
Aplique uma política de não permitir nada.
Defina políticas
ALLOW
para cada carga de trabalho. Para exemplos, consulte Token JWT.
A seguir
Saiba mais sobre os recursos de segurança do Cloud Service Mesh:
- Como configurar a autenticação do usuário do Cloud Service Mesh
- Como configurar políticas de auditoria em serviços
- Como configurar a segurança de transporte
- Como integrar o Identity-Aware Proxy ao Cloud Service Mesh
- Práticas recomendadas para usar gateways de saída do Cloud Service Mesh em clusters do GKE
Saiba mais sobre as políticas de autorização na documentação do Istio: