web-dev-qa-db-fra.com

Comprendre la propriété des fichiers utilisateur dans docker: comment éviter de modifier les autorisations des volumes liés

Considérez le fichier Dockerfile suivant:

FROM debian:testing
RUN  adduser --disabled-password --gecos '' docker
RUN  adduser --disabled-password --gecos '' bob 

dans un répertoire de travail avec rien d'autre. Construisez l'image du menu fixe:

docker build -t test .

puis exécutez un script bash sur le conteneur, liant le répertoire de travail à un nouveau sous-répertoire du répertoire personnel de bob:

docker run --rm -it -v $(pwd):/home/bob/subdir test 

À qui appartient le contenu de subdir sur le conteneur? Sur le conteneur, exécutez:

cd /home/bob/subdir
ls -l

annonce que nous voyons:

-rw-rw-r-- 1 docker docker 120 Oct 22 03:47 Dockerfile

Saint Fume! docker est propriétaire du contenu! De retour sur la machine hôte en dehors du conteneur, nous voyons que notre utilisateur d'origine possède toujours le Dockerfile. Essayons de corriger la propriété du répertoire personnel de bob. Sur le conteneur, exécutez:

chown -R bob:bob /home/bob
ls -l 

et on voit:

-rw-rw-r-- 1 bob bob 120 Oct 22 03:47 Dockerfile

Mais attendez! en dehors du conteneur, nous exécutons maintenant ls -l

-rw-rw-r-- 1 1001 1001 120 Oct 21 20:47 Dockerfile

nous ne possédons plus notre propre fichier. Terrible nouvelle!


Si nous n'avions ajouté qu'un seul utilisateur dans l'exemple ci-dessus, tout se serait passé plus facilement. Pour une raison quelconque, Docker semble créer tout répertoire personnel appartenant au premier (=== -) utilisateur rencontré (même si cet utilisateur est déclaré précédemment). image). De même, cet utilisateur est le premier qui correspond aux mêmes autorisations de propriété que mon utilisateur local.

Question 1 Est-ce correct? Quelqu'un peut-il m'indiquer de la documentation à ce sujet, je ne fais que supposer en fonction de l'expérience ci-dessus.

Question 2: C'est peut-être juste parce qu'ils ont tous les deux la même valeur numérique sur le noyau, et si j'ai testé sur un système où mon utilisateur personnel n'était pas id 1000 alors les autorisations seraient modifiées dans tous les cas?

Question: La vraie question est, bien sûr, 'que dois-je faire à ce sujet?' Si bob est connecté en tant que bob sur la machine hôte donnée, il devrait pouvoir exécuter le conteneur en tant que bob et ne pas avoir les autorisations de fichier modifiées sous son compte hôte. Dans l'état actuel des choses, il doit en fait exécuter le conteneur en tant qu'utilisateur docker pour éviter que son compte ne soit modifié.

Je vous entends demander Pourquoi ai-je quand même un fichier Docker aussi étrange? . Je me demande aussi parfois. J'écris un conteneur pour une application Web (RStudio-server) qui permet à différents utilisateurs de se connecter, qui utilise simplement les noms d'utilisateur et les informations d'identification de la machine Linux comme noms d'utilisateur valides. Cela m'amène à la motivation peut-être inhabituelle de vouloir créer plusieurs utilisateurs. Je peux contourner cela en créant l'utilisateur uniquement au moment de l'exécution et tout va bien. Cependant, j'utilise une image de base qui a ajouté un seul utilisateur docker afin qu'elle puisse être utilisée de manière interactive sans être exécutée en tant que root (conformément aux meilleures pratiques). Cela ruine tout puisque cet utilisateur devient le premier et finit par tout posséder. Il essaie donc de se connecter en cas d'échec des autres utilisateurs (l'application ne peut pas démarrer manque d'autorisations d'écriture). Faire exécuter le script de démarrage chown résout d’abord ce problème, mais au détriment des volumes liés qui modifient les autorisations (de toute évidence, un problème si nous lions des volumes).

63
cboettig

Est-ce exact? Quelqu'un peut-il m'indiquer de la documentation à ce sujet, je ne fais que supposer en fonction de l'expérience ci-dessus.

C’est peut-être simplement parce qu’ils ont tous les deux la même valeur numérique sur le noyau, et si j’essayais sur un système où mon utilisateur n’était pas id 1000, les autorisations seraient modifiées dans tous les cas?

Prenez connaissance de info coreutils 'chown invocation', Cela vous donnera peut-être une meilleure idée du fonctionnement des autorisations/de la propriété des fichiers.

En principe, chaque fichier de votre ordinateur est associé à un ensemble de bits qui définissent ses autorisations et sa propriété. Lorsque vous chown un fichier, vous ne définissez que ces bits.

Lorsque vous chown un fichier destiné à un utilisateur/groupe particulier à l'aide du nom d'utilisateur ou du nom du groupe, chown recherchera dans /etc/passwd Le nom d'utilisateur et /etc/group Le groupe pour tenter de mapper le nom sur un ID. Si le nom d'utilisateur/nom de groupe n'existe pas dans ces fichiers, chown échouera.

root@dc3070f25a13:/test# touch test
root@dc3070f25a13:/test# ll
total 8
drwxr-xr-x  2 root root 4096 Oct 22 18:15 ./
drwxr-xr-x 22 root root 4096 Oct 22 18:15 ../
-rw-r--r--  1 root root    0 Oct 22 18:15 test
root@dc3070f25a13:/test# chown test:test test
chown: invalid user: 'test:test'

Cependant, vous pouvez chown un fichier utilisant des identifiants quelconques (dans des limites d’entiers positifs supérieurs, bien sûr), qu’il existe ou non un utilisateur/groupe avec ces identifiants sur votre ordinateur.

root@dc3070f25a13:/test# chown 5000:5000 test
root@dc3070f25a13:/test# ll
total 8
drwxr-xr-x  2 root root 4096 Oct 22 18:15 ./
drwxr-xr-x 22 root root 4096 Oct 22 18:15 ../
-rw-r--r--  1 5000 5000    0 Oct 22 18:15 test

Les bits UID et GID sont définis sur le fichier lui-même. Ainsi, lorsque vous montez ces fichiers dans votre conteneur de menu fixe, le fichier a le même UID de propriétaire/groupe que sur l'hôte, mais il est maintenant mappé sur /etc/passwd. dans le conteneur, qui sera probablement un utilisateur différent, sauf s'il est la propriété de root (UID 0).

La vraie question est, bien sûr, "que dois-je faire à ce sujet?" Si bob est connecté en tant que bob sur la machine hôte donnée, il devrait pouvoir exécuter le conteneur en tant que bob et ne pas modifier les autorisations de fichier sous son compte hôte. Dans l'état actuel des choses, il doit en fait exécuter le conteneur en tant que docker d'utilisateur pour éviter que son compte ne soit modifié.

Il semble qu'avec votre configuration actuelle, vous devez vous assurer que vos UID> noms d'utilisateur dans /etc/passwd Sur votre hôte correspondent à vos UID> noms d'utilisateur dans vos conteneurs /etc/passwd Si vous souhaitez interagir avec votre répertoire d'utilisateurs monté en tant que même utilisateur connecté à l'hôte.

Vous pouvez créer un utilisateur avec un identifiant spécifique avec useradd -u xxxx. Mais bon, ça a l'air d'une solution compliquée ...

Vous devrez peut-être trouver une solution qui ne monte pas un répertoire de base des utilisateurs de l'hôte.

25
Chris McKinnel

Deux options que j'ai trouvées:

CHOWN toutes les choses (après avoir fait votre travail)

J'ai fait docker run -v `pwd`/shared:/shared image, et le conteneur a créé des fichiers dans pwd/shared qui appartiennent au processus de menu fixe. Toutefois, /shared est toujours la propriété de moi. Donc, dans le processus de docker, je fais

chown -R `stat -c "%u:%g" /shared` /shared

stat -c "%u:%g" /shared résultats 1000:1000 dans mon cas, étant le uid:gid de mon utilisateur. Même s'il n'y a pas d'utilisateur 1000 dans le conatainer du docker, l’identifiant est là (et stat /shared dit simplement "inconnu" si vous demandez le nom d'utilisateur).

Quoi qu'il en soit, chown transfère docilement la propriété du contenu de /shared à 1000:1000 (qui, en ce qui le concerne, n’existe pas, mais en dehors du conteneur, c’est moi). Donc, je possède maintenant tous les fichiers. Le conteneur peut toujours modifier les choses s'il le souhaite, car de son point de vue, il s'agit de root.

Et tout va bien avec le monde.

docker run -u afin que tous les fichiers créés aient automatiquement le bon propriétaire

Une autre façon de faire est le -u drapeau sur le docker.

docker run -v `pwd`/shared:/shared -u `stat -c "%u:%g" /shared` ubuntu bash

De cette façon, l'utilisateur du menu fixe à l'intérieur du conteneur est youruid:yourgid.

Cependant: cela signifie abandonner votre autorité racine dans le conteneur (apt-get install, etc.). Sauf si vous créez un utilisateur avec ce nouvel uid et l'ajoutez au groupe root.

54
Jared Forsyth

Donc, je me suis retrouvé dans ce post à chercher comment restaurer la propriété de tous les fichiers (appartenant à la racine) qui sortaient d'un conteneur de menu fixe fonctionnant en tant que root, à mon utilisateur non privilégié de l'hôte .

J'avais besoin du processus à l'intérieur du conteneur pour s'exécuter en tant que root, je ne peux donc pas utiliser -u lors de l'exécution de docker.

Je ne suis pas fier de ce que j'ai fait, mais à la fin de mon script bash, j'ai ajouté ceci:

docker run --rm -it \
    --entrypoint /bin/sh \
    -e Host_UID=`id -u` \
    -v ${Host_FOLDER_OWNED_BY_ROOT}:/tmp \
    Alpine:latest \
    -c 'chown -R ${Host_UID}:${Host_UID} /tmp/'

Brisons quelques lignes:

  • Exécutez/bin/sh à l'intérieur du conteneur:

--entrypoint/bin/sh

  • Transmettez l'uid de l'utilisateur actuel en tant que variable d'environnement dans le conteneur:

-e ID_Hôte = `id -u`

  • Montez le dossier que vous voulez revendre à votre utilisateur ( rempli de fichiers appartenant à root, sortis par le conteneur précédent qui fonctionnait en tant que root ), sous ce nouveau conteneur /tmp:

-v $ {Host_FOLDER_OWNED_BY_ROOT}:/tmp

  • Exécutez chown de manière récursive avec l'ID utilisateur de l'hôte sur le répertoire cible (monté à l'intérieur du conteneur dans /tmp):

-c 'chown -R $ {Host_UID}: $ {Host_UID}/tmp /'

Donc, avec cela, j'ai récupéré les fichiers appartenant à mon utilisateur actuel sans avoir à "faire passer" les privilèges à root ou à Sudo.

C'est sale, mais ça a fonctionné. J'espère que j'ai aidé.

2
BBerastegui