¿Cómo agregar usuarios al contenedor Docker?


286

Tengo un contenedor acoplable con algunos procesos (uwsgi y apio) ejecutándose dentro. Quiero crear un usuario de apio y un usuario de uwsgi para estos procesos, así como un grupo de trabajadores al que pertenecerán, para asignar permisos.

Intenté agregar RUN adduser uwsgiy RUN adduser celerya mi Dockerfile, pero esto está causando problemas, ya que estos comandos solicitan información (he publicado las respuestas de la compilación a continuación).

¿Cuál es la mejor manera de agregar usuarios a un contenedor Docker para establecer permisos para los trabajadores que se ejecutan en el contenedor?

La imagen de My Docker está construida a partir de la base oficial Ubuntu14.04.

Aquí está la salida del Dockerfile cuando se ejecutan los comandos adduser:

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] 

Respuestas:


489

El truco es usar en useraddlugar de su contenedor interactivo adduser. Normalmente creo usuarios con:

RUN useradd -ms /bin/bash newuser

que crea un directorio de inicio para el usuario y asegura que bash sea el shell predeterminado.

Luego puede agregar:

USER newuser
WORKDIR /home/newuser

a tu dockerfile. Cada comando posterior, así como las sesiones interactivas se ejecutarán como usuario newuser:

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

Es posible que deba otorgar newuserlos permisos para ejecutar los programas que desea ejecutar antes de invocar el comando del usuario.

Usar usuarios no privilegiados dentro de contenedores es una buena idea por razones de seguridad. También tiene algunos inconvenientes. Lo que es más importante, las personas que obtengan imágenes de su imagen tendrán que volver a la raíz antes de poder ejecutar comandos con privilegios de superusuario.


143
Recomiendo usar las opciones de nombre completo en un Dockerfile, como en un script, en lugar de las cortas (más para usar cuando se usa interactivamente IMO). useradd --create-home --shell /bin/bashEs más comprensible / legible para los compañeros de trabajo.
Baptiste Mathus

25
Para establecer una contraseña, puede usar chpasswd como:RUN echo 'newuser:newpassword' | chpasswd
iuridiniz

3
Tenga en cuenta que si está creando un nuevo usuario con una ID de usuario grande, la ventana acoplable puede bloquearse / bloquearse al intentar crear lastlog , un archivo escaso masivo. Evita esto con la --no-log-initopción de useradd.
davidA

10
Buen consejo, @iuridiniz! No olvides llamarlo antes USER newuser. Si también necesita que el usuario tenga privilegios de root, también puede incluir adduser <username> sudo.
Yamaneko

66
/bin/sh: useradd: not foundlinux alpino
deathangel908

92

Para evitar las preguntas interactivas de adduser, puede llamarlo con estos parámetros:

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

El --gecosparámetro se usa para establecer la información adicional. En este caso, solo está vacío.

En sistemas con busybox (como Alpine), use

RUN adduser -D -g '' newuser

Ver busybox adduser


3
¡Gracias! Parece que adduserla solución de alto nivel generalmente se prefiere al uso de funciones de bajo nivel como useradd.
akhmed

adduser: unrecognized option: gecosEsto no parece funcionar en Alpine.
weberc2

¿Qué hace --disabled-password y cómo podemos establecer una contraseña para el usuario al mismo tiempo en el Dockerfile?
Hossein

72

Ubuntu

Pruebe las siguientes líneas en Dockerfile:

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

useraddopciones (ver:) man useradd:

  • -r, --systemCrear una cuenta del sistema. ver: Implicaciones creando cuentas del sistema
  • -m, --create-homeCree el directorio de inicio del usuario.
  • -d, --home-dir HOME_DIRDirectorio de inicio de la nueva cuenta.
  • -s, --shell SHELLShell de inicio de sesión de la nueva cuenta.
  • -g, --gid GROUPNombre o ID del grupo primario.
  • -G, --groups GROUPSLista de grupos suplementarios.
  • -u, --uid UIDEspecifique la ID de usuario. ver: Comprender cómo funcionan uid y gid en los contenedores Docker
  • -p, --password PASSWORDContraseña cifrada de la nueva cuenta (p ubuntu. Ej .).

Establecer contraseña de usuario predeterminada

Para establecer la contraseña del usuario, agregue -p "$(openssl passwd -1 ubuntu)"al useraddcomando.

Alternativamente, agregue las siguientes líneas a su Dockerfile:

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

La primera instrucción de shell es asegurarse de que esa -o pipefailopción esté habilitada antes RUNcon una tubería. Leer más: Hadolint: Cubriendo tu Dockerfile .


2
¿Por qué el usuario estaría en el grupo raíz? El objetivo de esto no es tener un usuario no root por motivos de seguridad
Novaterata

55
@Novaterata Dependiendo del uso. rootgrupo no indica que tienen acceso de root, solo tienen más acceso de lectura a algunos archivos (como registros), lo cual es útil, pero depende del proyecto.
kenorb

Puedo ver que esto funciona, automáticamente inicie sesión como usuario, pero sigo generando archivos propiedad de root. Incluso acabo de usar 'usuario USUARIO' ya que mi nombre de usuario en el grupo y usuario local es 'usuario'. Todavía genera archivos propiedad de root. ¿Hay algo más que debería estar haciendo? Básicamente estoy haciendo un contenedor acoplable que compila nuestra base de código. Por lo tanto, comprueba el código de svn, configura variables utilizando la fuente bash. ¿Podrían los comandos bash hacer cosas como root incluso si nunca me piden la contraseña de root?
JoeManiaci

14

Agregar un usuario en Docker y ejecutar su aplicación con ese usuario es una muy buena práctica para el punto de vista de seguridad. Para hacer eso, recomendaría los siguientes pasos:

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"]

Los pasos anteriores son un ejemplo completo de cómo copiar archivos de proyecto NodeJS, crear un grupo de usuarios y usuarios, asignar permisos al usuario para la carpeta del proyecto, cambiar al usuario recién creado y ejecutar la aplicación con ese usuario.


1
addgroup falló para mí, Paso 11/15: EJECUTAR addgroup -S nombre de usuario ---> Ejecutar en db9fd22d469d La opción s es ambigua (shell, sistema) adduser [--home DIR] [--shell SHELL] [--no-create -home] [--idid ID] [--idifuididid] [--iduididid] [--gecos GECOS] [--ingroup GROUP | --id ID] [--disabled-contraseña] [--disabled-login] [--encrypt-home] USUARIO Agregar un usuario normal
almacenando el

9

Puede imitar el Dockerfile de código abierto, por ejemplo:

Nodo: nodo12-github

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

superset: superset-github

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

Creo que es una buena forma de seguir el código abierto.


3

Todos tienen su favorito personal, y este es el mío:

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

Referencia: man useradd

La RUNlínea agregará el usuario y el grupo app:

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

Utilice un nombre más específico que appsi la imagen se va a reutilizar como imagen base. Como comentario, inclúyalo --shell /bin/bashsi realmente lo necesita.


Crédito parcial: respuesta de Ryan M


1

Alternativamente, puedes hacer así.

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

El primer comando crea un grupo llamado demo . El segundo comando crea un usuario de demostración y lo agrega al grupo de demostración creado anteriormente .

Banderas significa:

-G Group
-D Don't assign password
-H Don't create home directory

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.