Accueil Le blog ebiznext
OpenShift : RBAC et SCC

Imaginons que nous recevons une quarantaine de serveurs comme par magie (si si je vous assure que ça peut se produire). Nous y installons un cluster OpenShift. L’information se propage à toutes les équipes qui voudraient l’utiliser. Vous souhaitez donner des accès au cluster mais surtout pas les droits admin. En plus, nous devons également isoler les équipes entre-elles. C’est exactement le but de cet article qui est d’expliquer le fonctionnement et la gestion des droits dans OpenShift. Pour cela, nous allons voir les différents aspects que sont les Role Based Access Control (RBAC), les utilisateurs, les Service Account (SA) et les Security Context Constraints (SCC). Une compétence minimale est requise sur OpenShift ou Kubernetes.

Role Based Access Control (RBAC)

Les RBAC définissent les actions auxquelles les utilisateurs et groupes ont le droit. Les actions non définies ne sont pas autorisées.

Il existe trois types de ressource pour gérer les autorisations

  • Rules: ensemble de Verbs ou d’actions (get, list, create, update, delete, deletecollection ou watch) autorisées sur des types de ressources.
  • Roles: ensemble de Rules pouvant être associé à des utilisateurs ou des groupes.
  • Bindings: liaison entre un rôle et des utilisateurs ou groupes.

OpenShift fournit une pléthore de rôles pouvant autoriser certaines actions à des utilisateurs ou des groupes au niveau des ressources du cluster ou des projets. Si cela ne suffisait pas, il est possible de créer vos propres rôles.

Relationships between cluster roles, local roles, cluster role bindings, local role bindings, users, groups and service accounts 1

Quelques rôles prédéfinis

Nom Description
cluster-admin Rôle de super utilisateur pouvant effectuer n’importe quelle action sur tout le cluster
cluster-status Rôle permettant de visualiser les informations du cluster
admin Permet de modifier et visualiser toutes les ressources d’un projet à l’exception des quotas
edit Permet de modifier et visualiser toutes les ressources d’un projet à l’exception des quotas et l’affectation des rôles
view Permet de visualiser toutes les ressources d’un projet

Liste des Rules par rôle

La commande suivante permet de connaître, pour le rôle admin, les verbs autorisés sur les différents types de resources. Les verbs ou les types de resources non présents ne sont pas autorisés pour le rôle.

$ oc describe clusterrole.rbac admin

Name:         admin
Labels:       kubernetes.io/bootstrapping=rbac-defaults
Annotations:  openshift.io/description=A user that has edit rights within the project and can change the project s membership.
              rbac.authorization.kubernetes.io/autoupdate=true
PolicyRule:
  Resources                                Non-Resource URLs  Resource Names  Verbs
  ---------                                -----------------  --------------  -----
  appliedclusterresourcequotas             []                 []              [get list watch]
  bindings                                 []                 []              [get list watch]
  buildconfigs                             []                 []              [create delete deletecollection get list patch update watch]
  buildconfigs/instantiate                 []                 []              [create]
  buildconfigs/instantiatebinary           []                 []              [create]
  buildconfigs/webhooks                    []                 []              [create delete deletecollection get list patch update watch]
  buildlogs                                []                 []              [create delete deletecollection get list patch update watch]
  builds                                   []                 []              [create delete deletecollection get list patch update watch]
  builds/clone                             []                 []              [create]
  builds/details                           []                 []              [update]
  ... etc

Les utilisateurs et les groupes

Les Users sont des utilisateurs physiques qui intéragissent avec la console OpenShift ou bien le client OC. Par exemple, ils peuvent être associés à des rôles du cluster et être membre d’un ou plusieurs groupes. Un groupe peut également être associé à des rôles.

Quelques commandes

Liste des utilisateurs

$ oc get user

Ajoute un rôle à un utilisateur

$ oc adm policy add-role-to-user ROLE USER [-n PROJECT]

Exemple : affecte le rôle admin sur le projet hello-world à l’utilisateur leeloo

$ oc adm policy add-role-to-user admin leeloo -n hello-world

Ajoute un rôle à un groupe

$ oc adm policy add-role-to-group ROLE GROUP [-n PROJECT]

Exemple : affecte le rôle cluster-admin au groupe administrateurs

$ oc adm policy add-role-to-group cluster-admin administrateurs

Association entre le role et utilisateur ou groupe

$ oc get rolebinding [-n PROJECT]

Exemple : liste des rôles pour le projet hello-world

$ oc get rolebinding -n hello-world

NAME                    ROLE                    USERS     GROUPS                              SERVICE ACCOUNTS   SUBJECTS
admin                   /admin                            administrateurs
system:deployer         /system:deployer                                                      deployer
system:deployers        /system:deployer                                                      deployer
system:image-builder    /system:image-builder                                                 builder
system:image-builders   /system:image-builder                                                 builder
system:image-puller     /system:image-puller              system:serviceaccounts:hello-world
system:image-pullers    /system:image-puller              system:serviceaccounts:hello-world

Les Service Accounts (SA)

Les Service Accounts (SA) sont des comptes de services permettant aux ressources du cluster d’être autorisées à effectuer certaines opérations comme par exemple le fait que certains containers puissent pousser une image dans la registry et pas d’autres. Ce sont en fait des utilisateurs logiques. Ils sont associés à un projet OpenShift (namespace). Par défaut, un projet contient trois Service Accounts. Chacun d’entre eux est associé à un type de POD: il y a les POD de build, de déploiements et ceux du projet.

Liste des Services Accounts du projet hello-world

$ oc get sa -n hello-world
NAME SECRETS AGE
builder 2 75d
default 2 75d
deployer 2 75d
  • builder: ce Service Account est associé aux POD dits de build, il permet via le rôle system:image-builder de leur donner les droits de pusher des images dans la registry. Les POD de Build sont éphémères, ils n’existent que pendant la phase de build d’une image.
  • deployer: les POD de déploiement ont les droits de modifier les replicas controller et les POD du projet grâce au rôle system:deployer dont bénéficie ce Service Account. Les POD de déploiements sont également éphémères, ils existent uniquement pendant la phase de déploiement du POD applicatif.
  • default: c’est le Service Account qui est utilisé par défaut par tous les autres pods du projet.

Secrets

Chaque Service Account est créé avec deux secret par défaut. Le premier secret permet l’accès aux APIs OpenShift et donc au client oc, quant au second il permet d’intéragir avec la registry Docker. Les secret sont des objets OpenShift contenant généralement des tokens. Ces deux token permettent des actions différentes, ils expirent uniquement lorsque l’on supprime le secret, dans ce cas un nouveau secret est automatiquement recréé.

$ oc describe sa builder -n hello-world
Name:                builder
Namespace:           hello-world
Image_pull_secrets:  builder-dockercfg-ab5pv
Mountable_secrets:   builder-token-9vrwx
                     builder-dockercfg-ab5pv
Tokens:              builder-token-9vrwx
                     builder-token-q956a

Token API

$ oc describe secret builder-token-9vrwx
Name:         builder-token-5wfwr
Namespace:    devops
Annotations:  kubernetes.io/service-account.name=builder
Type:  kubernetes.io/service-account-token
Data

====

token: ..............

On peut utiliser le token avec la commande oc. Le token est associé au Service Account, on ne pourra donc effectuer que les actions auxquelles il a le droit sur le projet.

$ oc whoami --token TOKEN
system:serviceaccount:hello-world:builder

Token pour la registry Docker

$ oc describe secret builder-token-q956a
Name:         builder-token-q282z
Namespace:    devops
Annotations:  kubernetes.io/created-by=openshift.io/create-dockercfg-secrets
              kubernetes.io/service-account.name=builder
Type:  kubernetes.io/service-account-token

Data

====

token: ..............

On peut utiliser ce token pour intéragir avec la registry docker. Il nous permet par exemple d’effectuer des pull et des push uniquement sur le repo du projet. Cela signifie qu’il y a également une gestion des droits sur la registry.

$ docker login -p TOKEN -u builder
$ docker push domain-registry/hello-world/image:1.0

NB: le nom de l’utilisateur n’a aucune importance

Security Context Constraints (SCC)

La Security Context Constraints (SCC) permet de définir ce qu’un POD a le droit ou n’a pas le droit de faire. Pour rappel, un POD est un ensemble de containers (1 à n) partageant le même réseau (communication en localhost) et les mêmes volumes, comme par exemple un pod contenant un container Apache et un container Tomcat.

OpenShift fournit quelques SCC

  $ oc get scc

  NAME               PRIV      CAPS      SELINUX     RUNASUSER          FSGROUP     SUPGROUP    PRIORITY   READONLYROOTFS   VOLUMES
  anyuid             false     []        MustRunAs   RunAsAny           RunAsAny    RunAsAny    10         false            [configMap downwardAPI emptyDir persistentVolumeClaim projected secret]
  hostaccess         false     []        MustRunAs   MustRunAsRange     MustRunAs   RunAsAny    none       false            [configMap downwardAPI emptyDir hostPath persistentVolumeClaim projected secret]
  hostmount-anyuid   false     []        MustRunAs   RunAsAny           RunAsAny    RunAsAny    none       false            [configMap downwardAPI emptyDir hostPath nfs persistentVolumeClaim projected secret]
  hostnetwork        false     []        MustRunAs   MustRunAsRange     MustRunAs   MustRunAs   none       false            [configMap downwardAPI emptyDir persistentVolumeClaim projected secret]
  node-exporter      false     []        RunAsAny    RunAsAny           RunAsAny    RunAsAny    none       false            [*]
  nonroot            false     []        MustRunAs   MustRunAsNonRoot   RunAsAny    RunAsAny    none       false            [configMap downwardAPI emptyDir persistentVolumeClaim projected secret]
  privileged         true      [*]       RunAsAny    RunAsAny           RunAsAny    RunAsAny    none       false            [*]
  restricted         false     []        MustRunAs   MustRunAsRange     MustRunAs   RunAsAny    none       false            [configMap downwardAPI emptyDir persistentVolumeClaim projected secret]
  
  
  • Détails du SCC restricted
$ oc describe scc restricted

Name:						restricted
Priority:					none
Access:
  Users:					none
  Groups:					system:authenticated
Settings:
  Allow Privileged:				false
  Default Add Capabilities:			none
  Required Drop Capabilities:			KILL,MKNOD,SETUID,SETGID
  Allowed Capabilities:				none
  Allowed Seccomp Profiles:			none
  Allowed Volume Types:				configMap,downwardAPI,emptyDir,persistentVolumeClaim,projected,secret
  Allowed Flexvolumes:				all
  Allow Host Network:				false
  Allow Host Ports:				false
  Allow Host PID:				false
  Allow Host IPC:				false
  Read Only Root Filesystem:			false
  Run As User Strategy:				MustRunAsRange
    UID:					none
    UID Range Min:				none
    UID Range Max:				none
  SELinux Context Strategy:			MustRunAs
    User:					none
    Role:					none
    Type:					none
    Level:					none
  FSGroup Strategy: MustRunAs
    Ranges:					none
  Supplemental Groups Strategy: RunAsAny
    Ranges:					none

Le SCC restricted est associé par défaut à tous les POD. Cela implique qu’ils utilisent la stratégie MustRunAsRange pour l’utilisateur de démarrage des containers. Cette stratégie autorise uniquement une plage de UID permettant de démarrer les containers. Le SCC ne définit pas cette plage car UID Range Min et Max du “Run As User” est définit à none. En fait, la plage est définie par le projet comme nous pouvons le voir ci-dessous.

$ oc describe project hello-world

Name:		hello-world
Annotations:	openshift.io/description=Hello World
                openshift.io/display-name=hello-world
                openshift.io/sa.scc.mcs=s0:c24,c19
                openshift.io/sa.scc.supplemental-groups=1000290000/10000
                openshift.io/sa.scc.uid-range=1000290000/10000
Display Name:	hello-world
...

L’annotation2 openshift.io/sa.scc.uid-range permet d’indiquer avec quel UID les containers vont et peuvent être démarrés. Par défaut, tous les containers vont être démarrés avec l’UID 1000290000. Il est possible de surcharger les POD du projet pour qu’ils soient démarrés avec un autre UID. Par contre, l’UID doit être compris entre 1000290000 et 1000290000+10000-1=1000299999. Pour quelles raisons OpenShift utilise-t-il des UID différents par projet ? L’une d’entre elles est que l’écriture dans les volumes soit effectuée avec des UID différents afin qu’un projet ne puisse pas lire le volume d’un autre.

apiVersion: v1
kind: Pod
metadata:
  name: security-context-demo
spec:
  securityContext:
    runAsUser: 1000290001
  containers:

Les POD surchargés avec un UID en dehors de la plage tomberont en erreur. De même les images définies avec le USER root (UID=1) dans le Dockerfile ne fonctionneront pas. Une dernière chose importante à connaître concerne la stratégie des Supplemental Groups3 qui est définie à RunAsAny. Cela signifie qu’il n’y aucune restriction sur les GID de groupe. On peut par exemple ajouter le groupe nfsnobody(65534) pour permettre aux POD d’accéder aux volumes NFS.

  • SCC anyuid

Pour pouvoir utiliser une image utilisant le USER défini dans le Dockerfile, il faudrait utiliser le SCC anyuid, ce qui est déconseillé, c’est pour cela qu’il est préférable d’aborder cette problèmatique sous un angle différent comme par exemple refaire le Dockerfile. Cela fera donc l’objet d’un autre article.

  • SCC privileged

Ce SCC permet de démarrer4 les containers avec le mode --privileged=true et --cap-add=ALL.

Conclusion

Les droits dans OpenShift sont trés complets, voire complexes (droits sur le cluster ou par projets) et permettent une gestion très fine grâce aux RBAC (Role Based Access Control). Ils permettent de donner des droits différents par projet et par type de POD (builder, deployer et default). Toujours est-il qu’un grand pouvoir implique de grandes responsabilités, réfléchissez donc bien avant de donner des droits. N’oubliez pas : on ne résoud pas un problème d’habilations en donnant plus ou trop de droits mais en les gérant correctemement.