miércoles, marzo 27, 2019

Kubernetes: Cómo gestionar autorización de recursos con RBAC (Parte 1) #docker #kubernetes

El Control de Acceso Basado en Roles (Role Based Access Control - RBAC), es uno de los mecanismos que nos ofrece Kubernetes a la hora de autorizar el acceso a sus recursos (pods, nodos, secretos, etcétera). Éste es de hecho el mecanismo de autorización más usado (disponible en versión estable desde la versión 1.8 de Kubernetes).

Figura 1: Kubernetes: Cómo gestionar autorización de recursos con RBAC (Parte 1)

Prácticamente toda interacción con los recursos se realiza a través de su servidor API, lo que implica, que al final todo se limita a hacer peticiones HTTP a dicho servidor (componente esencial del nodo/s maestro o Control Panel). Para hablar de autorización basada en roles, lo primero es hablar de los roles en sí. Vamos a ello.

Roles en Kubernetes

En Kubernetes existen dos tipos llamados Role y ClusterRole. La mayor diferencia entre ambos es que Role pertenece a un nombre de espacio con concreto, mientras que el ClusterRole es global al clúster. Por lo que, en el caso de ClusterRole, su nombre debe ser único ya que pertenece al clúster. En el caso del Role, dos espacios de nombre distintos pueden tener un Role con el mismo nombre.

Otra de las diferencias que cabe mencionar, es que Role permite dar acceso a recursos que están dentro del mismo espacio de nombres, mientras que ClusterRole, además de poder dar acceso a recursos en cualquier espacio de nombres, también puede dar a acceso a recursos del clúster, como nodos entre otros.

Figura 2: Arquitectura de Kubernetes

Ahora que sabemos los tipos de roles, lo siguiente es saber quién le podemos asignar dichos roles. En este caso tenemos: cuentas de usuario, cuentas de servicio y grupos. Las cuentas de usuarios, como puedes imaginar son cuentas asignadas a un usuario en particular, mientras que las cuentas de servicios son usadas por procesos. Por ejemplo, imagina que nuestra aplicación necesita acceder de forma programática a recursos del clúster, para ello usaríamos una cuenta de servicio.

Por último, necesitamos el "pegamento" que enlace un role a una cuenta (de usuario o servicio) o grupo. Para ello existen dos recursos en Kubernetes: RoleBinding y ClusterRoleBinding. RoleBinding puede referenciar un role que esté en el mismo espacio de nombres, mientras que ClusterRoleBinding puede referenciar a cualquier role en cualquier espacio de nombres y asignar permisos de forma global.

RBAC en Minikube

Una vez hemos visto todos elementos que entran en juego en el campo del RBAC, veamos algunos ejemplos. Para estos, vamos a usar minikube. Asegúrate que RBAC está habilitado, para ello puedes arrancar minikube con el siguiente comando:

Figura 3: Arrancando minikube

Vamos a crear dos usuarios: cybercaronte y tuxotron, ambos pertenecientes a un grupo llamado developers.

1.- Creamos los certificados para cada usuario:
    mkdir ~/certs && cd ~/certs
2.- Creamos la clave y petición de firma para cybercaronte
    openssl genrsa -out cybercaronte.key 2048
    openssl req -new -key cybercaronte.key -out cybercaronte.csr -subj "/CN=cybercaronte/O=developers"
3.- Creamos la clave y petición de firma para tuxotron
    openssl genrsa -out tuxotron.key 2048
    openssl req -new -key tuxotron.key -out tuxotron.csr -subj "/CN=tuxotron/O=developers"
4.- Creamos los certificados para ambos usuarios
Si tienes instalado minikube en un directorio distinto de ~/.minikube, ajusta el comando
    openssl x509 -req -in cybercaronte.csr -CA ~/.minikube/ca.crt -CAkey ~/.minikube/ca.key -CAcreateserial -out cybercaronte.crt -days 90
    openssl x509 -req -in tuxotron.csr -CA ~/.minikube/ca.crt -CAkey ~/.minikube/ca.key -CAcreateserial -out tuxotron.crt -days 90
Ya tenemos creado los certificados para ambos usuarios, lo siguiente sería:

5.- Creamos los propios usuarios en nuestro clúster (minikube):
    kubectl config set-credentials cybercaronte --client-certificate=cybercaronte.crt --client-key=cybercaronte.key
    kubectl config set-credentials tuxotron --client-certificate=tuxotron.crt --client-key=tuxotron.key
Para poder crear usuarios tenemos que ser administradores del clúster. Cuando arrancamos minikube por defecto somos administradores, por eso podemos ejecutar los dos comandos anteriores.

Puedes comprobar que dichos usuarios han sido creados con el siguiente comando:
    kubectl config view
O bien, puedes imprimir el contenido del fichero ~/.kube/config
    cat ~/.kube/config
En ambos casos deberías ver los usuarios cybercaronte y tuxotron. Para ejecutar comandos con un usuario u otro, tenemos que decírselo a kubectl a través del contexto. Para ello vamos a añadir dos contextos nuevos, uno para cada usuario.

6.- Creamos dos contextos nuevos:
    kubectl config set-context cybercaronte --cluster=minikube --user=cybercaronte
    kubectl config set-context tuxotron --cluster=minikube --user=tuxotron
Para ver los contextos que tenemos, podemos ejecutar:
kubectl config get-contexts

    CURRENT        NAME       CLUSTER         AUTHINFO    NAMESPACE
     cybercaronte   minikube   cybercaronte
    *minikube       minikube   minikube
     tuxotron       minikube   tuxotron
Como vemos tenemos tres contextos, los dos que acabamos de crear, más minikube, que es al que nos da acceso como administrador al clúster. Además, éste es actualmente el contexto activo, denotado por el asterisco.

7.- Cambiamos de contexto:

Para cambiar de contexto, es decir, para cambiar de usuario y/o clúster (podemos trabajar con varios clústers a la vez), podemos hacerlo con el siguiente comando:
    kubectl config use-context tuxotron
Para comprobar que el contexto ha sido cambiado, o bien ejecutamos el comando `kubectl config get-contexts` y buscamos la entrada con el asterisco:
    kubectl config current-context
Hasta ahora todo lo que hemos hecho es crear dos usuarios, pero no le hemos dado ningún permiso. Por lo que, si intentamos acceder a cualquier recurso, la petición debería ser denegada. Como nuestro contexto actual es tuxotron, intentemos leer los pods del espacio de nombres default y veremos el error:
    kubectl get pods -n default                                                                                                   
    Error from server (Forbidden): pods is forbidden: User "tuxotron" cannot list resource "pods" in API group "" in the namespace "default"
Volvamos a usar nuestro contexto minikube para poder realizar algunas tareas administrativas:
    kubectl config use-context minikube
8.- Creamos espacios de nombres:

Vamos a crear 3 espacios de nombres, uno personal para cada usuario y un tercero al cual llamaremos equipo, en el que ambos usuarios podrán interactuar con recursos:
    kubectl create namespace cybercaronte
    kubectl create namespace tuxotron
    kubectl create namespace equipo
Para comprobar que nuestros espacios de nombres han sido creados:
    kubectl get namespace

    NAME             STATUS     AGE
    cybercaronte    Active    14m
    default        Active    17h
    equipo          Active    14m
    kube-public     Active    17h
    kube-system     Active    17h
    tuxotron        Active    14m
Hasta aquí la primera parte de nuestro artículo, continúa en la segunda parte para que terminemos de jugar con RBAC en Kubernetes.


Figura 4: Kubernetes: Cómo gestionar autorización de recursos con RBAC [Parte 1]

En el vídeo que te dejamos por aquí, tienes el proceso completo de lo que hemos hecho hasta ahora en esta fase de aprender a utilizar RBAC.

Más información

Recuerda que en nuestro libro “Docker:SecDevOps” (que escribimos junto a Elías Grande), aunque no hablamos expresamente de Kubernetes, sí que lo hacemos de Docker Swarm y los conceptos generales de clústers en Docker. Pero, sobre todo, el libro aclara muchos conceptos de Docker básicos y está enfocado a la seguridad de sus componentes así como al SecDevOps.

Figura 5: Libro de Docker: SecDevOps en 0xWord

Os dejo por aquí también algunas de las referencias que tenemos sobre Docker escritas ya en este blog, para que tengáis toda la información disponible y accesible.

[BlogPost] SecDevOps: Una explicación en 5 minutos (o poco más)
[BlogPost] Cómo montar un entorno de pentesting desde cero en Docker
[BlogPost] SuperLatch Docker: Integrar Latch con Docker y Kubernetes en tus apps
[BlogPost] Docker Distroless Images: Cómo crear imágenes Docker sin SO ni shell
[BlogPost] Dagda Docker Security Suite: Auditoría de seguridad en aplicaciones dockerizadas
[BlogPost] Docker de My WordPress in Paranoid Mode
[BlogPost] Docker de My WordPress in Paranoid Mode (WPM): "The Making of"
[BlogPost] Hacking Kubernetes: Auditoría de seguridad y explotación de vulnerabilidades
[BlogPost] Kubernetes: Cómo gestionar autorización de recursos con RBAC

Por cierto, tanto Rafael Troncoso como yo mismo (Fran Ramírez), estaremos esta semana en la RootedCon por si queréis hablar un rato con nosotros sobre Docker o Microhistorias, estaremos más que encantados de firmar cualquiera de nuestros libros (“Docker: SecDevOps” y “Microhistorias: Anécdotas y curiosidades de la informática (y los hackers)”).

Fran Ramírez, (@cyberhadesblog) es investigador de seguridad y miembro del equipo de Ideas Locas en CDO en Telefónica, co-autor del libro "Microhistorias: Anécdotas y Curiosidades de la historia de la informática (y los hackers)", del libro "Docker: SecDevOps" y del blog Cyberhades.

Rafael Troncoso (@tuxotron) es Senior Software Engineer en SAP Concur, co-autor del libro "Microhistorias: Anécdotas y Curiosidades de la historia de la informática (y los hackers)", del libro "Docker: SecDevOps" y del blog Cyberhades.

1 comentario:

  1. hola antes que nada gracias por el aporte. He seguido la guia que describen. he creado un user de prueba(paula) y los demas objetos.el problema es que, con sudo veo algunos contextos, con mi user(sergio) el cual instale k8 veo el contexto y NS original solamente.
    Con el user original no puedo usar estos nuevos contextos, o cambiarme a ellos. Con sudo o root si, pero no puedo usar la API, el servidor rechaza la conexion.
    Tengo 3 contextos visibles con sudo, dev, paula y prod, mas el default, visible con mi user, sergio.

    Mi objetivo es con el user paula acceder al NS Produccion, pero cambiando a este user, el server tambien rechaza la conexion.

    Estoy olvidando algo mas?

    Desde ya muchas gracias.

    Sergio

    ResponderEliminar