Quando o controle de acesso dinâmico é necessário, você pode integrar um mecanismo Open Policy Agent (OPA) a um ingress gateway para personalizar políticas de autorização com base em identidades de usuário ou no conteúdo das requisições e controlar a comunicação entre services em tempo real. Isso previne acessos não autorizados, reduz os riscos de vazamento de dados e fortalece a segurança das aplicações em uma instância do Service Mesh (ASM). Este tópico descreve como usar um mecanismo OPA para autenticar e autorizar requisições recebidas por um ingress gateway. Neste exemplo, as requisições passam pelo ingress gateway para acessar a aplicação HTTPBin.
Pré-requisitos
Um cluster Kubernetes gerenciado adicionado a uma instância do ASM que executa a versão 1.15.3.25 ou posterior. Para obter instruções, consulte Add a cluster to an ASM instance e Upgrade an ASM instance.
A aplicação httpbin implantada e acessível por meio de um ingress gateway do ASM. Os comandos de teste neste tutorial enviam requisições para
${ASM_GATEWAY_IP}, que é o endereço IP desse gateway. Para obter instruções, consulte Deploy the httpbin application.A injeção automática de sidecar ativada para o namespace
default. Para obter instruções, consulte Configure a sidecar injection policy.
Etapa 1: Implantar o OPA
Implante um service de autorização OPA centralizado no cluster adicionado à sua instância do ASM.
-
Crie o arquivo
asm-opa.yamlcom o conteúdo a seguir. O arquivo YAML implanta um Service OPA, um Deployment OPA e um Secret.Substitua
cn-hangzhouna imagemregistry-vpc.cn-hangzhou.aliyuncs.com/acs/opa:0.46.1-istio-3-staticpela região do seu cluster antes de implantar o arquivo.O mecanismo OPA no Deployment ativa o registro de logs por padrão (
--set=decision_logs.console=true) para simplificar a depuração.O Secret define a política do OPA, que permite uma requisição em qualquer um dos seguintes casos:
O caminho da requisição é
health.O método da requisição é
HEAD.-
O nome de usuário é
alice.NotaO nome de usuário vem do cabeçalho
Authorizationda requisição, no formatoAuthorization: Basic ${Base64 encoding of the username:password string}.
asm-opa.yaml
apiVersion: v1 kind: Service metadata: name: asm-opa labels: app: opa spec: ports: - name: grpc port: 9191 targetPort: 9191 protocol: TCP - name: http port: 8181 targetPort: 8181 protocol: TCP selector: app: opa --- kind: Deployment apiVersion: apps/v1 metadata: name: opa labels: app: opa spec: replicas: 1 selector: matchLabels: app: opa template: metadata: labels: app: opa annotations: sidecar.istio.io/inject: "false" spec: containers: - name: opa image: registry-vpc.cn-hangzhou.aliyuncs.com/acs/opa:0.46.1-istio-3-static securityContext: runAsUser: 1111 volumeMounts: - readOnly: true mountPath: /policy name: opa-policy args: - "run" - "--server" - "--addr=0.0.0.0:8181" - "--diagnostic-addr=0.0.0.0:8282" - "--set=plugins.envoy_ext_authz_grpc.addr=:9191" - "--set=plugins.envoy_ext_authz_grpc.path=asm/authz/allow" - "--set=decision_logs.console=true" - "--ignore=.*" - "/policy/policy.rego" ports: - containerPort: 9191 protocol: TCP resources: limits: cpu: "0" memory: "0" volumes: - name: opa-policy secret: secretName: opa-policy --- apiVersion: v1 kind: Secret metadata: name: opa-policy type: Opaque stringData: policy.rego: | package asm.authz import future.keywords import input.attributes.request.http as http_request import input.parsed_path default allow := false allow if { parsed_path[0] == "health" } allow if { http_request.method == "HEAD" } allow if { user_name == "alice" } user_name := parsed if { [_, encoded] := split(http_request.headers.authorization, " ") [parsed, _] := split(base64url.decode(encoded), ":") }NotaOs valores de
resources.limitsneste exemplo são marcadores de posição. Definacpuememorycom valores adequados ao seu ambiente. -
Use o arquivo kubeconfig do cluster do Container Service for Kubernetes (ACK) para executar o comando a seguir e implantar o OPA.
kubectl apply -f asm-opa.yaml Confirme que o service de autorização OPA está disponível antes de continuar. O Deployment
opadeve estar pronto, e o Serviceasm-opadeve expor a porta9191para gRPC e a porta8181para HTTP.
Etapa 2: Usar o recurso de autorização externa do ingress gateway para integrar o mecanismo OPA ao ingress gateway
Faça login no console do ASM. No painel de navegação à esquerda, escolha .
Na página Mesh Management, clique no nome da instância do ASM. No painel de navegação à esquerda, escolha .
Na página Ingress Gateway, localize o gateway que deseja integrar ao OPA e clique em Gateway Security.
No painel de navegação à esquerda do gateway, escolha .
-
Configure um service de autorização personalizado.
-
No assistente Custom Authorization Service Configuration, configure o OPA como o service de autorização personalizado do gateway e clique em Next.
Ative o switch Enable Gateway Custom Authorization Service, selecione a aba Custom authorization service based on envoy.ext_authz (HTTP or gRPC), defina Protocol como GRPC, service address como
asm-opa.default.svc.cluster.local, service port como 9191 e timeout como 10 segundos. -
No assistente Matching Rules, configure as regras de correspondência para especifique quais requisições exigem autorização do OPA e clique em Submit.
Defina Matching Mode como Selected requests must be authorized, selecione Custom matching rules, ative HTTP Path (Path) e insira
/status/*.Uma mensagem é exibida confirmando que o Gateway Custom Authorization Service was created successfully e listando os recursos nativos do Istio criados: um ASMExtensionProvider (nome do recurso:
grpcextauth-asmsecuritypolicy-ingressgateway-extauthz) e um AuthorizationPolicy (nome do recurso:ingressgateway-extauthz-ap-wg-gateway-istio-system-gateway-ingressgateway). Clique em View YAML para visualize a configuração do recurso ou em Edit para modifique o service de autorização.
-
Etapa 3: Testar o acesso ao httpbin
Nos comandos a seguir, ${ASM_GATEWAY_IP} é o endereço IP do ingress gateway do ASM que expõe o httpbin. Cada comando usa -I para retornar apenas os cabeçalhos de resposta e -X GET para forçar o método GET, pois a política do OPA permite todas as requisições HEAD. Esses testes verificam a regra de nome de usuário da política do OPA.
-
Execute o comando a seguir para acessar o caminho
/.curl ${ASM_GATEWAY_IP}/ -I -X GET
HTTP/1,1 200 OK server: istio-envoy date: Tue, 25 Jul 2023 08:30:58 GMT content-type: text/html; charset=utf-8 content-length: 9593 access-control-allow-origin: * access-control-allow-credentials: true x-envoy-upstream-service-time: 2 — A resposta
200 OKindica que a requisição foi permitida. O caminho/não corresponde à regra de correspondência/status/*configurada na Etapa 2, portanto a requisição não é enviada ao OPA para autorização. -
Execute o comando a seguir para acessar o caminho
/status/201sem credenciais válidas.curl ${ASM_GATEWAY_IP}/status/201 -I -X GET
HTTP/1,1 403 Forbidden date: Tue, 25 Jul 2023 08:31:18 GMT server: istio-envoy content-length: 0 x-envoy-upstream-service-time: 1 — A resposta
403 Forbiddenindica que a requisição foi negada por não conter credenciais válidas. -
Execute o comando a seguir para acessar o caminho
/status/201com credenciais válidas.curl ${ASM_GATEWAY_IP}/status/201 -I -X GET --user alice:testpassword
HTTP/1,1 201 Created server: istio-envoy date: Tue, 25 Jul 2023 08:31:38 GMT content-type: text/html; charset=utf-8 access-control-allow-origin: * access-control-allow-credentials: true content-length: 0 x-envoy-upstream-service-time: 3 — A resposta
201 Createdconfirma que a requisição foi permitida por conter credenciais válidas do usuárioalice. Caso essa requisição retorne403 Forbidden, revise a implantação do OPA na Etapa 1 e a configuração da política de segurança do ASM na Etapa 2.
Etapa 4: Atualizar a política do OPA e retestar o acesso
Chame a API HTTP do mecanismo OPA para atualize a política do OPA em tempo de execução. O Secret opa-policy criado na Etapa 1 não é modificado e continua contendo a política original.
-
Execute o comando a seguir para atualize a política de modo que apenas o usuário
bobtenha permissão para acessar a aplicação, enquanto o usuárioalicepassa a ser negado.kubectl exec deployment/httpbin -c istio-proxy -- curl asm-opa:8181/v1/policies/policy/policy.rego -XPUT --data-binary 'package asm.authz import future.keywords import input.attributes.request.http as http_request import input.parsed_path default allow := false allow if { parsed_path[0] == "health" } allow if { http_request.method == "HEAD" } allow if { user_name == "bob" } user_name := parsed if { [_, encoded] := split(http_request.headers.authorization, " ") [parsed, _] := split(base64url.decode(encoded), ":") }' -
Execute o comando a seguir para acessar o httpbin como o usuário
bob.curl ${ASM_GATEWAY_IP}/status/201 -I -X GET --user bob:testpassword
HTTP/1,1 201 Created server: istio-envoy date: Tue, 25 Jul 2023 08:32:16 GMT content-type: text/html; charset=utf-8 access-control-allow-origin: * access-control-allow-credentials: true content-length: 0 x-envoy-upstream-service-time: 3 — A resposta
201 Createdindica que o usuáriobobacessou a aplicação com sucesso sob a política atualizada. -
Execute o comando a seguir para acessar o httpbin como o usuário
alice.curl ${ASM_GATEWAY_IP}/status/201 -I -X GET --user alice:testpassword
HTTP/1,1 403 Forbidden date: Tue, 25 Jul 2023 08:32:49 GMT server: istio-envoy content-length: 0 x-envoy-upstream-service-time: 1 — A resposta
403 Forbiddenindica que o acesso do usuárioalicefoi negado.