Pregunta 23 | Configuración de Seguridad RBAC
Usar contexto: kubectl config use-context infra-prod
Tienes acceso de administrador al cluster2. También existe el contexto gianna@infra-prod que autentica como usuario gianna con el mismo cluster.
Existen recursos RBAC a nivel de cluster para, entre otras cosas, asegurar que el usuario gianna nunca pueda leer el contenido de los Secrets en todo el cluster. Confirma que esto es correcto o restringe los recursos RBAC existentes para asegurar esto.
Además, crea más recursos RBAC para permitir que el usuario gianna cree Pods y Deployments en los Namespaces security, restricted e internal. Es probable que el usuario reciba estos mismos permisos para otros Namespaces en el futuro.
Respuesta:
Parte 1 - verificar reglas RBAC existentes
Probablemente deberíamos echar un vistazo primero a los recursos RBAC existentes para el usuario gianna. No conocemos los nombres de los recursos pero sabemos que estos son a nivel de cluster, así que podemos buscar un ClusterRoleBinding:
k get clusterrolebinding -oyaml | grep gianna -A10 -B20 De esto vemos que el binding también se llama gianna:
k edit clusterrolebinding gianna
# kubectl edit clusterrolebinding gianna
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
creationTimestamp: "2020-09-26T13:57:58Z"
name: gianna
resourceVersion: "3049"
selfLink: /apis/rbac.authorization.k8s.io/v1/clusterrolebindings/gianna
uid: 72b64a3b-5958-4cf8-8078-e5be2c55b25d
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: gianna
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: gianna
# Vincula al usuario gianna al ClusterRole del mismo nombre:
k edit clusterrole gianna
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
creationTimestamp: "2020-09-26T13:57:55Z"
name: gianna
resourceVersion: "3038"
selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/gianna
uid: b713c1cf-87e5-4313-808e-1a51f392adc0
rules:
- apiGroups:
- ""
resources:
- secrets
- configmaps
- pods
- namespaces
verbs:
- list
Según la tarea, el usuario nunca debería poder leer el contenido de los Secrets. El verbo list podría indicar a primera vista que esto es correcto. También podemos verificar usando la Impersonación de Usuario de K8s:
➜ k auth can-i list secrets --as gianna
yes
➜ k auth can-i get secrets --as gianna
no
Pero echemos un vistazo más de cerca:
➜ k config use-context gianna@infra-prod
Switched to context "gianna@infra-prod".
➜ k -n security get secrets
NAME TYPE DATA AGE
default-token-gn455 kubernetes.io/service-account-token 3 20m
kubeadmin-token Opaque 1 20m
mysql-admin Opaque 1 20m
postgres001 Opaque 1 20m
postgres002 Opaque 1 20m
vault-token Opaque 1 20m
➜ k -n security get secret kubeadmin-token
Error from server (Forbidden): secrets "kubeadmin-token" is forbidden: User "gianna" cannot get resource "secrets" in API group "" in the namespace "security"
# Aún todo lo esperado, pero poder listar recursos también permite especificar el formato:
➜ k -n security get secrets -oyaml | grep password
password: ekhHYW5lQUVTaVVxCg==
{"apiVersion":"v1","data":{"password":"ekhHYW5lQUVTaVVxCg=="},"kind":"Secret","metadata":{"annotations":{},"name":"kubeadmin-token","namespace":"security"},"type":"Opaque"}
f:password: {}
password: bWdFVlBSdEpEWHBFCg==
...
El usuario gianna en realidad puede leer el contenido de los Secrets. Para prevenir esto deberíamos eliminar la capacidad de listarlos:
k config use-context infra-prod # volver al contexto admin
k edit clusterrole gianna
# kubectl edit clusterrole gianna
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
creationTimestamp: "2020-09-26T13:57:55Z"
name: gianna
resourceVersion: "4496"
selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/gianna
uid: b713c1cf-87e5-4313-808e-1a51f392adc0
rules:
- apiGroups:
- ""
resources:
# - secrets # eliminar
- configmaps
- pods
- namespaces
verbs:
- list
Parte 2 - crear reglas RBAC adicionales
Hablemos un poco sobre los recursos RBAC:
Un ClusterRole|Role define un conjunto de permisos y dónde está disponible, en todo el cluster o solo en un único Namespace.
Un ClusterRoleBinding|RoleBinding conecta un conjunto de permisos con una cuenta y define dónde se aplica, en todo el cluster o solo en un único Namespace.
Debido a esto hay 4 combinaciones diferentes de RBAC y 3 válidas:
Role + RoleBinding (disponible en un único Namespace, aplicado en un único Namespace)
ClusterRole + ClusterRoleBinding (disponible en todo el cluster, aplicado en todo el cluster)
ClusterRole + RoleBinding (disponible en todo el cluster, aplicado en un único Namespace)
Role + ClusterRoleBinding (NO POSIBLE: disponible en un único Namespace, aplicado en todo el cluster)
El usuario gianna debería poder crear Pods y Deployments en tres Namespaces. Podemos usar el número 1 o 3 de la lista anterior. Pero debido a que la tarea dice: "El usuario podría recibir estos mismos permisos para otros Namespaces en el futuro", elegimos el número 3 ya que requiere crear solo un ClusterRole en lugar de tres Roles.
k create clusterrole gianna-additional --verb=create --resource=pods --resource=deployments
# Esto creará un ClusterRole como:
# kubectl create clusterrole gianna-additional --verb=create --resource=pods --resource=deployments
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
creationTimestamp: null
name: gianna-additional
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- create
- apiGroups:
- apps
resources:
- deployments
verbs:
- create
# A continuación los tres bindings:
k -n security create rolebinding gianna-additional \
--clusterrole=gianna-additional --user=gianna
k -n restricted create rolebinding gianna-additional \
--clusterrole=gianna-additional --user=gianna
k -n internal create rolebinding gianna-additional \
--clusterrole=gianna-additional --user=gianna
# Esto creará RoleBindings como:
# k -n security create rolebinding gianna-additional --clusterrole=gianna-additional --user=gianna
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
creationTimestamp: null
name: gianna-additional
namespace: security
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: gianna-additional
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: gianna
Y probamos:
➜ k -n default auth can-i create pods --as gianna
no
➜ k -n security auth can-i create pods --as gianna
yes
➜ k -n restricted auth can-i create pods --as gianna
yes
➜ k -n internal auth can-i create pods --as gianna
yes
Siéntete libre de verificar esto también creando Pods y Deployments como usuario gianna a través del contexto gianna@infra-prod.