Prácticas recomendadas esenciales de RBAC para proteger sus clústeres de Kubernetes

Aprende las mejores prácticas de RBAC en Kubernetes, ejemplos de Roles con mínimo privilegio, alcance de cuentas de servicio y verificaciones de auditoría para clústeres más seguros.

Prácticas Esenciales de RBAC para Asegurar tus Clústeres de Kubernetes

El RBAC de Kubernetes decide quién puede hacer qué en tu clúster. Un único enlace amplio puede permitir que una cuenta comprometida lea secretos, modifique cargas de trabajo o tome el control de los recursos del clúster.

Esta guía explica los objetos centrales de RBAC, muestra ejemplos prácticos y te proporciona hábitos de revisión que evitan que el acceso se desvíe con el tiempo.

Comprendiendo los Fundamentos de RBAC en Kubernetes

RBAC en Kubernetes es un mecanismo de autorización que regula el acceso a los recursos de Kubernetes basándose en los roles de usuarios individuales o cuentas de servicio. Es una capa de defensa crucial que garantiza que solo entidades autorizadas puedan realizar acciones específicas sobre recursos específicos.

En esencia, RBAC se basa en cuatro tipos principales de objetos de Kubernetes:

  • Role: Un Role es un conjunto de permisos que se aplica dentro de un espacio de nombres específico. Define qué acciones (verbos como get, list, create, update, delete) se pueden realizar sobre qué recursos (como pods, deployments, services, secrets). Por ejemplo, un Role podría otorgar permiso para leer pods y deployments en el espacio de nombres development.
  • ClusterRole: Similar a un Role, pero un ClusterRole define permisos que se aplican a nivel de clúster o a recursos sin espacio de nombres (ej., nodes, persistentvolumes). Un ClusterRole también puede definir permisos para recursos con espacio de nombres en todos los espacios de nombres. Por ejemplo, un ClusterRole podría permitir listar todos los nodes en el clúster.
  • RoleBinding: Un RoleBinding otorga los permisos definidos en un Role (o un ClusterRole aplicado a un espacio de nombres) a un usuario, grupo o cuenta de servicio. Siempre opera dentro de un espacio de nombres específico.
  • ClusterRoleBinding: Un ClusterRoleBinding otorga los permisos definidos en un ClusterRole a un usuario, grupo o cuenta de servicio, aplicando esos permisos en todo el clúster.

Juntos, estos objetos permiten a los administradores construir un sistema de control de acceso robusto y granular. Cuando un usuario o aplicación (representado por una cuenta de servicio) intenta realizar una acción, Kubernetes evalúa los RoleBindings y ClusterRoleBindings existentes para determinar si la acción solicitada está permitida.

Implementando el Principio de Mínimo Privilegio con RBAC

Un principio central de la seguridad de la información es el principio de mínimo privilegio. Un usuario, programa o proceso debe recibir solo los permisos que necesita para realizar su trabajo. En Kubernetes, los roles excesivamente permisivos son una forma común de que un pequeño compromiso se convierta en un problema a nivel de clúster.

Definiendo Permisos Granulares

Al diseñar políticas RBAC, piensa en las acciones y recursos precisos requeridos:

  • Verbos: En lugar de otorgar * (todos los verbos), especifica exactamente qué acciones se necesitan (get, list, watch, create, update, delete, patch, exec).
  • Recursos: Sé específico sobre los recursos (pods, deployments, secrets, configmaps). Evita otorgar acceso a * para recursos a menos que sea absolutamente necesario y para roles administrativos bien justificados.
  • Nombres de Recursos: Para recursos muy sensibles como secrets, puedes restringir algunos verbos, como get, a resourceNames específicos dentro de un tipo de recurso. No confíes en resourceNames para el acceso de tipo lista, porque list y watch no están limitados a un solo objeto nombrado de la misma manera.
  • Grupos de API: La mayoría de los recursos de Kubernetes pertenecen a un grupo de API (ej., apps, rbac.authorization.k8s.io, "" para recursos centrales). Especifica el grupo de API correcto para reducir aún más el alcance.

Alcance de Espacios de Nombres

Para la mayoría de las aplicaciones y equipos de desarrollo, los permisos deben limitarse a espacios de nombres específicos. Esta segregación asegura que un compromiso en el entorno de una aplicación o equipo no conduzca automáticamente a un acceso a nivel de clúster. Siempre prefiere Role y RoleBinding sobre ClusterRole y ClusterRoleBinding cuando sea posible.

Implementación Práctica de RBAC: Ejemplos

Repasemos algunos ejemplos prácticos de creación y vinculación de políticas RBAC.

Ejemplo 1: Acceso de Desarrollador a un Espacio de Nombres Específico

Imagina que un desarrollador necesita gestionar despliegues y ver registros en su espacio de nombres dedicado, dev-team-a. No debería tener acceso a otros espacios de nombres o recursos a nivel de clúster.

Primero, define un Role para el desarrollador en el espacio de nombres dev-team-a:

# dev-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: dev-team-a
  name: dev-deployer
rules:
- apiGroups: ["apps"] # Para Deployments
  resources: ["deployments", "replicasets"]
  verbs: ["get", "list", "watch", "create", "update", "delete", "patch"]
- apiGroups: [""] # Grupo de API central para Pods y registros de Pods
  resources: ["pods", "pods/log"]
  verbs: ["get", "list", "watch"]

Aplica este rol:

kubectl apply -f dev-role.yaml

A continuación, vincula este Role a un usuario específico (ej., [email protected] a través de un proveedor de identidad externo) o a una cuenta de servicio dentro del espacio de nombres dev-team-a:

# dev-role-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: dev-team-a
  name: john-dev-deployer-binding
subjects:
- kind: User
  name: [email protected] # El nombre distingue entre mayúsculas y minúsculas
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: dev-deployer
  apiGroup: rbac.authorization.k8s.io

Aplica este enlace:

kubectl apply -f dev-role-binding.yaml

Ahora, [email protected] solo puede gestionar despliegues y ver registros dentro del espacio de nombres dev-team-a. No puede, por ejemplo, crear secretos en kube-system ni listar todos los nodos.

Ejemplo 2: Cuenta de Servicio de Aplicación Accediendo a Secretos

Una aplicación que se ejecuta como una ServiceAccount necesita leer un secreto específico en su propio espacio de nombres.

Primero, asegúrate de que la cuenta de servicio exista o crea una:

# app-sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: my-app-namespace
  name: my-app-service-account

Aplica esta cuenta de servicio:

kubectl apply -f app-sa.yaml

A continuación, define un Role que permita leer un secreto específico:

# secret-reader-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: my-app-namespace
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  resourceNames: ["my-app-db-credentials"]
  verbs: ["get"]

Aplica este rol:

kubectl apply -f secret-reader-role.yaml

Finalmente, vincula este Role a la my-app-service-account:

# app-secret-reader-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: my-app-namespace
  name: my-app-secret-reader-binding
subjects:
- kind: ServiceAccount
  name: my-app-service-account
  namespace: my-app-namespace
roleRef:
  kind: Role
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

Aplica este enlace:

kubectl apply -f app-secret-reader-binding.yaml

La aplicación ahora solo podrá leer el secreto especificado y nada más.

Ejemplo 3: Rol de Administrador de Clúster (con precaución)

Los roles administrativos a nivel de clúster deben otorgarse con extrema moderación. Aquí hay un ejemplo de un ClusterRole para listar todos los nodos, que podría ser necesario para una herramienta de monitoreo.

# node-viewer-clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: node-viewer
rules:
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get", "list", "watch"]

Aplica este ClusterRole:

kubectl apply -f node-viewer-clusterrole.yaml

Luego, vincúlalo a una cuenta de servicio de monitoreo usando un ClusterRoleBinding:

# monitoring-node-viewer-binding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: monitoring-node-viewer-binding
subjects:
- kind: ServiceAccount
  name: monitoring-sa
  namespace: monitoring
roleRef:
  kind: ClusterRole
  name: node-viewer
  apiGroup: rbac.authorization.k8s.io

Aplica este enlace:

kubectl apply -f monitoring-node-viewer-binding.yaml

Advertencia: Ten mucho cuidado con ClusterRole y ClusterRoleBinding para usuarios humanos. Limita su uso a verdaderos administradores de clúster y cuentas de servicio de infraestructura específicas.

Prácticas Esenciales de RBAC

Adherirse a estas mejores prácticas mejorará significativamente la postura de seguridad de tu clúster:

  1. Aplica el Principio de Mínimo Privilegio (PoLP):

    • Otorga solo los permisos mínimos necesarios. Revisa cada permiso cuidadosamente.
    • Evita los comodines (*) para resources y verbs siempre que sea posible. Si se usan, justifícalos e intenta limitarlos lo más posible.
    • Restringe el acceso a recursos sensibles (como secrets) usando resourceNames en los roles.
  2. Usa Espacios de Nombres para la Segregación:

    • Organiza tus aplicaciones y equipos en espacios de nombres distintos.
    • Por defecto, usa Role y RoleBinding para otorgar permisos dentro de estos espacios de nombres.
  3. Prefiere Roles sobre ClusterRoles:

    • Solo usa ClusterRole y ClusterRoleBinding cuando los permisos realmente necesiten ser a nivel de clúster (ej., gestión de nodos, definiciones de recursos personalizados, agentes de monitoreo específicos).
    • La mayoría de los permisos específicos de aplicaciones deben tener un espacio de nombres.
  4. Audita y Revisa Regularmente las Políticas RBAC:

    • Las políticas RBAC pueden desviarse con el tiempo. Revisa periódicamente quién tiene qué acceso.
    • Usa herramientas como kubectl auth can-i para probar permisos para usuarios/cuentas de servicio específicos.
    # Verifica si '[email protected]' puede obtener pods en 'dev-team-a'
    kubectl auth can-i get pods --namespace=dev-team-a [email protected]
    
    # Verifica si 'monitoring-sa' puede listar nodos (a nivel de clúster)
    kubectl auth can-i list nodes --as=system:serviceaccount:monitoring:monitoring-sa
    
    • Considera herramientas de terceros o scripts personalizados para una auditoría RBAC completa.
  5. Separa los Roles Administrativos:

    • Nunca otorgues privilegios cluster-admin a desarrolladores o cuentas de servicio de aplicaciones.
    • Crea ClusterRoles administrativos específicos con solo los permisos elevados necesarios (ej., cluster-reader, node-reader).
  6. Aprovecha las Cuentas de Servicio para Aplicaciones:

    • Las aplicaciones que se ejecutan dentro del clúster deben usar ServiceAccounts para interactuar con la API de Kubernetes.
    • Cada aplicación o microservicio debería tener idealmente su propia ServiceAccount dedicada con permisos mínimos.
    • Establece automountServiceAccountToken: false para pods que no requieran acceso a la API de Kubernetes, ya sea en el pod o en la cuenta de servicio.
  7. Integra con la Gestión de Identidad Externa:

    • Para usuarios humanos, integra Kubernetes con un proveedor de identidad externo (ej., OIDC, LDAP, Active Directory) para autenticación y gestión de grupos.
    • Mapea grupos externos a RoleBindings o ClusterRoleBindings de Kubernetes para una gestión más fácil.
  8. Automatiza la Gestión de RBAC con GitOps:

    • Trata tus políticas RBAC como código. Almacénalas en un repositorio controlado por versiones (Git).
    • Usa principios GitOps para gestionar e implementar configuraciones RBAC, asegurando consistencia, trazabilidad y reversiones más fáciles.
  9. Monitorea los Eventos de RBAC a través de Registros de Auditoría:

    • Habilita y configura el registro de auditoría de Kubernetes para rastrear solicitudes de API, incluyendo quién realizó qué acción y cuándo.
    • Revisa regularmente los registros de auditoría para detectar intentos de acceso no autorizados o actividades sospechosas relacionadas con RBAC.
  10. Actualiza Kubernetes Regularmente:

    • Mantente al día con las versiones de Kubernetes para beneficiarte de parches de seguridad y mejoras, incluyendo mejoras en RBAC.

Errores Comunes y Cómo Evitarlos

  • Comodines Excesivamente Permisivos: Otorgar apiGroups: ["*"], resources: ["*"], o verbs: ["*"] es un riesgo de seguridad importante. Sé siempre explícito.
  • Uso Predeterminado de cluster-admin: No uses el grupo system:masters o el ClusterRole cluster-admin para operaciones diarias ni lo asignes a usuarios no administradores. Cualquiera de ellos otorga un control amplio sobre el clúster.
  • Ignorar automountServiceAccountToken: En muchos clústeres, los pods reciben un token de cuenta de servicio a menos que deshabilites el montaje automático. Si un pod no necesita interactuar con la API de Kubernetes, establece automountServiceAccountToken: false en la especificación del pod o en la definición de la cuenta de servicio para reducir su superficie de ataque.
  • Falta de Auditoría: Sin revisiones regulares, las políticas RBAC pueden volverse obsoletas o excesivamente permisivas a medida que evolucionan las necesidades del clúster. Implementa un proceso de revisión.
  • Confundir Role y ClusterRole: Malinterpretar el alcance puede llevar a otorgar acceso a nivel de clúster cuando solo se pretendía acceso a un espacio de nombres.

Conclusión

RBAC funciona mejor cuando lo mantienes aburrido y específico: roles con espacio de nombres para equipos de aplicación, permisos estrechos de cuentas de servicio, sin comodines sin revisión, y verificaciones regulares de kubectl auth can-i. Trata cada enlace como código de producción, porque en un clúster de Kubernetes, efectivamente lo es.