O Alibaba Cloud Service Mesh (ASM) integra-se ao plug-in Open Policy Agent (OPA), permitindo definir políticas de controle de acesso refinadas para suas aplicações. Instâncias do ASM a partir da versão v1.8.6.41 suportam a configuração de um ConfigMap para enviar automaticamente políticas OPA aos pods, possibilitando atualizações dinâmicas. Este tópico mostra como atualizar dinamicamente políticas OPA no ASM.
Pré-requisitos
Instância do ASM na versão v1.8.6.41-gb1d8f288-aliyun ou posterior criada. Para mais informações, consulte Criar uma instância do ASM.
Cluster gerenciado ACK criado. Para mais informações, consulte Criar um cluster gerenciado ACK.
Informações de fundo
Hospedado pela CNCF como projeto em incubação, o Open Policy Agent (OPA) é um mecanismo de políticas que permite implementar controle de acesso refinado para suas aplicações. Como mecanismo de políticas de uso geral, o OPA pode ser implantado como serviço independente junto aos microsserviços. Para proteger uma aplicação, autorize cada requisição ao microsserviço. O microsserviço consulta a API do OPA para determinar se a requisição é permitida.
Etapa 1: Ativar o OPA
Faça login no console do ASM.
No painel de navegação à esquerda, escolha .
Na página Mesh Management, localize a instância do ASM desejada. Clique em nome da instância ou em Manage na coluna Actions.
Na página Basic Information, clique em Settings no canto superior direito.
No painel Settings Update, selecione Enable OPA plug-in.
-
Clique em OK.
Na página Basic Information, o status do OPA Plug-in muda para Enable.
Etapa 2: Criar ConfigMaps
O ASM suporta atualizações dinâmicas para políticas OPA. Configure um Service Mesh com o rótulo openpolicyagent.org/policy=rego. A política será então enviada automaticamente para todos os pods com sidecar OPA injetado em todos os namespaces. Remover o ConfigMap também remove a política dos pods.
Ao definir uma política OPA para um pod, inclua apenas um campo
default allow. Se vários ConfigMaps relacionados a políticas OPA se aplicarem a um pod e cada política definir um campodefault allow, os múltiplos camposdefault allowcausarão falha nas atualizações dinâmicas.O sidecar OPA depende de um ConfigMap chamado
opa-policypara iniciar. Excluir este ConfigMap remove a política OPA correspondente do sidecar. Recriar o ConfigMap não restaura a política. É necessário recriar o pod.
Obtenha o arquivo kubeconfig de um cluster e use kubectl para conectar-se ao cluster.
-
Crie um ConfigMap chamado opa-policy.
O sidecar OPA requer um ConfigMap chamado
opa-policypara iniciar. Este ConfigMap suporta atualizações dinâmicas. Utilize-o apenas para configurações básicas de política. Adicione políticas complexas dinamicamente por meio de outros ConfigMaps.-
Use o conteúdo a seguir para criar um arquivo YAML chamado opa-policy:
apiVersion: v1 kind: ConfigMap metadata: name: opa-policy data: policy.rego: | ### The paths allowed in this policy are required for dynamic OPA policy updates. If these paths are not configured, the updates will fail. package istio.authz import input.parsed_path allow { parsed_path[0] = "v1" parsed_path[1] = "policies" } -
Execute o comando a seguir para criar o ConfigMap:
kubectl apply -f opa-policy.yaml
-
-
Crie um ConfigMap chamado opa-policy-add.
Utilize este ConfigMap para definir sua política OPA.
-
Use o conteúdo a seguir para criar um arquivo YAML chamado opa-policy-add:
apiVersion: v1 kind: ConfigMap metadata: name: opa-policy-add labels: ### You must configure the following label in the ConfigMap. Otherwise, the OPA policy that the ConfigMap defines cannot be dynamically updated. openpolicyagent.org/policy: rego data: policy.rego: | ### The following code shows the definition of a sample policy. Define a policy based on your actual needs. package istio.authz import input.attributes.request.http as http_request default allow = false allow { roles_for_user[r] required_roles[r] } roles_for_user[r] { r := user_roles[user_name][_] } required_roles[r] { perm := role_perms[r][_] perm.method = http_request.method perm.path = http_request.path } user_name = parsed { [_, encoded] := split(http_request.headers.authorization, " ") [parsed, _] := split(base64url.decode(encoded), ":") } user_roles = { "guest1": ["guest"], "admin1": ["admin"] } role_perms = { "guest": [ {"method": "GET", "path": "/productpage"}, ], "admin": [ {"method": "GET", "path": "/productpage"}, {"method": "GET", "path": "/api/v1/products"}, ], }user_roles: Atribui funções aos usuários. Neste exemplo, a funçãoguesté atribuída aguest1e a funçãoadminaadmin1.role_perms: Define as permissões para cada função. Neste exemplo, a funçãoguestacessa a aplicação no caminho /productpage, e a funçãoadminacessa a aplicação nos caminhos /productpage e /api/v1/products.
-
Execute o comando a seguir para criar o ConfigMap:
kubectl apply -f opa-policy-add.yaml
-
-
Execute o comando a seguir para visualizar o resultado do envio da política:
O status do envio é atualizado nas
annotationsdo ConfigMap.kubectl get configmap opa-policy-add -o yamlVerifique o ConfigMap na saída do comando:
-
Se o envio for bem-sucedido, as seguintes informações aparecerão no ConfigMap.
openpolicyagent.org/policy-status: '{"status":"ok"}' Em caso de falha no envio, uma mensagem de erro correspondente será exibida.
-
Etapa 3: Injetar um sidecar OPA
Implante a aplicação de exemplo Bookinfo na instância do ASM e verifique se um sidecar OPA foi injetado em cada pod da aplicação Bookinfo.
Implante a aplicação de exemplo Bookinfo na instância do ASM. Para mais informações, consulte Implantar uma aplicação em uma instância do ASM.
Defina serviços virtuais Istio e um serviço de gateway de entrada conforme necessário. Para mais informações, consulte Roteamento de tráfego baseado em versão com Istio.
-
Verifique se um sidecar OPA foi injetado nos pods de cada aplicação dentro da aplicação Bookinfo.
Faça login no Console de Gerenciamento do Container Service.
No painel de navegação à esquerda, clique em Cluster.
Na página Cluster List, clique em nome do cluster de destino ou em Details na coluna Actions.
No painel de navegação à esquerda da página de gerenciamento do cluster, escolha .
-
Na página Pods, selecione default na lista suspensa Namespace e clique em nome do pod da aplicação alvo.
Na aba Containers, confirme a injeção de um proxy sidecar (istio-proxy) e de um sidecar OPA (opa-istio). Repita esta verificação para cada pod da aplicação.
Etapa 4: Verificar se a política OPA implementa o controle de acesso conforme esperado
-
Execute os comandos a seguir. Os resultados mostram que o usuário
guest1, com a funçãoguest, consegue acessar a aplicação em/productpage, mas tem o acesso negado em/api/v1/products.curl -X GET http://{{The IP address of the ingress gateway service}}/productpage --user guest1:password -ISaída esperada:
HTTP/1.1 200 OKcurl -X GET http://{{The IP address of the ingress gateway service}}/api/v1/products --user guest1:password -ISaída esperada:
HTTP/1.1 403 Forbidden -
Execute os comandos a seguir. Os resultados indicam que o usuário
admin1, com a funçãoadmin, consegue acessar a aplicação tanto no caminho/productpagequanto no caminho/api/v1/products.curl -X GET http://{{The IP address of the ingress gateway service}}/productpage --user admin1:password -ISaída esperada:
HTTP/1.1 200 OKcurl -X GET http://{{The IP address of the ingress gateway service}}/api/v1/products --user admin1:password -ISaída esperada:
HTTP/1.1 200 OKOs resultados anteriores indicam que a política OPA definida implementa o controle de acesso conforme esperado.
Etapa 5: Atualizar dinamicamente uma política OPA
-
Execute o comando a seguir no cluster ACK para atualizar o ConfigMap chamado opa-policy-add:
kubectl replace -n {The namespace where the ACK cluster resides} -f - <<EOF apiVersion: v1 kind: ConfigMap metadata: name: opa-policy-add labels: ### You must configure the following label in the ConfigMap. Otherwise, the OPA policy that the ConfigMap defines cannot be dynamically updated. openpolicyagent.org/policy: rego data: policy.rego: | ### The following code shows the definition of a sample policy. Define a policy based on your actual needs. package istio.authz import input.attributes.request.http as http_request default allow = false allow { roles_for_user[r] required_roles[r] } roles_for_user[r] { r := user_roles[user_name][_] } required_roles[r] { perm := role_perms[r][_] perm.method = http_request.method perm.path = http_request.path } user_name = parsed { [_, encoded] := split(http_request.headers.authorization, " ") [parsed, _] := split(base64url.decode(encoded), ":") } user_roles = { "guest1": ["guest", "admin"], "admin1": ["admin"] } role_perms = { "guest": [ {"method": "GET", "path": "/productpage"}, ], "admin": [ {"method": "GET", "path": "/productpage"}, {"method": "GET", "path": "/api/v1/products"}, ], } EOFuser_roles: Atribui funções aos usuários. Neste exemplo,guest1recebe as funçõesguesteadmin, enquantoadmin1mantém a funçãoadmin.role_perms: Define as permissões para cada função. Neste exemplo, a funçãoguestacessa a aplicação no caminho /productpage, e a funçãoadminacessa a aplicação nos caminhos /productpage e /api/v1/products.
-
Execute o comando a seguir para visualizar o resultado do envio da política:
O status do envio é atualizado nas
annotationsdo ConfigMap.kubectl get configmap opa-policy-add -o yamlVerifique o ConfigMap na saída do comando:
-
Se o envio for bem-sucedido, as seguintes informações aparecerão no ConfigMap.
openpolicyagent.org/policy-status: '{"status":"ok"}' Em caso de falha no envio, uma mensagem de erro correspondente será exibida.
-
Etapa 6: Verificar se uma política OPA foi atualizada dinamicamente
Execute os comandos curl a seguir. Os resultados indicam que a função admin foi atribuída ao usuário guest1. Além disso, o usuário guest1 agora tem permissão para acessar a aplicação usando uma URL que contém /productpage ou /api/v1/products.
curl -X GET http://{{The IP address of the ingress gateway service}}/productpage --user guest1:password -I
Saída esperada:
HTTP/1.1 200 OK
curl -X GET http://{{The IP address of the ingress gateway service}}/api/v1/products --user guest1:password -I
Saída esperada:
HTTP/1.1 200 OK
Antes da atualização da política OPA, o usuário guest1 conseguia acessar a aplicação usando uma URL contendo /productpage, mas não /api/v1/products. Após a atualização, o usuário guest1 consegue acessar a aplicação usando URLs contendo /productpage ou /api/v1/products. Esse resultado confirma que a política OPA foi atualizada dinamicamente.