Cuando se requiere control de acceso dinámico, puede integrar un motor Open Policy Agent (OPA) en una puerta de enlace de entrada. Esto le permite personalizar las políticas de autorización según las identidades de los usuarios o el contenido de las solicitudes, además de controlar la comunicación entre servicios en tiempo real. De esta manera, se previene eficazmente el acceso no autorizado, se reducen los riesgos de filtración de datos y se mejora la seguridad de las aplicaciones en una instancia de Service Mesh (ASM). En este tema se describe cómo usar un motor OPA para autenticar y autorizar las solicitudes que recibe una puerta de enlace de entrada. En este ejemplo, las solicitudes fluyen a través de la puerta de enlace de entrada para acceder a la aplicación HTTPBin.
Requisitos previos
Se agregó un clúster de Kubernetes administrado a una instancia de ASM que ejecuta la versión 1.15.3.25 o posterior. Para consultar las instrucciones, consulte Add a cluster to an ASM instance y Upgrade an ASM instance.
La aplicación httpbin está desplegada y es accesible a través de una puerta de enlace de entrada de ASM. Los comandos de prueba de este tutorial envían solicitudes a
${ASM_GATEWAY_IP}, que es la dirección IP de dicha puerta de enlace. Para consultar las instrucciones, consulte Deploy the httpbin application.La inyección automática de sidecar está habilitada para el espacio de nombres
default. Para consultar las instrucciones, consulte Configure a sidecar injection policy.
Paso 1: Desplegar OPA
Despliegue un servicio de autorización OPA centralizado en el clúster que agregó a su instancia de ASM.
-
Cree el archivo
asm-opa.yamlcon el siguiente contenido. Este archivo YAML despliega un Service de OPA, un Deployment de OPA y un Secret.Antes de desplegar el archivo, reemplace
cn-hangzhouen la imagenregistry-vpc.cn-hangzhou.aliyuncs.com/acs/opa:0.46.1-istio-3-staticpor la región de su clúster.El motor OPA del Deployment habilita el registro de forma predeterminada (
--set=decision_logs.console=true) para simplificar la depuración.El Secret define la política de OPA, la cual permite una solicitud en cualquiera de los siguientes casos:
La ruta de la solicitud es
health.El método de la solicitud es
HEAD.-
El nombre de usuario es
alice.NotaEl nombre de usuario proviene del encabezado
Authorizationde la solicitud, con el 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), ":") }NotaLos valores de
resources.limitsen este ejemplo son marcadores de posición. Establezcacpuymemorycon los valores adecuados para su entorno. -
Use el archivo kubeconfig del clúster de Container Service for Kubernetes (ACK) para ejecutar el siguiente comando y desplegar OPA.
kubectl apply -f asm-opa.yaml Compruebe que el servicio de autorización OPA esté disponible antes de continuar. El Deployment
opadebe estar listo, y el Serviceasm-opadebe exponer el puerto9191para gRPC y el puerto8181para HTTP.
Paso 2: Usar la función de autorización externa de la puerta de enlace de entrada para integrar el motor OPA
Inicie sesión en la consola de ASM. En el panel de navegación izquierdo, elija .
En la página Mesh Management, haga clic en el nombre de la instancia de ASM. En el panel de navegación izquierdo, elija .
En la página Ingress Gateway, busque la puerta de enlace que desea integrar con OPA y haga clic en Gateway Security.
En el panel de navegación izquierdo de la puerta de enlace, elija .
-
Configure un servicio de autorización personalizado.
-
En el asistente Custom Authorization Service Configuration, configure OPA como el servicio de autorización personalizado de la puerta de enlace y luego haga clic en Next.
Active el interruptor Enable Gateway Custom Authorization Service, seleccione la pestaña Custom authorization service based on envoy.ext_authz (HTTP or gRPC), establezca Protocol en GRPC, service address en
asm-opa.default.svc.cluster.local, service port en 9191 y timeout en 10 segundos. -
En el asistente Matching Rules, configure las reglas de coincidencia para especificar qué solicitudes requieren autorización de OPA y luego haga clic en Submit.
Establezca Matching Mode en Selected requests must be authorized, seleccione Custom matching rules, active HTTP Path (Path) e introduzca
/status/*.Aparecerá un mensaje que confirma que el Gateway Custom Authorization Service was created successfully y enumera los recursos nativos de Istio creados: un ASMExtensionProvider (nombre del recurso:
grpcextauth-asmsecuritypolicy-ingressgateway-extauthz) y una AuthorizationPolicy (nombre del recurso:ingressgateway-extauthz-ap-wg-gateway-istio-system-gateway-ingressgateway). Puede hacer clic en View YAML para consultar la configuración del recurso o en Edit para modificar el servicio de autorización.
-
Paso 3: Probar el acceso a httpbin
En los siguientes comandos, ${ASM_GATEWAY_IP} es la dirección IP de la puerta de enlace de entrada de ASM que expone httpbin. Cada comando usa -I para devolver solo los encabezados de respuesta y -X GET para forzar el método GET, ya que la política de OPA permite todas las solicitudes HEAD. Estas pruebas validan la regla de nombre de usuario de la política de OPA.
-
Ejecute el siguiente comando para acceder a la ruta
/.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: 2La respuesta
200 OKindica que la solicitud se permitió. La ruta/no coincide con la regla/status/*que configuró en el paso 2, por lo que la solicitud no se envía a OPA para su autorización. -
Ejecute el siguiente comando para acceder a la ruta
/status/201sin credenciales 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: 1La respuesta
403 Forbiddenindica que la solicitud se rechazó porque no incluye credenciales válidas. -
Ejecute el siguiente comando para acceder a la ruta
/status/201con credenciales 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: 3La respuesta
201 Createdconfirma que la solicitud se permitió porque incluye credenciales válidas para el usuarioalice. Si esta solicitud también devuelve403 Forbidden, revise el despliegue de OPA en el paso 1 y la configuración de la política de seguridad de ASM en el paso 2.
Paso 4: Actualizar la política de OPA y volver a probar el acceso
Llame a la API HTTP del motor OPA para actualizar la política de OPA en tiempo de ejecución. El Secret opa-policy que creó en el paso 1 no se modifica y conserva la política original.
-
Ejecute el siguiente comando para actualizar la política. Con este cambio, solo el usuario
bobpodrá acceder a la aplicación y se denegará el acceso al usuarioalice.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), ":") }' -
Ejecute el siguiente comando para acceder a httpbin como el usuario
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: 3La respuesta
201 Createdmuestra que el usuariobobaccede correctamente a la aplicación con la política actualizada. -
Ejecute el siguiente comando para acceder a httpbin como el usuario
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: 1La respuesta
403 Forbiddenmuestra que se denegó el acceso del usuarioalice.