4.1 KiB
Le namespace user
Introduction
L'espace de noms user
est plutôt pratique car il permet de virtualiser la
liste et les droits des utilisateurs.
Par exemple, on va pouvoir entrer dans un conteneur en tant que super-utilisateur à partir d'un compte d'un simple utilisateur. Il nous sera alors possible d'effectuer toutes les actions privilégiées dont nous pourrions avoir besoin à l'intérieur de cet espace de noms, sans que cela ne réduise la sécurité des composants à l'extérieur de cet espace.
Comportement vis-à-vis des autres namespaces
Alors qu'il est normalement nécessaire d'avoir des privilèges pour créer de nouveaux espaces de noms, en commençant par demander un namespace utilisateur, on obtient les privilèges requis pour créer tous les autres types de namespaces.
Grâce à cette technique, il est possible de lancer des conteneurs en tant que
simple utilisateur ; les projets podman
et
Singularity, ... reposent en grande partie sur cela.
Correspondance des utilisateurs et des groupes
Comme pour les autres espaces de noms, le namespace user
permet de ne
garder dans le nouvel espace, que les utilisateurs et les groupes utiles au
processus, en les renumérotant au passage si besoin.
L'utilisateur -2 : nobody\
Lorsque l'on arrive dans un nouvel espace, aucun utilisateur ni groupe n'est défini. Dans cette situation, tous les identifiants d'utilisateur et de groupe, renvoyés par le noyau sont à -2 ; valeur qui correspond par convention à l'utilisateur nobody et au groupe nogroup.
-1 étant réservé pour indiquer une erreur dans le retour d'une commande, ou la non-modification d'un paramètre passé en argument d'une fonction.
uid_map
et gid_map
\
Pour établir la correspondance, une fois que l'on a créé le nouveau
namespace, ces deux fichiers, accessibles dans /proc/self/
, peuvent être
écrits une fois.
uid_map
{-}
\
Sur chaque ligne, on doit indiquer :
- L'identifiant marquant le début de la plage d'utilisateurs, pour le processus en question.
- L'identifiant marquant le début de la plage d'utilisateurs, pour le processus affichant le fichier.
- La taille de la plage.
Par exemple, le namespace user
initial défini la correspondance suivante :
Cela signifie que les utilisateurs dont l'identifiant court de 0 à MAX_INT - 2
inclus, dans cet espace de noms, correspondent aux utilisateurs allant de 0 à
MAX_INT - 1
inclus, pour le processus affichant ce fichier.
Lorsque l'on crée un namespace user
, généralement, la correspondance vaut :
Dans cette situation, on comprend que notre processus considère que l'utilisateur root, dans le conteneur équivaut à l'utilisateur 1000 hors de l'espace de noms.
gid_map
{-}
\
Le principe est identique pour ce fichier, mais agit sur les correspondances des groupes au lieu des utilisateurs.
Il y a cependant un subtilité car il faut écrire la chaîne deny
dans le
fichier setgroups
avant de modifier gid_map
.
Utilisation basique de l'espace de noms
Avec unshare(1)
, voici comment, en tant que simple utilisateur, se dissocier
de plusieurs namespaces en gardant un environnement cohérent, dans lequel on
devient le super-utilisateur :
Un capsh --print
nous montre que l'on est bien root
et que l'on possède
toutes les capabilities. Cependant, cela ne signifie pas que l'on a tous les
droits sur le système ; il y a plusieurs niveaux de validation qui entrent en
jeu. L'idée étant que l'on a été désigné root dans son conteneur, on devrait
pouvoir y faire ce que l'on veut, tant que l'on n'agit pas en dehors.
Aller plus loin {-}
N'hésitez pas à jeter un œil à la page du manuel consacrée à ce namespace :
user_namespaces(7)
.