Vuelta a los microservicios con Istio. Parte 3

Vuelta a los microservicios con Istio. Parte 3

Nota. traducir: La primera parte Esta serie se dedicó a conocer las capacidades de Istio y demostrarlas en acción. segundo — enrutamiento y gestión del tráfico de red ajustados con precisión. Ahora hablaremos de seguridad: para demostrar las funciones básicas relacionadas con ella, el autor utiliza el servicio de identidad Auth0, pero otros proveedores se pueden configurar de forma similar.

Configuramos un clúster de Kubernetes en el que implementamos Istio y una aplicación de microservicio de ejemplo, Sentiment Analysis, para demostrar las capacidades de Istio.

Con Istio, pudimos mantener nuestros servicios pequeños porque no necesitan implementar capas como reintentos, tiempos de espera, disyuntores, seguimiento y monitoreo. Además, utilizamos técnicas avanzadas de prueba e implementación: pruebas A/B, duplicación y implementaciones canary.

Vuelta a los microservicios con Istio. Parte 3

En el nuevo material, abordaremos las capas finales del camino hacia el valor empresarial: autenticación y autorización, ¡y en Istio es un verdadero placer!

Autenticación y autorización en Istio

Nunca hubiera creído que la autenticación y la autorización me inspirarían. ¿Qué puede ofrecer Istio desde una perspectiva tecnológica para que estos temas sean divertidos y, aún más, inspiradores para ti?

La respuesta es simple: Istio transfiere la responsabilidad de estas capacidades de sus servicios al proxy Envoy. Cuando las solicitudes llegan a los servicios, ya han sido autenticadas y autorizadas, por lo que todo lo que tiene que hacer es escribir un código útil para el negocio.

¿Suena bien? ¡Echemos un vistazo al interior!

Autenticación con Auth0

Como servidor para la gestión de identidades y accesos usaremos Auth0, que tiene una versión de prueba, es intuitivo de usar y simplemente me gusta. Sin embargo, los mismos principios se pueden aplicar a cualquier otro Implementaciones de OpenID Connect: KeyCloak, IdentityServer y muchos otros.

Para comenzar, vaya a Portal de autenticación0 con tu cuenta, crea un inquilino (inquilino - “inquilino”, unidad lógica de aislamiento, para más detalles ver documentación - aprox. trad.) E ir a Aplicaciones > Aplicación predeterminadaelegir Dominio, como se muestra en la siguiente captura de pantalla:

Vuelta a los microservicios con Istio. Parte 3

Especifique este dominio en el archivo resource-manifests/istio/security/auth-policy.yaml (codigo fuente):

apiVersion: authentication.istio.io/v1alpha1
kind: Policy
metadata:
  name: auth-policy
spec:
  targets:
  - name: sa-web-app
  - name: sa-feedback
  origins:
  - jwt:
      issuer: "https://{YOUR_DOMAIN}/"
      jwksUri: "https://{YOUR_DOMAIN}/.well-known/jwks.json"
  principalBinding: USE_ORIGIN

Con tal recurso, Pilot (uno de los tres componentes básicos del plano de control en Istio - traducción aproximada) configura Envoy para autenticar solicitudes antes de reenviarlas a los servicios: sa-web-app и sa-feedback. Al mismo tiempo, la configuración no se aplica al servicio Envoys. sa-frontend, permitiéndonos dejar la interfaz sin autenticar. Para aplicar la Política, ejecute el comando:

$ kubectl apply -f resource-manifests/istio/security/auth-policy.yaml
policy.authentication.istio.io “auth-policy” created

Regrese a la página y haga una solicitud; verá que termina con el estado 401 no autorizado. Ahora redirijamos a los usuarios del frontend para que se autentiquen con Auth0.

Autenticar solicitudes con Auth0

Para autenticar las solicitudes de los usuarios finales, debe crear una API en Auth0 que representará los servicios autenticados (reseñas, detalles y calificaciones). Para crear una API, vaya a Portal Auth0 > API > Crear API y llena el formulario:

Vuelta a los microservicios con Istio. Parte 3

La información importante aquí es Identificador, que usaremos más adelante en el script. Escribámoslo así:

  • Público: {TU_AUDIENCIA}

Los detalles restantes que necesitamos se encuentran en el Portal Auth0 en la sección Aplicaciones - Seleccione Aplicación de prueba (creado automáticamente junto con la API).

Aquí escribiremos:

  • Dominio: {TU DOMINIO}
  • Identificación del cliente: {TU_CLIENTE_ID}

Desplácese hasta Aplicación de prueba al campo de texto URL de devolución de llamada permitidas (URL resueltas para la devolución de llamada), en el que especificamos la URL donde se debe enviar la llamada una vez completada la autenticación. En nuestro caso es:

http://{EXTERNAL_IP}/callback

Y para URL de cierre de sesión permitidas (URL permitidas para cerrar sesión) agregue:

http://{EXTERNAL_IP}/logout

Pasemos a la interfaz.

Actualización de interfaz

Cambiar a sucursal auth0 repositorio [istio-mastery]. En esta rama, el código de interfaz se cambia para redirigir a los usuarios a Auth0 para la autenticación y usar el token JWT en solicitudes a otros servicios. Este último se implementa de la siguiente manera (Aplicación.js):

analyzeSentence() {
    fetch('/sentiment', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${auth.getAccessToken()}` // Access Token
        },
        body: JSON.stringify({ sentence: this.textField.getValue() })
    })
        .then(response => response.json())
        .then(data => this.setState(data));
}

Para cambiar la interfaz para usar datos de inquilinos en Auth0, abra sa-frontend/src/services/Auth.js y reemplace en él los valores que escribimos arriba (autenticación.js):

const Config = {
    clientID: '{YOUR_CLIENT_ID}',
    domain:'{YOUR_DOMAIN}',
    audience: '{YOUR_AUDIENCE}',
    ingressIP: '{EXTERNAL_IP}' // Используется для редиректа после аутентификации
}

La aplicación está lista. Especifique su ID de Docker en los siguientes comandos al crear e implementar los cambios realizados:

$ docker build -f sa-frontend/Dockerfile 
 -t $DOCKER_USER_ID/sentiment-analysis-frontend:istio-auth0 
 sa-frontend

$ docker push $DOCKER_USER_ID/sentiment-analysis-frontend:istio-auth0

$ kubectl set image deployment/sa-frontend 
 sa-frontend=$DOCKER_USER_ID/sentiment-analysis-frontend:istio-auth0

¡Prueba la aplicación! Serás redirigido a Auth0, donde deberás iniciar sesión (o registrarte), después de lo cual serás enviado de regreso a la página desde donde se realizarán las solicitudes ya autenticadas. Si prueba los comandos mencionados en las primeras partes del artículo con curl, obtendrá el código 401 Código de estado, indicando que la solicitud no está autorizada.

Demos el siguiente paso: autorizar solicitudes.

Autorización con Auth0

La autenticación nos permite entender quién es un usuario, pero se requiere autorización para saber a qué tiene acceso. Istio también ofrece herramientas para esto.

Como ejemplo, creemos dos grupos de usuarios (consulte el diagrama a continuación):

  • Miembros (usuarios) — con acceso únicamente a los servicios SA-WebApp y SA-Frontend;
  • Moderadores (moderadores) — con acceso a los tres servicios.

Vuelta a los microservicios con Istio. Parte 3
Concepto de autorización

Para crear estos grupos, usaremos la extensión de autorización Auth0 y usaremos Istio para proporcionarles diferentes niveles de acceso.

Instalación y configuración de Autorización Auth0

En el portal Auth0, vaya a extensiones (Prórrogas de tiempo para presentar declaraciones de impuestos) e instalar Autorización Auth0. Después de la instalación, vaya a Extensión de autorización, y allí - a la configuración del inquilino haciendo clic en la parte superior derecha y seleccionando la opción de menú adecuada (Configuración). Activar grupos (Grupos) y haga clic en el botón publicar regla (Regla de publicación).

Vuelta a los microservicios con Istio. Parte 3

Crear grupos

En Extensión de autorización vaya a Grupos y crear un grupo Moderan. Dado que trataremos a todos los usuarios autenticados como usuarios normales, no es necesario crear un grupo adicional para ellos.

Elige un grupo Moderan, Prensa Añadir miembros, agrega tu cuenta principal. Deje a algunos usuarios sin ningún grupo para asegurarse de que se les niegue el acceso. (Los nuevos usuarios se pueden crear manualmente a través de Portal Auth0 > Usuarios > Crear usuario.)

Agregar reclamo de grupo al token de acceso

Se han agregado usuarios a grupos, pero esta información también debe reflejarse en los tokens de acceso. Para cumplir con OpenID Connect y al mismo tiempo devolver los grupos que necesitamos, el token deberá agregar el suyo propio reclamo personalizado. Implementado a través de reglas Auth0.

Para crear una regla, vaya al Portal Auth0 para Reglas, Prensa Crear regla y seleccione una regla vacía de las plantillas.

Vuelta a los microservicios con Istio. Parte 3

Copie el código a continuación y guárdelo como una nueva regla. Agregar reclamo de grupo (namespacedGroup.js):

function (user, context, callback) {
    context.accessToken['https://sa.io/group'] = user.groups[0];
    return callback(null, user, context);
}

Nota: este código toma el primer grupo de usuarios definido en la Extensión de autorización y lo agrega al token de acceso como un reclamo personalizado (bajo su espacio de nombres, según lo requiere Auth0).

Volver a la página Reglas y comprueba que tienes dos reglas escritas en el siguiente orden:

  • extensión-autorización-auth0
  • Agregar reclamo de grupo

El orden es importante porque el campo del grupo recibe la regla de forma asincrónica extensión-autorización-auth0 y después se añade como pretensión por la segunda regla. El resultado es un token de acceso como este:

{
 "https://sa.io/group": "Moderators",
 "iss": "https://sentiment-analysis.eu.auth0.com/",
 "sub": "google-oauth2|196405271625531691872"
 // [сокращено для наглядности]
}

Ahora necesita configurar el proxy Envoy para verificar el acceso de los usuarios, para lo cual el grupo será retirado del reclamo (https://sa.io/group) en el token de acceso devuelto. Este es el tema de la siguiente sección del artículo.

Configuración de autorización en Istio

Para que la autorización funcione, debe habilitar RBAC para Istio. Para ello utilizaremos la siguiente configuración:

apiVersion: "rbac.istio.io/v1alpha1"
kind: RbacConfig
metadata:
  name: default
spec:
  mode: 'ON_WITH_INCLUSION'                     # 1
  inclusion:
    services:                                   # 2
    - "sa-frontend.default.svc.cluster.local"
    - "sa-web-app.default.svc.cluster.local"
    - "sa-feedback.default.svc.cluster.local" 

Explicación:

  • 1: habilite RBAC solo para los servicios y espacios de nombres enumerados en el campo Inclusion;
  • 2 — enumeramos una lista de nuestros servicios.

Apliquemos la configuración con el siguiente comando:

$ kubectl apply -f resource-manifests/istio/security/enable-rbac.yaml
rbacconfig.rbac.istio.io/default created

Todos los servicios ahora requieren control de acceso basado en roles. En otras palabras, el acceso a todos los servicios está prohibido y dará lugar a una respuesta. RBAC: access denied. Ahora permitamos el acceso a usuarios autorizados.

Configuración de acceso para usuarios habituales.

Todos los usuarios deben tener acceso a los servicios SA-Frontend y SA-WebApp. Implementado utilizando los siguientes recursos de Istio:

  • Función de servicio — determina los derechos que tiene el usuario;
  • Enlace de funciones de servicio — determina a quién pertenece este ServiceRole.

Para los usuarios comunes permitiremos el acceso a ciertos servicios (función de servicio.yaml):

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
  name: regular-user
  namespace: default
spec:
  rules:
  - services: 
    - "sa-frontend.default.svc.cluster.local" 
    - "sa-web-app.default.svc.cluster.local"
    paths: ["*"]
    methods: ["*"]

Y a través de regular-user-binding aplicar ServiceRole a todos los visitantes de la página (enlace-de-roles-de-servicio-de-usuario-regular.yaml):

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
  name: regular-user-binding
  namespace: default
spec:
  subjects:
  - user: "*"
  roleRef:
    kind: ServiceRole
    name: "regular-user"

¿Significa "todos los usuarios" que los usuarios no autenticados también tendrán acceso a la aplicación web SA? No, la política verificará la validez del token JWT.

Apliquemos las configuraciones:

$ kubectl apply -f resource-manifests/istio/security/user-role.yaml
servicerole.rbac.istio.io/regular-user created
servicerolebinding.rbac.istio.io/regular-user-binding created

Configuración de acceso para moderadores

Para los moderadores, queremos permitir el acceso a todos los servicios (rol-servicio-mod.yaml):

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRole
metadata:
  name: mod-user
  namespace: default
spec:
  rules:
  - services: ["*"]
    paths: ["*"]
    methods: ["*"]

Pero queremos tales derechos sólo para aquellos usuarios cuyo token de acceso contenga un reclamo. https://sa.io/group con valor Moderators (mod-servicio-role-binding.yaml):

apiVersion: "rbac.istio.io/v1alpha1"
kind: ServiceRoleBinding
metadata:
  name: mod-user-binding
  namespace: default
spec:
  subjects:
  - properties:
      request.auth.claims[https://sa.io/group]: "Moderators"
  roleRef:
    kind: ServiceRole
name: "mod-user" 

Apliquemos las configuraciones:

$ kubectl apply -f resource-manifests/istio/security/mod-role.yaml
servicerole.rbac.istio.io/mod-user created
servicerolebinding.rbac.istio.io/mod-user-binding created

Debido al almacenamiento en caché de los enviados, las reglas de autorización pueden tardar un par de minutos en surtir efecto. Luego puede asegurarse de que los usuarios y moderadores tengan diferentes niveles de acceso.

Conclusión sobre esta parte.

En serio, ¿ha visto alguna vez un método de autenticación y autorización más simple, sencillo, escalable y seguro?

Solo se requirieron tres recursos de Istio (RbacConfig, ServiceRole y ServiceRoleBinding) para lograr un control detallado sobre la autenticación y autorización del acceso del usuario final a los servicios.

Además, hemos atendido estos temas desde nuestros servicios de enviado, logrando:

  • reducir la cantidad de código genérico que puede contener problemas y errores de seguridad;
  • reducir el número de situaciones estúpidas en las que un terminal resultó ser accesible desde el exterior y se olvidó de informarlo;
  • eliminando la necesidad de actualizar todos los servicios cada vez que se agrega un nuevo rol o derecho;
  • que los nuevos servicios sigan siendo simples, seguros y rápidos.

conclusión

Istio permite a los equipos centrar sus recursos en tareas críticas para el negocio sin agregar gastos generales a los servicios, devolviéndolos al estado micro.

El artículo (en tres partes) proporciona conocimientos básicos e instrucciones prácticas ya preparadas para empezar a utilizar Istio en proyectos reales.

PD del traductor

Lea también en nuestro blog:

Fuente: habr.com

Añadir un comentario