Qu'est-ce que cela signifie si un conteneur Linux (conteneur LXC) est appelé "non privilégié"?
Qu'est-ce que cela signifie si un conteneur Linux (conteneur LXC) est appelé "non privilégié"?
Réponses:
Les conteneurs LXC non privilégiés sont ceux qui utilisent des espaces de noms d'utilisateurs ( utilisateurs ). C'est-à-dire d'une fonctionnalité de noyau qui permet de mapper une plage d'UID sur l'hôte dans un espace de noms à l' intérieur duquel un utilisateur avec UID 0 peut à nouveau exister.
Contrairement à ma perception initiale des conteneurs LXC non privilégiés pendant un certain temps, cela ne signifie pas que le conteneur doit appartenir à un utilisateur hôte non privilégié. Ce n'est qu'une possibilité.
Pertinent est:
usermod [-v|-w|--add-sub-uids|--add-sub-gids]
)lxc.id_map = ...
)Ainsi, même root
peut posséder des conteneurs non privilégiés, car les UID efficaces des processus de conteneur sur l'hôte se retrouveront dans la plage définie par le mappage.
Cependant, root
vous devez d'abord définir les ID subordonnés. Contrairement aux utilisateurs créés via adduser
, root
aucune plage d'ID subordonnés ne sera définie par défaut.
Gardez également à l'esprit que la gamme complète que vous donnez est à votre disposition, vous pouvez donc avoir 3 conteneurs avec les lignes de configuration suivantes (uniquement le mappage UID illustré):
lxc.id_map = u 0 100000 100000
lxc.id_map = u 0 200000 100000
lxc.id_map = u 0 300000 100000
en supposant qu'il root
possède les UID subordonnés entre 100000 et 400000. Toute la documentation que j'ai trouvée suggère d'utiliser 65536 ID subordonnés par conteneur, certains utilisent 100000 pour le rendre plus lisible par l'homme, cependant.
En d'autres termes: vous n'avez pas à attribuer la même plage à chaque conteneur.
Avec plus de 4 milliards (~ 2^32
) d'ID subordonnés possibles, cela signifie que vous pouvez être généreux lorsque vous distribuez les plages subordonnées à vos utilisateurs hôtes.
Pour frotter cela à nouveau. Un invité LXC non privilégié n'a pas besoin d'être exécuté par un utilisateur non privilégié sur l'hôte.
Configuration de votre conteneur avec un mappage UID / GID subordonné comme celui-ci:
lxc.id_map = u 0 100000 100000
lxc.id_map = g 0 100000 100000
où l'utilisateur root
sur l'hôte possède cette plage d'ID subordonnée donnée, vous permettra de confiner encore mieux les invités.
Cependant, il y a un avantage supplémentaire important dans un tel scénario (et oui, j'ai vérifié que cela fonctionne): vous pouvez démarrer automatiquement votre conteneur au démarrage du système.
Habituellement, lorsque vous parcourez le Web pour obtenir des informations sur LXC, vous serez informé qu'il n'est pas possible de démarrer automatiquement un invité LXC non privilégié. Cependant, cela n'est vrai par défaut que pour les conteneurs qui ne sont pas dans le stockage à l'échelle du système pour les conteneurs (généralement quelque chose comme /var/lib/lxc
). S'ils le sont (ce qui signifie généralement qu'ils ont été créés par root et démarrés par root), c'est une toute autre histoire.
lxc.start.auto = 1
fera le travail très bien, une fois que vous l'avez mis dans votre configuration de conteneur.
J'ai eu un peu de mal avec ça moi-même, alors j'ajoute une section ici.
En plus de l'extrait de configuration inclus via lxc.include
lequel va généralement par le nom /usr/share/lxc/config/$distro.common.conf
(où $distro
est le nom d'une distribution), vous devez vérifier s'il y a également un /usr/share/lxc/config/$distro.userns.conf
sur votre système et l'inclure également. Par exemple:
lxc.include = /usr/share/lxc/config/ubuntu.common.conf
lxc.include = /usr/share/lxc/config/ubuntu.userns.conf
Ajoutez en outre les mappages d'ID subordonnés:
lxc.id_map = u 0 100000 65535
lxc.id_map = g 0 100000 65535
ce qui signifie que l'hôte UID 100000 se trouve root
dans l'espace de noms utilisateur de l'invité LXC.
Assurez-vous maintenant que les autorisations sont correctes. Si le nom de votre invité était stocké dans la variable d'environnement, $lxcguest
vous exécuteriez ce qui suit:
# Directory for the container
chown root:root $(lxc-config lxc.lxcpath)/$lxcguest
chmod ug=rwX,o=rX $(lxc-config lxc.lxcpath)/$lxcguest
# Container config
chown root:root $(lxc-config lxc.lxcpath)/$lxcguest/config
chmod u=rw,go=r $(lxc-config lxc.lxcpath)/$lxcguest/config
# Container rootfs
chown 100000:100000 $(lxc-config lxc.lxcpath)/$lxcguest/rootfs
chmod u=rwX,go=rX $(lxc-config lxc.lxcpath)/$lxcguest/rootfs
Cela devrait vous permettre d'exécuter le conteneur après que votre première tentative ait donné des erreurs liées aux autorisations.
chroot
cela peut aider, mais LXC combine divers des espaces de noms (UTS, mount etc ...) pour conteneuriser l'ensemble du système.
unshare
cela fonctionne déjà admirablement pour n'importe lequel / tous les différents espaces de noms - et vous obtiendra même un /proc
montage privé séparé avec un seul cli-switch. Si votre application unique est init
et votre chroot
est initramfs
alors vous obtenez un récipient entier en quelques secondes à plat.
Pour faire un suivi sur 0xC0000022L, dont la solution a bien fonctionné pour moi, j'ai écrit un script perl augmenter-uid-gid.pl pour automatiser les changements de propriété nécessaires pour que les fichiers dans les conteneurs LXC soient correctement mappés.
Sans cela, avec cette configuration proposée, un fichier dans le conteneur LXC rootfs appartenant à 0 / root sur l'hôte principal sera, dans le conteneur LXC lui-même, mappé à 65534 / nobody. Pour être mappés à 0 / root dans le conteneur LXC, ils doivent appartenir à 100000 sur l'hôte.
Ceci est décrit ici https://yeupou.wordpress.com/2017/06/23/setting-up-lxc-containers-with-mapped-giduid/ et le script peut être obtenu directement sur gitlab https://gitlab.com /yeupou/stalag13/blob/master/usr/local/bin/increase-uid-gid.pl
lxc
n'est pas une nécessité pour ce genre de chose. Vous pouvez créer un conteneur d'espace de noms de tout type à l'aide de l'util-linux
outilunshare
. Vous pouvez entrer dans ledit conteneur à l'aide de l'util-linux
outilnsenter
. Ce dernier outil vous permet également d'ajouter des processus en cours d'exécution à un conteneur déjà créé à partir de celui-ci. La prise en charge de l'espace de noms est implémentée dans le noyau.