Configura la autenticación de usuarios de Anthos Service Mesh

La autenticación de usuarios de Anthos Service Mesh es una solución integrada para la autenticación de usuarios finales basada en el navegador y el control de acceso a tus cargas de trabajo implementadas. Te permite integrarte con proveedores de identidad (IdP) existentes para la autenticación de usuarios y usa API de Istio y políticas de autorización para la administración de acceso. Es una alternativa fácil de usar a la autenticación de token web JSON (JWT) de Istio.

Un caso de uso típico es cuando una organización usa Anthos Service Mesh a fin de alojar una aplicación web para que su personal acceda a través de un navegador web. Además, la organización debe usar su proveedor de identidad existente para administrar las identidades del usuario. La autenticación de usuarios de Anthos Service Mesh facilita la autenticación mediante un flujo de acceso y consentimiento estándar de OpenID Connect (OIDC) basado en la Web. Cuando el usuario se autentica, Anthos Service Mesh aplica políticas de autorización de Istio y, cuando se realiza de forma correcta, transmite la identidad a las cargas de trabajo en un formato de credencial seguro.

Cómo funciona

La autenticación de usuario de Anthos Service Mesh presenta un nuevo componente, authservice. Este componente se integra con la entrada basada en Envoy como un servicio de autorización externo que intercepta todas las solicitudes entrantes de autenticación. authservice implementa el protocolo OIDC del cliente y permite el acceso de los usuarios a las aplicaciones a través de un navegador, en el que los usuarios completan un flujo de consentimiento y autenticación interactivo para establecer una sesión de corta duración. authservice implementa protocolos estándar de la industria para integrarse en cualquier proveedor de identidad que pueda actuar como servidor de autorización de OIDC. Cuando se autentica al usuario, la información principal se encapsula en un RCToken en formato JWT, firmado por authservice, que se reenvía a la capa de autorización de Istio en la entrada. Este modelo proporciona control de acceso al perímetro para el tráfico en la malla. Si el usuario está autorizado a acceder a un recurso, este RCToken también se reenvía a los microservicios para obtener información principal y aplicar un control de acceso detallado.

En el siguiente diagrama, se muestra la ubicación de authservice en la malla y cómo se relaciona con las demás partes de la malla, como la entrada, las cargas de trabajo, el navegador del usuario y cualquier IdP existente.

Autenticación del usuario final

Los administradores pueden instalar authservice como un complemento en una instalación de Anthos Service Mesh. Cuando se instala, authservice lee la configuración del extremo de OIDC y otros parámetros de configuración asociados que se definen en el recurso personalizado de UserAuth. El administrador puede usar las API de ExternalAuthorization de Anthos Service Mesh para configurar auth_server como un filtro en la entrada.

Instala el servicio de autenticación de usuarios

En los siguientes pasos, se explica cómo configurar authservice.

Requisitos previos

Sigue estos pasos para asegurarte de cumplir con los requisitos previos.

Personaliza la instalación con la superposición de autenticación del usuario

Para instalar el servicio de autenticación de usuarios, debes personalizar la instalación de ASM a fin de agregar un proveedor de autorización externo a nivel de malla.

  1. Obtén el ejemplo de superposición de autenticación de usuarios y actualízalo si hay personalizaciones en la malla. Se recomienda mantener este archivo de superposición en tu control fuente.

    curl https://raw.githubusercontent.com/GoogleCloudPlatform/asm-user-auth/release-1.0/overlay/user-auth-overlay.yaml > user-auth-overlay.yaml
    
  2. Sigue la instalación de ASM con superposición para usar una secuencia de comandos proporcionada por Google a fin de instalar Anthos Service Mesh con la superposición de autenticación del usuario. Por ejemplo:

    /install_asm \
     --project_id "PROJECT_ID" \
     --cluster_name "CLUSTER_NAME" \
     --cluster_location "CLUSTER_LOCATION" \
     --mode install \
     --enable_all \
     --custom_overlay user-auth-overlay.yaml
    

    Los paquetes kpt de autenticación de usuarios crean una AuthorizationPolicy para hacer referencia al proveedor de autorización externo que especifica pkg/ext-authz.yaml.

Prepara la configuración del cliente de OIDC

Sigue estos pasos para establecer la configuración del cliente de OIDC. En esta guía, se usa Google como IdP, pero puedes usar cualquier IdP que admita la autenticación de OIDC.

  1. En la consola de Google Cloud, ve a API y servicios > Credenciales.

    Ir a Credenciales

  2. Ve a Crear credenciales y elige ID de cliente de OAuth. Si es necesario, configura las opciones de la pantalla de consentimiento de OAuth y, luego, las siguientes opciones:

    • Configura Tipo de aplicación como Aplicación web.
    • Configura el URI de redireccionamiento autorizado como https://localhost:8443/_gcp_anthos_callback.

    Luego, haga clic en Guardar.

  3. Además, guarda la configuración del cliente de OIDC para usarla más adelante.

    export OIDC_CLIENT_ID='<your-client-id>'
    export OIDC_CLIENT_SECRET='<your-client-secret>'
    export OIDC_ISSUER_URI='https://accounts.google.com'
    # The host where your application is served from, such as https://example.com
    export OIDC_REDIRECT_HOST='<your-oidc-redirect-host>'
    export OIDC_REDIRECT_PATH='<your-oidc-redirect-path>'
    

Obtén los paquetes kpt

Usa los siguientes pasos para instalar la configuración de authservice recomendada del repositorio público. Con estos comandos, se recupera el contenedor authservice más reciente y se lo inicia como un Pod en el espacio de nombres asm-user-auth. También configura la entrada para interceptar todas las solicitudes.

  1. Obtén el paquete kpt:

    kpt pkg get https://github.com/GoogleCloudPlatform/asm-user-auth@release-1.0 .
    cd asm-user-auth/
    

Configura el secreto y la URL de redireccionamiento para la puerta de enlace de entrada

OAuth2 requiere una URL de redireccionamiento alojada en un extremo protegido por HTTPS. Estos comandos son, por ejemplo, para simplificar la configuración mediante la generación de un certificado autofirmado para la puerta de enlace de entrada de Istio. Una implementación de producción no debe usar certificados autofirmados.

  1. Genera un certificado autofirmado:

    openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem \
     -days 365 -nodes -subj '/CN=localhost'
    
  2. Crea un secreto para la puerta de enlace de entrada a fin de alojar tráfico HTTPS:

    kubectl create -n istio-system secret tls userauth-tls-cert --key=key.pem \
    --cert=cert.pem
    

Aplica las claves de encriptación y firma

El authservice necesita dos conjuntos de claves para operar de forma correcta. La primera es una clave simétrica para la encriptación y desencriptación. Esta clave se usa para encriptar el estado de la sesión antes de configurarla como una cookie.

El segundo conjunto de claves es un par de claves pública/privada. Esta clave se usa para firmar la información del usuario autenticado en formato JWT como un RCToken. La clave pública de este par se publica en un extremo predefinido que los sidecars pueden usar para validar el JWT.

El paquete kpt de autenticación de usuarios contiene dos claves de muestra para una configuración rápida. Sin embargo, puedes usar tu sistema de administración de claves preferido para generar estas claves.

  1. Después de generar tus claves, coloca los datos de la clave en el mismo formato:

    cat ./samples/rctoken_signing_key.json
    {
      "keys":[
         {
            "kty":"RSA",
            "kid":"rsa-signing-key",
            "K":"YOUR_KEY", # k contains a Base64 encoded PEM format RSA signing key.
            "useAfter": 1612813735, # unix timestamp
         }
      ]
    }
    
    cat ./samples/cookie_encryption_key.json
    {
      "keys":[
         {
            "kty":"oct",
            "kid":"key-0",
            "K":"YOUR_KEY",
            "useAfter": 1612813735
         }
      ]
    }
    
  2. Crea el secreto de Kubernetes, que authservice activará en su propio sistema de archivos.

    Para encontrar el valor de la etiqueta REVISION, verifica la implementación de Istio.

    kubectl create namespace asm-user-auth
    kubectl label namespace asm-user-auth istio.io/rev=REVISION --overwrite
    kubectl create secret generic secret-key  \
        --from-file="session_cookie.key"="./samples/cookie_encryption_key.json" \
        --from-file="rctoken.key"="./samples/rctoken_signing_key.json"  \
        --namespace=asm-user-auth
    

Implementa el servicio de autenticación de usuarios

Los siguientes comandos crean el servicio de autenticación de usuarios y la implementación en el espacio de nombres asm-user-auth.

  1. Configura las variables oauth. El ID de cliente y el secreto se almacenan como secretos de Kubernetes, por lo que usamos Base64 para codificarlos.

    kpt cfg set pkg anthos.servicemesh.user-auth.oidc.clientID $(echo -n ${OIDC_CLIENT_ID} | base64 -w0)
    kpt cfg set pkg anthos.servicemesh.user-auth.oidc.clientSecret $(echo -n ${OIDC_CLIENT_SECRET} | base64 -w0)
    kpt cfg set pkg anthos.servicemesh.user-auth.oidc.issuerURI ${OIDC_ISSUER_URI}
    kpt cfg set pkg anthos.servicemesh.user-auth.oidc.redirectURIHost ${OIDC_REDIRECT_HOST}
    kpt cfg set pkg anthos.servicemesh.user-auth.oidc.redirectURIPath ${OIDC_REDIRECT_PATH}
    
  2. Aplica el paquete kpt:

    # Remove the potential alpha version CRD if exists.
    kubectl delete crd userauthconfigs.security.anthos.io
    kubectl apply -f ./pkg/asm_user_auth_config_v1beta1.yaml
    kubectl apply -f ./pkg
    

El authservice consume la CRD UserAuthConfig para proporcionar la autenticación del usuario final. UserAuthConfig se puede configurar en el tiempo de ejecución. También puedes actualizarlo a fin de cambiar el comportamiento de authservice y configurarlo con extremos para cualquier servidor de autorización de OIDC. Contiene los siguientes campos:

cat pkg/user_auth_config.yaml

apiVersion: security.anthos.io/v1beta1
kind: UserAuthConfig
metadata:
  name: user-auth-config
  namespace: asm-user-auth
spec:
  authentication:
    oidc:
      certificateAuthorityData: ""
      oauthCredentialsSecret:
        name: "oauth-secret"
        namespace: "asm-user-auth"
      issuerURI: "https://accounts.google.com"
      redirectURIHost: ""
      redirectURIPath: "/_gcp_asm/authenticate"

Consulta los detalles de la configuración de autenticación del usuario para obtener descripciones detalladas de los campos user_auth_config.yaml.

Realiza tareas posteriores a la instalación

Las siguientes tareas son obligatorias después de completar los pasos de instalación anteriores.

Habilita la autenticación de usuarios para tus aplicaciones

En esta sección, se muestra cómo habilitar la autenticación de usuarios con la aplicación de muestra Online Boutique a modo de ejemplo.

La autenticación de usuarios de Anthos Service Mesh usa una política de autorización de tipo CUSTOM para activar el flujo de OIDC.

El proceso de instalación también crea una puerta de enlace de Istio para entregar tráfico HTTPS con el certificado TLS userauth-tls-cert que creaste antes. Esta es la configuración pkg/gateway.yaml.

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: userauth
  namespace: asm-user-auth
spec:
  selector:
    istio: ingressgateway
  servers:
  - hosts:
    - '*'
    port:
      name: https
      number: 443
      protocol: HTTPS
    tls:
      mode: SIMPLE
      credentialName: userauth-tls-cert
---
# This ensures the OIDC endpoint has at least some route defined.
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: userauth-oidc
  namespace: asm-user-auth
spec:
  gateways:
  - userauth
  hosts:
  - '*'
  http:
  - match:
    - uri:
        prefix: /status
    - uri:
        prefix: "your-oidc-redirect-path"
    name: user-auth-route
    route:
    - destination:
        host: authservice
        port:
          number: 10004
  1. Actualiza la aplicación Online Boutique a fin de usar esta puerta de enlace para entregar tráfico HTTPS y usar la redirección de puertos a fin de acceder a la aplicación de manera local:

    kubectl apply -f./samples/boutique-route.yaml -n demo
    kubectl port-forward service/istio-ingressgateway 8443:443 -n istio-system
    

    La puerta de enlace de entrada del puerto 8443 se reenviará a localhost para permitir el acceso local a la aplicación.

  2. Verifica que se pueda acceder a la aplicación de ejemplo Online Boutique en https://localhost:8443/.

Verifica la autenticación del usuario

Los servicios de la aplicación Online Boutique ahora requieren que el usuario final acceda con sus Cuentas de Google.

  1. Para verificar que veas la página de acceso de OIDC, visita https://localhost:8443/.

  2. Después de acceder, haz clic en Siguiente y verifica que te redireccione a la página principal de Online Boutique.

Configura políticas de autorización

Después de finalizar la configuración en los pasos anteriores, se redireccionará a cada usuario a través de un flujo de autenticación basado en la Web. Cuando se completa el flujo, authservice genera un RCToken en formato JWT, que se usa para transmitir la información del usuario autenticado.

  1. Agrega políticas de autorización de Istio a la entrada para garantizar que se realice una verificación de autorización de cada usuario autenticado:

    kubectl apply -f ./samples/rctoken-authz.yaml
    
  2. El archivo rctoken-authz.yaml configura la puerta de enlace de entrada para validar el token de RC que emite el authservice y solo lo autoriza cuando el JWT contiene los campos deseados, como público y entidades emisoras.

    Consulta la siguiente política de autorización de ejemplo:

    apiVersion: security.istio.io/v1beta1
    kind: RequestAuthentication
    metadata:
     name: require-rc-token
     namespace: istio-system
    spec:
     selector:
       matchLabels:
         istio: ingressgateway
     jwtRules:
     - issuer: "authservice.asm-user-auth.svc.cluster.local"
       audiences:
       - "test_audience"
       jwksUri: "http://authservice.asm-user-auth.svc.cluster.local:10004/_gcp_user_auth/jwks"
       fromHeaders:
       - name: X-ASM-RCTOKEN
       forwardOriginalToken: true
    ---
    apiVersion: security.istio.io/v1beta1
    kind: AuthorizationPolicy
    metadata:
     name: require-rc-token
     namespace: istio-system
    spec:
     selector:
       matchLabels:
         istio: ingressgateway
     action: ALLOW
     rules:
     - when:
       - key: request.auth.claims[iss]
         values:
         - authservice.asm-user-auth.svc.cluster.local
       - key: request.auth.claims[aud]
         values:
         - test_audience
    

Establece la configuración específica del entorno

En los pasos anteriores, se usa localhost y un certificado HTTPS autofirmado para una configuración rápida. Para uso real de producción, usa tu propio dominio, como example.com.

Además, asegúrate de que tokenEndpoint y authorizationEndpoint configurados en la CRD de UserAuthConfig tengan una ruta configurada en VirtualService. Los pasos de instalación anteriores lo establecen en asm-user-auth/userauth-oidc VirtualService.

Administra y rota claves

authservice usa dos conjuntos de claves. Puedes rotar cada clave de forma independiente. Sin embargo, antes de rotar las claves, es importante comprender cómo funciona la rotación.

Ambas claves están en formato JSON. En el campo useAfter, se especifica la marca de tiempo desde que se considera que se usará la clave. Durante una rotación de claves, debes incluir claves antiguas y nuevas en el archivo JSON. Por ejemplo, en el siguiente ejemplo, new-key solo se usará después de la marca de tiempo 1712813735.

{
   "keys":[
      {
         "kty":"RSA",
         "kid":"old-key",
         "K":"...", # k contains a Base64 encoded PEM format RSA signing key.
         "useAfter": 1612813735, # unix timestamp
      }
      {
      "kty":"RSA",
         "kid":"new-key",
         "K":"...", # k contains a Base64 encoded PEM format RSA signing key.
         "useAfter": 1712813735, # unix timestamp
      }
   ]
}

Anthos Service Mesh usa la clave simétrica para encriptar los datos de las sesiones que se almacenan en las cookies del navegador. Para garantizar la validez de las sesiones existentes, authservice intenta desencriptar todas las claves en el conjunto de claves. Durante la rotación, authservice usará la clave nueva para encriptar las sesiones nuevas y seguirá intentando la desencriptación con las claves anteriores.

El par de claves pública/privada se usa para firmar RCToken. istiod transmite la clave pública a los sidecars para la verificación de JWT. Es fundamental que los sidecars reciban la clave pública nueva antes de que authservice comience a usar la clave privada nueva para firmar el RCToken. En este sentido, authservice comienza a publicar la clave pública de inmediato después de agregar la clave, pero espera un tiempo significativo antes de comenzar a usarla para firmar RCToken.

En resumen, te recomendamos lo siguiente cuando realices rotaciones de claves:

  1. Realiza rotaciones de claves frecuentes o a pedido, según lo necesites.
  2. En el formato JSON, incluye las claves actuales y nuevas. Las claves nuevas se deben asociar con una marca de tiempo en el futuro. Te recomendamos que especifiques una marca de tiempo con al menos un par de horas de anticipación de la hora actual.
  3. Supervisa y confirma que los servicios aún estén en buen estado después de usar la clave nueva. Espera al menos un día después de usar la clave nueva antes de continuar con el siguiente paso.
  4. Quita las claves anteriores de las entradas JSON. Ya no son necesarias.

Detalles de configuración de autenticación del usuario

En la siguiente tabla, se describe cada campo de la CRD:

Nombre del campo Descripción
authentication.oidc En esta sección, se conserva la configuración del extremo de OIDC y los parámetros que se usan en el flujo de OIDC.
authentication.oidc.certificateAuthorityData Este es el certificado SSL del dominio del servidor de autorización de OIDC.
authentication.oidc.clientSecret Referencias de Tsecret al secreto de tipo opaco de Kubernetes que contiene client_id de OIDC de OAuth2 y client_secret en la carga útil de JSON.
authentication.oidc.issuerURI El URI que se usará como entidad emisora en el RCToken de salida.
authentication.oidc.redirectURIHost El host que se usará para el URI de finalización de OAuth. Si dejas este campo vacío, se usará el host de la URL de destino y el URI de redireccionamiento se ensamblará de forma dinámica.
Este valor se puede usar cuando se desea una sesión de SSO de autenticación de usuario en un dominio de nivel superior. Por ejemplo, para habilitar el SSO entre profile.example.com/ y admin.example.com/, este valor se puede configurar en example.com. Esto permitirá establecer una sesión de autenticación de usuarios en example.com que se compartirá entre todos los subdominios. Nota: Si se entregan varios dominios desde la misma malla, example1.com y example2.com, no se puede usar la característica y se recomienda dejarla vacía.
authentication.oidc.redirectURIPath La ruta de acceso del extremo en la que “authservice” finalizará el flujo de OAuth. Debes registrar esta ruta de URI más el host como un URI de redireccionamiento autorizado en el servidor de autorización para authentication.oidc.clientID.
Además, este URI se debe entregar desde la misma malla de servicios y entrada en la que está habilitado “authservice”.
authentication.oidc.scopes El alcance de OAuth que se debe solicitar en la solicitud de autenticación.
authentication.oidc.groupsClaim Si el “idtoken” contiene una reclamación de grupo, usa este campo para indicar su nombre. Si se especifica, el servicio pasará los datos en esta reclamación a la reclamación de “grupos” en el RCToken de salida.
authentication.outputJWTAudience El público del RCToken que genera “authservice”. Los archivos adicionales pueden validar el RCToken entrante en función de este valor de público.

Implementación de varios clústeres

La autenticación de usuarios de Anthos Service Mesh es compatible con la implementación de varios clústeres. Debes implementar la autenticación del usuario en cada clúster como se describió antes. La configuración de autenticación del usuario, como el recurso personalizado UserAuth, el secreto de cliente de OIDC y las claves de encriptación, se deben replicar en cada clúster.

De forma predeterminada, la puerta de enlace de entrada realizará el balanceo de cargas de las solicitudes de autenticación en cualquiera de las instancias authservice. Puedes usar la regla de destino para configurar la puerta de enlace de entrada a fin de enviar solicitudes a authservice en el mismo clúster y solo conmutar por error a los authservice de otros clústeres.

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: authservice-fail-over
  namespace: asm-user-auth
spec:
  host: authservice.asm-user-auth.svc.cluster.local
  trafficPolicy:
    loadBalancer:
      localityLbSetting:
        enabled: true
        failover:
        - from:  us-east
          to: us-west
        - from: us-west
          to: us-east

Al igual que con otra configuración, esto debe configurarse en cada clúster.

Preguntas frecuentes

  1. ¿Cómo actualizo Anthos Service Mesh con la autenticación de usuarios habilitada?

    Sigue el proceso de actualización de Anthos Service Mesh y especifica el archivo de superposición user-auth.yaml en la línea de comandos como install_asm.

  2. ¿Cuántos recursos deberíamos aprovisionar para authservice? ¿Cuántas solicitudes por segundo puede manejar?

    De forma predeterminada, authservice se configura con CPU virtuales 2.0 y memoria de 256 Mi. Con esta configuración, authservice puede controlar 500 solicitudes por segundo. Para controlar una cantidad mayor de solicitudes, debes aprovisionar más CPU, lo que es aproximadamente proporcional a su capacidad de control de solicitudes. También puedes configurar varias réplicas del authservice para aumentar la escalabilidad horizontal.