Récemment, l'équipe Podman a reçu un rapport Bugzilla affirmant qu'il n'y avait aucun moyen d'empêcher Podman sans racine d'exécuter des conteneurs. Le signaleur a créé un compte utilisateur sans aucune entrée dans /etc/subuid
et /etc/subgid
et signalé que Podman sans racine pouvait toujours exécuter le hello-world
conteneur.
Supposition erronée
Suppression des informations utilisateur de /etc/subuid
n'empêche pas les utilisateurs d'utiliser Podman. Examinons plus en profondeur ce qui se passe lorsque quelqu'un utilise Podman sans racine pour exécuter un conteneur.
Tout d'abord, sachez que les images de conteneur telles que hello-world
ne sont que des archives tar avec du contenu JSON hébergé sur un serveur Web appelé registre d'images de conteneurs. Toute application capable de communiquer avec un serveur Web peut les supprimer à l'aide de protocoles Web standard et d'outils tels que curl
.
Lorsque Podman déroule une image, il crée d'abord et entre dans un espace de noms d'utilisateur. Cet espace de noms d'utilisateur mappe généralement l'UID de l'utilisateur à la racine (UID=0) dans l'espace de noms d'utilisateur. Il examine ensuite /etc/subuid
pour l'utilisateur et utilise les UID qui y sont répertoriés pour remplir le reste des UID disponibles dans l'espace de noms de l'utilisateur. Il en va de même pour les groupes via /etc/subgid
. S'il n'y a pas d'entrées dans /etc/subuid
et /etc/subgid
, l'espace de noms d'utilisateur se compose uniquement de l'UID de l'utilisateur mappé en tant que root. Une fois l'espace de noms d'utilisateur configuré, Podman extrait le contenu tar de l'image. Si l'image contient des fichiers appartenant à des utilisateurs autres que UID=0, alors Podman extrait et tente de chown
le contenu à l'utilisateur et au groupe définis. Si l'utilisateur et le groupe ne sont pas définis dans l'espace de noms d'utilisateur, alors le chown
échoue, et Podman échoue.
Dans l'exemple Bugzilla, le rapporteur a tenté d'exécuter hello-world
.
$ podman run hello-world
Resolved "hello-world" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
Trying to pull docker.io/library/hello-world:latest...
Getting image source signatures
Copying blob b8dfde127a29 done
Copying config d1165f2212 done
Writing manifest to image destination
Storing signatures
Hello from Docker!
…
Cela a fonctionné même si l'utilisateur n'avait aucune entrée dans /etc/subuid
et /etc/subgid
.
Entrons dans l'espace de noms d'utilisateur et voyons ce qui se passe.
Podman unshare cat /proc/self/uid_map
0 3267
Remarquez, mon compte est configuré sans accès dans /etc/subuid
. Podman mappe mon UID 3267 sur l'UID 0 pour une plage d'un UID. Regardons maintenant le contenu de l'image conteneur hello-world
. Entrez l'espace de noms d'utilisateur, montez le hello-world
image, et listez le contenu.
$ podman unshare
# mnt=$(podman image mount hello-world)
# ls -l $mnt
total 16
-rwxrwxr-x. 1 root root 13336 Mar 5 18:25 hello
Notez que le seul contenu est le hello
commande. Il s'agit d'un binaire GO lié statiquement, détenu par root dans l'espace de noms de l'utilisateur et UID=3267 dans mon répertoire personnel.
C'est pourquoi la commande a fonctionné, même sans les UID et GID supplémentaires.
Essayons d'exécuter une image de conteneur avec plusieurs UID.
$ podman run fedora echo hi
Resolved "fedora" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
Trying to pull registry.fedoraproject.org/fedora:latest...
Getting image source signatures
Copying blob 7679c09af385 done
Copying config 3567369c67 done
Writing manifest to image destination
Storing signatures
Error: Error committing the finished image: error adding layer with blob "sha256:7679c09af3851a1622782c74864351c296a0d1886813862fd7116383aeba9f07": Error processing tar file(exit status 1): potentially insufficient UIDs or GIDs available in user namespace (requested 0:12 for /var/spool/mail): Check /etc/subuid and /etc/subgid: lchown /var/spool/mail: invalid argument
Notez que Podman peut dérouler les archives tar (il les appelle des blobs). Lorsqu'il tente de les extraire, il échoue lorsqu'il essaie de chown
le /var/spool/mail
répertoire vers un GID (12) non défini dans l'espace de noms de l'utilisateur, et le conteneur échoue.
Conclusion
L'exécution de conteneurs non privilégiés est sûre et ne peut pas vraiment affecter le système plus que le simple fait d'avoir une connexion sur le système. L'utilisateur Podman effectue des tâches que les utilisateurs normaux peuvent effectuer :extraire le contenu des serveurs Web et le décompresser. Enfin, les utilisateurs peuvent même exécuter le contenu. Les seuls échecs se produisent lorsque l'utilisateur tente de basculer vers des UID auxquels l'utilisateur n'est pas autorisé via des commandes telles que chown
ou su
.
Dans l'exemple ci-dessus, Podman n'a rien fait qui nécessite des privilèges supplémentaires. Tous les processus exécutés via Podman par l'utilisateur étaient soumis aux mêmes contraintes que n'importe quel processus utilisateur. En fait, ils sont plus limités car ils sont enveloppés avec SELinux, SECCOMP et d'autres mécanismes de sécurité.
L'utilisation de Podman sans racine pour exécuter une image de conteneur n'est pas moins sécurisée que de permettre aux utilisateurs de télécharger des fichiers exécutables à partir d'un serveur Web et de les exécuter dans leur répertoire personnel.
Si vous souhaitez toujours empêcher certains utilisateurs d'un système d'exécuter Podman, vous devez modifier les autorisations sur Podman lui-même.
# chmod 750 /usr/bin/podman
# groupadd podman
# chown root:podman /usr/bin/podman
Ajoutez les utilisateurs auxquels vous souhaitez autoriser l'accès à Podman au groupe podman. Sachez simplement que lorsque Podman sera mis à jour, vous devrez faire le chmod
et chown
commandes à nouveau, et rpm -qV podman
signalera les problèmes d'installation.
Crédit supplémentaire
Pour les utilisateurs avancés, en particulier les personnes en calcul haute performance (HPC), nous avons ajouté un indicateur spécial, ignore_chown_errors
, au stockage du conteneur.
man storage.conf
…
ignore_chown_errors = "false"
ignore_chown_errors can be set to allow a non privileged user running with a single UID within a user namespace to run containers. The user can pull and use any image, even those with multiple uids. Note multiple UIDs will be squashed down to the default uid in the container. These images will have no separation between the users in the container. (default: false)
En définissant ce drapeau dans /etc/containers/storage.conf
de $HOME/.config/containers/storage.conf
sur true, Podman peut exécuter avec succès le conteneur Fedora.
$ grep ignore_chown_err /etc/containers/storage.conf
# ignore_chown_errors can be set to allow a non privileged user running with
ignore_chown_errors = "true"
$ podman unshare cat /proc/self/uid_map
0 3267 1
$ podman run fedora echo hi
Resolved "fedora" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
Trying to pull registry.fedoraproject.org/fedora:latest...
Getting image source signatures
Copying blob 7679c09af385 done
Copying config 3567369c67 done
Writing manifest to image destination
Storing signatures
hi
Cette fois, lorsque Podman a tenté de chown
le /var/spool/mail
répertoire et a reçu une erreur, il l'a ignorée et a continué. HPC ne souhaite pas que les utilisateurs aient plus d'un UID, ce qui permet à leurs utilisateurs d'exécuter des images OCI standard sans avoir à assouplir leurs paramètres de sécurité. Notez que cela fonctionne correctement tant que le seul UID que vous exécutez à l'intérieur du conteneur est la racine du conteneur. Si, pour une raison quelconque, le processus tente de remplacer l'UID par un UID non défini dans le conteneur, il échouera. De plus, dans la plupart des cas, tous les fichiers de l'image appartiendront à l'utilisateur. Cet utilisateur du conteneur dispose d'autorisations complètes de lecture/écriture sur tout le contenu.
[ Vous débutez avec les conteneurs ? Découvrez ce cours gratuit. Déploiement d'applications conteneurisées :présentation technique. ]
Récapitulez
Les administrateurs de Podman doivent savoir quels niveaux d'accès sont accordés. Assurez-vous de comprendre l'intention et la fonction de /etc/subuid
et /etc/subgid
, et leur impact sur la sécurité des conteneurs.
Enfin, utilisez le ignore_chown_errors
option avec soin. Il a été conçu pour les scénarios HPC.