Comment ajouter des utilisateurs au conteneur Docker?

286

J'ai un conteneur docker avec certains processus (uwsgi et céleri) en cours d'exécution à l'intérieur. Je veux créer un utilisateur céleri et un utilisateur uwsgi pour ces processus ainsi qu'un groupe de travailleurs auquel ils appartiendront tous les deux, afin d'attribuer des autorisations.

J'ai essayé d'ajouter RUN adduser uwsgiet RUN adduser celeryà mon Dockerfile, mais cela pose des problèmes, car ces commandes demandent une entrée (j'ai publié les réponses de la build ci-dessous).

Quelle est la meilleure façon d'ajouter des utilisateurs à un conteneur Docker afin de définir des autorisations pour les travailleurs exécutés dans le conteneur?

Mon image Docker est construite à partir de la base officielle Ubuntu14.04.

Voici la sortie du Dockerfile lorsque les commandes adduser sont exécutées:

Adding user `uwsgi' ...
Adding new group `uwsgi' (1000) ... 
Adding new user `uwsgi' (1000) with group `uwsgi' ... 
Creating home directory `/home/uwsgi' ...
Copying files from `/etc/skel' ... 
[91mEnter new UNIX password: Retype new UNIX password: [0m 
[91mpasswd: Authentication token manipulation error
passwd: password unchanged
[0m 
[91mUse of uninitialized value $answer in chop at /usr/sbin/adduser line 563.
[0m 
[91mUse of uninitialized value $answer in pattern match (m//) at /usr/sbin/adduser line 564.
[0m 
Try again? [y/N] 
Changing the user information for uwsgi
Enter the new value, or press ENTER for the default
    Full Name []: 
Room Number []:     Work Phone []:  Home Phone []:  Other []: 
[91mUse of uninitialized value $answer in chop at /usr/sbin/adduser line 589.
[0m 
[91mUse of uninitialized value $answer in pattern match (m//) at /usr/sbin/adduser line 590.
[0m 
Is the information correct? [Y/n] 
---> 258f2f2f13df 
Removing intermediate container 59948863162a 
Step 5 : RUN adduser celery 
---> Running in be06f1e20f64 
Adding user `celery' ...
Adding new group `celery' (1001) ... 
Adding new user `celery' (1001) with group `celery' ... 
Creating home directory `/home/celery' ...
Copying files from `/etc/skel' ... 
[91mEnter new UNIX password: Retype new UNIX password: [0m 
[91mpasswd: Authentication token manipulation error
passwd: password unchanged
[0m 
[91mUse of uninitialized value $answer in chop at /usr/sbin/adduser line 563.
[0m 
[91mUse of uninitialized value $answer in pattern match (m//) at /usr/sbin/adduser line 564.
[0m 
Try again? [y/N] 
Changing the user information for celery
Enter the new value, or press ENTER for the default
    Full Name []:   Room Number []:     Work Phone []: 
Home Phone []:  Other []: 
[91mUse of uninitialized value $answer in chop at /usr/sbin/adduser line 589.
[0m 
[91mUse of uninitialized value $answer in pattern match (m//) at /usr/sbin/adduser line 590.
[0m 
Is the information correct? [Y/n] 
rfj001
la source

Réponses:

489

L'astuce consiste à utiliser à la useraddplace de son wrapper interactif adduser. Je crée généralement des utilisateurs avec:

RUN useradd -ms /bin/bash newuser

qui crée un répertoire personnel pour l'utilisateur et garantit que bash est le shell par défaut.

Vous pouvez ensuite ajouter:

USER newuser
WORKDIR /home/newuser

à votre dockerfile. Chaque commande ainsi que les sessions interactives seront exécutées en tant qu'utilisateur newuser:

docker run -t -i image
newuser@131b7ad86360:~$

Vous devrez peut-être donner newuserles autorisations pour exécuter les programmes que vous souhaitez exécuter avant d'appeler la commande utilisateur.

L'utilisation d'utilisateurs non privilégiés à l'intérieur des conteneurs est une bonne idée pour des raisons de sécurité. Il présente également quelques inconvénients. Plus important encore, les personnes dérivant des images de votre image devront revenir à la racine avant de pouvoir exécuter des commandes avec des privilèges de superutilisateur.

Paul Staab
la source
143
Je recommanderais d'utiliser les options de nom complet dans un Dockerfile, comme dans un script, au lieu des courtes (plus à utiliser lorsqu'elles sont utilisées de manière interactive IMO). useradd --create-home --shell /bin/bashest plus compréhensible / lisible pour les collègues.
Baptiste Mathus
25
Afin de définir le mot de passe, vous pouvez utiliser chpasswd comme:RUN echo 'newuser:newpassword' | chpasswd
iuridiniz
3
Notez que si vous créez un nouvel utilisateur avec un ID utilisateur volumineux, le docker peut se bloquer / planter lors de la tentative de création de lastlog - un fichier fragmenté massif. Évitez cela avec l' --no-log-initoption useradd.
davA
10
Bon conseil, @iuridiniz! N'oubliez pas de l'appeler avant USER newuser. Si vous avez également besoin que l'utilisateur dispose de privilèges root, vous pouvez également les inclure adduser <username> sudo.
Yamaneko
6
/bin/sh: useradd: not foundalpine linux
deathangel908
92

Pour éviter les questions interactives par adduser, vous pouvez l'appeler avec ces paramètres:

RUN adduser --disabled-password --gecos '' newuser

Le --gecosparamètre est utilisé pour définir les informations supplémentaires. Dans ce cas, il est juste vide.

Sur les systèmes avec busybox (comme Alpine), utilisez

RUN adduser -D -g '' newuser

Voir addbox busybox

Raffael
la source
3
Merci! Il semble que la addusersolution de haut niveau soit généralement préférée à l'utilisation de fonctions de bas niveau comme useradd.
akhmed
adduser: unrecognized option: gecosCela ne semble pas fonctionner sur Alpine.
weberc2
que fait le mot de passe --disabled et comment pouvons-nous définir le mot de passe pour l'utilisateur en même temps dans le Dockerfile?
Hossein
72

Ubuntu

Essayez les lignes suivantes dans Dockerfile:

RUN useradd -rm -d /home/ubuntu -s /bin/bash -g root -G sudo -u 1001 ubuntu
USER ubuntu
WORKDIR /home/ubuntu

useraddoptions (voir:) man useradd:

Définition du mot de passe de l'utilisateur par défaut

Pour définir le mot de passe utilisateur, ajoutez -p "$(openssl passwd -1 ubuntu)"à la useraddcommande.

Vous pouvez également ajouter les lignes suivantes à votre Dockerfile:

SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN echo 'ubuntu:ubuntu' | chpasswd

La première instruction shell est de s'assurer que cette -o pipefailoption est activée avant RUNavec un tube dedans. En savoir plus: Hadolint: Linting your Dockerfile .

Kenorb
la source
2
Pourquoi l'utilisateur serait-il dans le groupe racine? Le but n'est pas d'avoir un utilisateur non root pour des raisons de sécurité
Novaterata
5
@Novaterata Selon l'utilisation. rootLe groupe n'indique pas qu'ils ont un accès root, mais juste qu'ils ont plus d'accès en lecture à certains fichiers (tels que les journaux), ce qui est utile, mais cela dépend du projet.
kenorb
Je peux voir que cela fonctionne, je suis automatiquement connecté en tant qu'utilisateur, mais je génère toujours des fichiers appartenant à root. J'ai même utilisé "utilisateur USER" car mon nom d'utilisateur sur l'utilisateur et le groupe local est "utilisateur". Génère toujours des fichiers appartenant à root. Y a-t-il autre chose que je devrais faire? Je fais essentiellement un conteneur docker qui compile notre base de code. Il extrait donc le code de svn, configure les variables en utilisant la source bash. Les commandes bash pourraient-elles faire les choses en tant que root même si on ne me demande jamais le mot de passe root?
JoeManiaci
14

Ajouter un utilisateur dans Docker et exécuter votre application sous cet utilisateur est une très bonne pratique pour le point de vue de la sécurité. Pour ce faire, je recommanderais les étapes ci-dessous:

FROM node:10-alpine

# Copy source to container
RUN mkdir -p /usr/app/src

# Copy source code
COPY src /usr/app/src
COPY package.json /usr/app
COPY package-lock.json /usr/app

WORKDIR /usr/app

# Running npm install for production purpose will not run dev dependencies.
RUN npm install -only=production    

# Create a user group 'xyzgroup'
RUN addgroup -S xyzgroup

# Create a user 'appuser' under 'xyzgroup'
RUN adduser -S -D -h /usr/app/src appuser xyzgroup

# Chown all the files to the app user.
RUN chown -R appuser:xyzgroup /usr/app

# Switch to 'appuser'
USER appuser

# Open the mapped port
EXPOSE 3000

# Start the process
CMD ["npm", "start"]

Les étapes ci-dessus sont un exemple complet de la copie de fichiers de projet NodeJS, de la création d'un groupe d'utilisateurs et d'un utilisateur, de l'attribution d'autorisations à l'utilisateur pour le dossier du projet, du passage à l'utilisateur nouvellement créé et de l'exécution de l'application sous cet utilisateur.

S.Mishra
la source
1
addgroup a échoué pour moi, Étape 11/15: RUN addgroup -S nom d'utilisateur ---> L'exécution dans db9fd22d469d L'option s est ambiguë (shell, système) adduser [--home DIR] [--shell SHELL] [--no-create -home] [--uid ID] [--firstuid ID] [--lastuid ID] [--gecos GECOS] [--ingroup GROUP | --gid ID] [--disabled-password] [--disabled-login] [--encrypt-home] USER Ajouter un utilisateur normal
apprenant
9

Vous pouvez imiter Dockerfile open source, par exemple:

Noeud: node12-github

RUN groupadd --gid 1000 node \
    && useradd --uid 1000 --gid node --shell /bin/bash --create-home node

surensemble: superset-github

RUN useradd --user-group --create-home --no-log-init --shell /bin/bash 
    superset

Je pense que c'est un bon moyen de suivre l'open source.

Ryan Miao
la source
3

Chacun a son favori personnel, et voici le mien:

RUN useradd --user-group --system --create-home --no-log-init app
USER app

Référence: man useradd

La RUNligne ajoutera l'utilisateur et le groupe app:

root@ef3e54b60048:/# id app
uid=999(app) gid=999(app) groups=999(app)

Utilisez un nom plus spécifique que appsi l'image doit être réutilisée comme image de base. En aparté, indiquez --shell /bin/bashsi vous en avez vraiment besoin.


Crédit partiel: réponse de Ryan M

Acumenus
la source
1

Alternativement, vous pouvez faire comme ça.

RUN addgroup demo && adduser -DH -G demo demo

La première commande crée un groupe appelé démo . La deuxième commande crée l' utilisateur de démonstration et l'ajoute au groupe de démonstration précédemment créé .

Drapeaux signifie:

-G Group
-D Don't assign password
-H Don't create home directory
Lukasz Dynowski
la source
0

Ajoutez cette ligne à votre Dockerfile (vous pouvez exécuter n'importe quelle commande linux de cette façon)

RUN useradd -ms /bin/bash yourNewUserName
K - La toxicité du SO augmente.
la source