En esta página se ofrecen prácticas recomendadas para planificar las políticas de control de acceso basado en roles (RBAC). Para saber cómo implementar RBAC en Google Kubernetes Engine (GKE), consulta el artículo Configurar el control de acceso basado en roles. El control de acceso basado en roles (RBAC) es una función de seguridad básica de Kubernetes que te permite crear permisos detallados para gestionar las acciones que pueden realizar los usuarios y las cargas de trabajo en los recursos de tus clústeres. Creas roles de RBAC y los vinculas a sujetos, que son usuarios autenticados, como cuentas de servicio o grupos de Google.
Esta página está dirigida a especialistas en seguridad y operadores que planifican e implementan políticas de control de acceso basado en roles para su organización. Para obtener más información sobre los roles habituales y las tareas de ejemplo a las que hacemos referencia en el contenido, consulta Roles y tareas habituales de los usuarios de GKE. Trusted Cloud by S3NS
Antes de leer esta página, asegúrese de que conoce los siguientes conceptos:
Para ver una lista de comprobación de estas directrices, consulta Resumen de la lista de comprobación.
Cómo funciona el control de acceso basado en roles
El control de acceso basado en roles admite los siguientes tipos de roles y vinculaciones:
- ClusterRole: conjunto de permisos que se pueden aplicar a cualquier espacio de nombres o a todo el clúster.
- Rol: conjunto de permisos limitado a un solo espacio de nombres.
- ClusterRoleBinding: vincula un
ClusterRole
a un usuario o a un grupo en todos los espacios de nombres del clúster. - RoleBinding: vincula un
Role
o unClusterRole
a un usuario o un grupo en un espacio de nombres específico.
Los permisos se definen como rules
en un Role
o un ClusterRole
. Cada campo rules
de un rol consta de un grupo de APIs, los recursos de API de ese grupo y los verbos (acciones) permitidos en esos recursos. Si quieres, puedes limitar los verbos a instancias con nombre de recursos de la API mediante el campo resourceNames
. Para ver un ejemplo, consulta Restringir el acceso a instancias de recursos específicas.
Después de definir un rol, puedes usar un RoleBinding
o un ClusterRoleBinding
para vincularlo a un sujeto. Elige el tipo de vinculación en función de si quieres conceder permisos en un solo espacio de nombres o en varios.
Diseño de roles de RBAC
Aplica el principio de mínimos accesos
Cuando asignes permisos en un rol de control de acceso basado en roles, utiliza el principio de mínimos accesos y concede los permisos mínimos necesarios para realizar una tarea. Si aplicas el principio de privilegio mínimo, se reduce la posibilidad de que se produzca una apropiación de privilegios si tu clúster se ve comprometido, así como la probabilidad de que un acceso excesivo provoque un incidente de seguridad.
Cuando diseñes tus roles, ten en cuenta los riesgos habituales de escalada de privilegios, como los verbos escalate
o bind
, el acceso create
a PersistentVolumes o el acceso create
a Certificate Signing Requests. Para ver una lista de los riesgos, consulta el artículo Kubernetes RBAC - privilege escalation risks (Riesgos de escalada de privilegios de RBAC de Kubernetes).
Evitar los roles y grupos predeterminados
Kubernetes crea un conjunto de ClusterRoles y ClusterRoleBindings predeterminados que puedes usar para descubrir APIs y habilitar la funcionalidad de los componentes gestionados. Los permisos que conceden estos roles predeterminados pueden ser amplios en función del rol. Kubernetes también tiene un conjunto de usuarios y grupos de usuarios predeterminados, identificados por el prefijo system:
.
De forma predeterminada, Kubernetes y GKE vinculan automáticamente estos roles a los grupos predeterminados y a varios temas. Para ver una lista completa de los roles y las vinculaciones predeterminados que crea Kubernetes, consulta Roles y vinculaciones de roles predeterminados.
En la siguiente tabla se describen algunos roles, usuarios y grupos predeterminados. Te recomendamos que no interactúes con estos roles, usuarios y grupos a menos que los hayas evaluado detenidamente, ya que interactuar con estos recursos puede tener consecuencias no deseadas en la seguridad de tu clúster.
Nombre | Tipo | Descripción |
---|---|---|
cluster-admin |
ClusterRole | Concede a un sujeto permiso para hacer cualquier acción en cualquier recurso del clúster. |
system:anonymous |
Usuario | Kubernetes asigna este usuario a las solicitudes del servidor de la API que no tienen información de autenticación. Al vincular un rol a este usuario, cualquier usuario no autenticado tendrá los permisos concedidos por ese rol. |
system:unauthenticated |
Grupo | Kubernetes asigna este grupo a las solicitudes del servidor de la API que no tienen información de autenticación. Al vincular un rol a este grupo, cualquier usuario no autenticado tendrá los permisos que concede ese rol. |
system:authenticated |
Grupo | GKE asigna este grupo a las solicitudes del servidor de la API realizadas por cualquier usuario que haya iniciado sesión con una cuenta de Google, incluidas todas las cuentas de Gmail. En la práctica, no hay una diferencia significativa con Al vincular un rol a este grupo, cualquier usuario que tenga una cuenta de Google, incluidas todas las cuentas de Gmail, obtendrá los permisos que otorga ese rol. |
system:masters |
Grupo | Kubernetes asigna el Si añades tus propias asignaturas a este grupo, esas asignaturas podrán hacer lo que quieran con cualquier recurso de tu clúster. |
Si es posible, evita crear enlaces que incluyan usuarios, roles y grupos predeterminados. Esto puede tener consecuencias no deseadas en la postura de seguridad de tu clúster. Por ejemplo:
- Al vincular el
cluster-admin
ClusterRolesystem:unauthenticated
predeterminado al grupocluster-admin
system:unauthenticated
, cualquier usuario no autenticado tendrá acceso a todos los recursos del clúster (incluidos los secretos). Estos enlaces con privilegios elevados son el objetivo de ataques como las campañas de malware masivas. - Al vincular un rol personalizado al grupo
system:unauthenticated
, los usuarios no autenticados obtienen los permisos concedidos por ese rol.
Cuando sea posible, sigue estas directrices:
- No añadas tus propios temas al grupo
system:masters
. - No vincules el grupo
system:unauthenticated
a ningún rol de control de acceso basado en roles (RBAC). - No vincules el grupo
system:authenticated
a ningún rol de control de acceso basado en roles (RBAC). - No vincules el usuario
system:anonymous
a ningún rol de control de acceso basado en roles. - No enlaces el
cluster-admin
ClusterRole a tus propios elementos o a ninguno de los usuarios y grupos predeterminados. Si tu aplicación requiere muchos permisos, determina los permisos exactos que necesita y crea un rol específico para ese fin. - Evalúa los permisos concedidos por otros roles predeterminados antes de vincular los sujetos.
- Evalúa los roles vinculados a los grupos predeterminados antes de modificar los miembros de esos grupos.
No permitir el uso de grupos predeterminados
Puedes usar la gcloud CLI para inhabilitar las vinculaciones de RBAC no predeterminadas en un clúster que haga referencia a los grupos system:unauthenticated
y system:authenticated
o al usuario system:anonymous
. Usa una o ambas de las siguientes marcas
cuando crees un clúster de GKE o actualices uno que ya tengas.
El uso de estas marcas no inhabilita las vinculaciones predeterminadas de Kubernetes que hacen referencia a estos grupos. Estas marcas requieren la versión 1.30.1-gke.1283000 de GKE o una posterior.
--no-enable-insecure-binding-system-authenticated
: inhabilita las enlaces no predeterminados que hagan referencia asystem:authenticated
.--no-enable-insecure-binding-system-unauthenticated
: inhabilita las vinculaciones no predeterminadas que hagan referencia asystem:unauthenticated
ysystem:anonymous
.
Detectar y eliminar el uso de roles y grupos predeterminados
Para comprobar si tus clústeres hacen referencia a estos usuarios y grupos en las vinculaciones de RBAC, habilita el nivel estándar de análisis de la postura de seguridad de Kubernetes en tus clústeres o flota para que GKE pueda mostrarte los resultados en el panel de control de postura de seguridad de la Trusted Cloud consola. Para obtener instrucciones, consulta el artículo Habilitar la auditoría de la configuración de cargas de trabajo.
En las siguientes secciones se muestra cómo encontrar los RoleBindings o ClusterRoleBindings específicos que hacen referencia a usuarios y grupos predeterminados, y cómo eliminar esos recursos.
ClusterRoleBindings
Lista los nombres de los ClusterRoleBindings con el asunto
system:anonymous
,system:unauthenticated
osystem:authenticated
:kubectl get clusterrolebindings -o json \ | jq -r '["Name"], ["-----"], (.items[] | select((.subjects | length) > 0) | select(any(.subjects[]; .name == "system:anonymous" or .name == "system:unauthenticated" or .name == "system:authenticated")) | [.metadata.namespace, .metadata.name]) | @tsv'
La salida solo debe mostrar los siguientes ClusterRoleBindings:
Name ---- "system:basic-user" "system:discovery" "system:public-info-viewer"
Si el resultado contiene enlaces adicionales que no son predeterminados, haz lo siguiente para cada enlace adicional. Si tu salida no contiene enlaces no predeterminados, omite los pasos siguientes.
Lista los permisos del rol asociado a la vinculación:
kubectl get clusterrolebinding CLUSTER_ROLE_BINDING_NAME -o json \ | jq ' .roleRef.name +" " + .roleRef.kind' \ | sed -e 's/"//g' \ | xargs -l bash -c 'kubectl get $1 $0 -o yaml'
Sustituye
CLUSTER_ROLE_BINDING_NAME
por el nombre del ClusterRoleBinding no predeterminado.El resultado debería ser similar al siguiente:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: ... rules: - apiGroups: - "" resources: - secrets verbs: - get - watch - list
Si determinas que los permisos de la salida son seguros para concederlos a los usuarios o grupos predeterminados, no es necesario que hagas nada más. Si determina que los permisos concedidos por la vinculación no son seguros, vaya al paso siguiente.
Elimina una vinculación no segura de tu clúster:
kubectl delete clusterrolebinding CLUSTER_ROLE_BINDING_NAME
Sustituye
CLUSTER_ROLE_BINDING_NAME
por el nombre del ClusterRoleBinding que quieras eliminar.
RoleBindings
Muestra el espacio de nombres y el nombre de cualquier RoleBinding con el asunto
system:anonymous
,system:unauthenticated
osystem:authenticated
:kubectl get rolebindings -A -o json \ | jq -r '["Namespace", "Name"], ["---------", "-----"], (.items[] | select((.subjects | length) > 0) | select(any(.subjects[]; .name == "system:anonymous" or .name == "system:unauthenticated" or .name == "system:authenticated")) | [.metadata.namespace, .metadata.name]) | @tsv'
Si el clúster está configurado correctamente, el resultado debería ser en blanco. Si el resultado contiene enlaces que no son predeterminados, sigue los pasos que se indican a continuación para cada enlace adicional. Si el resultado está en blanco, sáltate los pasos siguientes.
Si solo conoces el nombre del recurso RoleBinding, puedes usar el siguiente comando para buscar los recursos RoleBinding que coincidan en todos los espacios de nombres:
kubectl get rolebindings -A -o json \ | jq -r '["Namespace", "Name"], ["---------", "-----"], (.items[] | select((.subjects | length) > 0) | select(.metadata.name == "ROLE_BINDING_NAME") | [.metadata.namespace, .metadata.name]) | @tsv'
Sustituye
ROLE_BINDING_NAME
por el nombre del RoleBinding no predeterminado.Lista los permisos del rol asociado a la vinculación:
kubectl get rolebinding ROLE_BINDING_NAME --namespace ROLE_BINDING_NAMESPACE -o json \ | jq ' .roleRef.name +" " + .roleRef.kind' \ | sed -e 's/"//g' \ | xargs -l bash -c 'kubectl get $1 $0 -o yaml --namespace ROLE_BINDING_NAMESPACE'
Haz los cambios siguientes:
ROLE_BINDING_NAME
: el nombre del RoleBinding no predeterminado.ROLE_BINDING_NAMESPACE
: el espacio de nombres de RoleBinding no predeterminado.
El resultado debería ser similar al siguiente:
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: ... rules: - apiGroups: - "" resources: - secrets verbs: - get - watch - list
Si determinas que los permisos de la salida son seguros para concederlos a los usuarios o grupos predeterminados, no es necesario que hagas nada más. Si determina que los permisos concedidos por la vinculación no son seguros, vaya al paso siguiente.
Elimina una vinculación no segura de tu clúster:
kubectl delete rolebinding ROLE_BINDING_NAME --namespace ROLE_BINDING_NAMESPACE
Haz los cambios siguientes:
ROLE_BINDING_NAME
: el nombre del RoleBinding que se va a eliminar.ROLE_BINDING_NAMESPACE
: espacio de nombres del RoleBinding que se va a eliminar.
Limitar los permisos al nivel del espacio de nombres
Usa las vinculaciones y los roles de la siguiente manera, en función de las necesidades de tu carga de trabajo o usuario:
- Para conceder acceso a los recursos de un espacio de nombres, usa un
Role
con unRoleBinding
. - Para conceder acceso a recursos de más de un espacio de nombres, usa un
ClusterRole
con unRoleBinding
para cada espacio de nombres. - Para conceder acceso a los recursos de todos los espacios de nombres, usa un
ClusterRole
con unClusterRoleBinding
.
Concede permisos en el menor número de espacios de nombres posible.
No uses comodines
El carácter *
es un comodín que se aplica a todo. Evita usar comodines en tus reglas. Especifica explícitamente grupos de APIs, recursos y verbos en las reglas de RBAC. Por ejemplo, si se especifica *
en el campo verbs
, se concederán los permisos get
, list
, watch
, patch
, update
, deletecollection
y delete
en los recursos. En la siguiente tabla se muestran ejemplos de cómo evitar los comodines en las reglas:
Recomendado | No recomendado |
---|---|
- rules: apiGroups: ["apps","extensions"] resources: ["deployments"] verbs: ["get","list","watch"] Concede los verbos |
- rules: apiGroups: ["*"] resources: ["deployments"] verbs: ["get","list","watch"] Concede los verbos a |
- rules: apiGroups: ["apps", "extensions"] resources: ["deployments"] verbs: ["get", "list", "watch"] Solo concede los verbos |
- rules: apiGroups: ["apps", "extensions"] resources: ["deployments"] verbs: ["*"] Concede todos los verbos, incluidos |
Usar reglas independientes para conceder el mínimo acceso a recursos específicos
Cuando planifiques tus reglas, prueba los siguientes pasos generales para diseñar reglas de mínimo privilegio más eficientes en cada rol:
- Crea reglas de control de acceso basado en roles independientes para cada verbo de cada recurso al que necesite acceder un sujeto.
- Después de redactar las reglas, analízalas para comprobar si varias reglas tienen la misma lista
verbs
. Combina esas reglas en una sola. - Mantén todas las reglas restantes separadas entre sí.
De esta forma, las reglas se organizan mejor, ya que se combinan las que conceden los mismos verbos a varios recursos y se separan las que conceden verbos diferentes a los recursos.
Por ejemplo, si tu carga de trabajo necesita obtener permisos para el recurso deployments
, pero necesita list
y watch
en los recursos daemonsets
, debes usar reglas independientes al crear un rol. Cuando vinculas el rol RBAC a tu carga de trabajo, no podrá usar watch
en deployments
.
Por ejemplo, si tu carga de trabajo necesita get
y watch
en los recursos pods
y daemonsets
, puedes combinar ambos en una sola regla, ya que la carga de trabajo necesita los mismos verbos en ambos recursos.
En la siguiente tabla, ambos diseños de reglas funcionan, pero las reglas divididas restringen el acceso a los recursos de forma más granular en función de tus necesidades:
Recomendado | No recomendado |
---|---|
- rules: apiGroups: ["apps"] resources: ["deployments"] verbs: ["get"] - rules: apiGroups: ["apps"] resources: ["daemonsets"] verbs: ["list", "watch"] Concede acceso de |
- rules: apiGroups: ["apps"] resources: ["deployments", "daemonsets"] verbs: ["get","list","watch"] Concede los verbos a Deployments y DaemonSets. Un sujeto
que no necesite acceso |
- rules: apiGroups: ["apps"] resources: ["daemonsets", "deployments"] verbs: ["list", "watch"] Combina dos reglas porque el asunto necesita los mismos verbos para los recursos |
- rules: apiGroups: ["apps"] resources: ["daemonsets"] verbs: ["list", "watch"] - rules: apiGroups: ["apps"] resources: ["deployments"] verbs: ["list", "watch"] Estas reglas divididas tendrían el mismo resultado que la regla combinada, pero crearían un desorden innecesario en el archivo de manifiesto de tu rol. |
Restringir el acceso a instancias de recursos concretas
El control de acceso basado en roles te permite usar el campo resourceNames
en tus reglas para restringir el acceso a una instancia con nombre específica de un recurso. Por ejemplo, si estás escribiendo un rol de RBAC que necesita update
el seccomp-high
ConfigMap y nada más, puedes usar resourceNames
para especificar solo ese ConfigMap. Usa resourceNames
siempre que sea posible.
Recomendado | No recomendado |
---|---|
- rules: apiGroups: [""] resources: ["configmaps"] resourceNames: ["seccomp-high"] verbs: ["update"] Restringe el asunto para que solo actualice el |
- rules: apiGroups: [""] resources: ["configmaps"] verbs: ["update"] El sujeto puede actualizar el |
- rules: apiGroups: [""] resources: ["configmaps"] verbs: ["list"] - rules: apiGroups: [""] resources: ["configmaps"] resourceNames: ["seccomp-high"] verbs: ["update"] Concede |
- rules: apiGroups: [""] resources: ["configmaps"] verbs: ["update", "list"] Concede acceso |
No permitir que las cuentas de servicio modifiquen los recursos de RBAC
No enlaces recursos de Role
o ClusterRole
que tengan permisos de bind
, escalate
,
create
, update
o patch
en el grupo de APIs rbac.authorization.k8s.io
a cuentas de servicio de ningún espacio de nombres. escalate
y bind
en particular pueden permitir que un atacante eluda los mecanismos de prevención de escaladas integrados en el control de acceso basado en roles.
Cuentas de servicio de Kubernetes
Crear una cuenta de servicio de Kubernetes para cada carga de trabajo
Crea una cuenta de servicio de Kubernetes independiente para cada carga de trabajo. Asigna un Role
o un ClusterRole
con los mínimos privilegios a esa cuenta de servicio.
No usar la cuenta de servicio predeterminada
Kubernetes crea una cuenta de servicio llamada default
en cada espacio de nombres. La cuenta de servicio default
se asigna automáticamente a los pods que no especifican explícitamente una cuenta de servicio en el manifiesto. No vincules un Role
o un ClusterRole
a la cuenta de servicio default
. Kubernetes puede asignar la cuenta de servicio default
a un pod que no necesite el acceso concedido en esos roles.
No montar automáticamente los tokens de cuentas de servicio
El campo automountServiceAccountToken
de la especificación del pod indica a Kubernetes que inserte un token de credenciales de una cuenta de servicio de Kubernetes en el pod. El pod puede usar este token para hacer solicitudes autenticadas al servidor de la API de Kubernetes. El valor predeterminado de este campo es true
.
En todas las versiones de GKE, define automountServiceAccountToken=false
en la especificación del pod si tus pods no necesitan comunicarse con el servidor de la API.
Preferir los tokens efímeros a los tokens basados en secretos
De forma predeterminada, el proceso kubelet del nodo obtiene un token de cuenta de servicio de corta duración que rota automáticamente para cada pod. El kubelet monta este token en el pod como un volumen proyectado, a menos que asignes el valor false
al campo automountServiceAccountToken
en la especificación del pod. Cualquier llamada a la API de Kubernetes desde el pod usa este token para autenticarse en el servidor de la API.
Si recuperas manualmente los tokens de la cuenta de servicio, no utilices secretos de Kubernetes para almacenar el token. Los tokens de cuentas de servicio basados en secretos son credenciales antiguas que no caducan y no se rotan automáticamente. Si necesitas credenciales para cuentas de servicio, usa la API TokenRequest
para obtener tokens de corta duración que se roten automáticamente.
Revisar continuamente los permisos de RBAC
Revisa periódicamente tus roles y accesos de RBAC para identificar posibles vías de escalada y reglas redundantes. Por ejemplo, imagina una situación en la que no eliminas un RoleBinding
que vincula un Role
con privilegios especiales a un usuario eliminado. Si un atacante crea una cuenta de usuario en ese espacio de nombres con el mismo nombre que el usuario eliminado, se vinculará a ese Role
y heredará el mismo acceso. Las revisiones periódicas minimizan este riesgo.
Resumen de la lista de comprobación
Siguientes pasos
- Consulta los consejos para reforzar la seguridad de GKE.
- Consulta las prácticas recomendadas de RBAC de Kubernetes.
- Consulte otras prácticas recomendadas.
- Ver archivos de manifiesto de ejemplo para roles de clúster habituales