Cambiar usuarios dentro de la imagen de Docker a un usuario no root

80

Estoy intentando cambiar de usuario al usuario de tomcat7 para configurar los certificados SSH.

Cuando lo hago su tomcat7, no pasa nada.

whoami todavía ruturns root después de hacer su tomcat7

Al hacer una more /etc/passwd, obtengo el siguiente resultado que muestra claramente que existe un usuario de tomcat7:

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
lp:x:7:7:lp:/var/spool/lpd:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
proxy:x:13:13:proxy:/bin:/bin/sh
www-data:x:33:33:www-data:/var/www:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
list:x:38:38:Mailing List Manager:/var/list:/bin/sh
irc:x:39:39:ircd:/var/run/ircd:/bin/sh
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
libuuid:x:100:101::/var/lib/libuuid:/bin/sh
messagebus:x:101:104::/var/run/dbus:/bin/false
colord:x:102:105:colord colour management daemon,,,:/var/lib/colord:/bin/false
saned:x:103:106::/home/saned:/bin/false
tomcat7:x:104:107::/usr/share/tomcat7:/bin/false

Lo que estoy tratando de solucionar es este error en Hudson:

Command "git fetch -t git@________.co.za:_______/_____________.git +refs/heads/*:refs/remotes/origin/*" returned status code 128: Host key verification failed.

Este es mi Dockerfile, toma una configuración y un archivo war de hudson existente que está alquilado y crea una imagen, hudson funciona bien, simplemente no puede acceder a git debido a que los certificados no existen para el usuario tomcat7.

FROM debian:wheezy

# install java on image
RUN apt-get update
RUN apt-get install -y openjdk-7-jdk tomcat7

# install hudson on image
RUN rm -rf /var/lib/tomcat7/webapps/*
ADD ./ROOT.tar.gz /var/lib/tomcat7/webapps/

# copy hudson config over to image
RUN mkdir /usr/share/tomcat7/.hudson
ADD ./dothudson.tar.gz /usr/share/tomcat7/
RUN chown -R tomcat7:tomcat7 /usr/share/tomcat7/

# add ssh certificates
RUN mkdir /root/.ssh
ADD ssh.tar.gz /root/

# install some dependencies
RUN apt-get update
RUN apt-get install --y maven
RUN apt-get install --y git
RUN apt-get install --y subversion

# background script
ADD run.sh /root/run.sh
RUN chmod +x /root/run.sh

# expose port 8080
EXPOSE 8080


CMD ["/root/run.sh"]

Estoy usando la última versión de Docker (Docker versión 1.0.0, compilación 63fe64c / 1.0.0), ¿es esto un error en Docker o me falta algo en mi Dockerfile?

Jan Vladimir Mostert
fuente
4
¿ USERConoce la instrucción Dockerfile?
Icecrime
1
No, ¿para qué sugieres que lo use?
Jan Vladimir Mostert
¿Sería posible generar certificados a través del Dockerfile usando la instrucción USER?
Jan Vladimir Mostert
3
Todo lo que haces RUNdespués de una USERinstrucción se realiza bajo el uid correspondiente, por lo que aunque no estoy seguro de entender perfectamente tu problema, parece que podría ser lo que estás buscando.
Icecrime
@icecrime no todo, lamentablemente. COPYcrea archivos como uid 0, lo que significa que el usuario no root no puede escribirlos, y la ejecución RUN chown ...en esos archivos no funcionará a menos que el usuario actual también sea root. Entonces, uno termina alternando entre root y el otro usuario a través del Dockerfile.
davidA

Respuestas:

119

No debe usarlo suen un archivo docker , sin embargo, debe usar las USERinstrucciones en el archivo Docker.

En cada etapa de la compilación de Dockerfile , se crea un nuevo contenedor para que cualquier cambio que realice en el usuario no persistirá en la siguiente etapa de compilación.

Por ejemplo:

RUN whoami
RUN su test
RUN whoami

Esto nunca diría que el usuario estaría testya que se genera un nuevo contenedor en el segundo whoami. La salida sería root en ambos (a menos que, por supuesto, ejecute USER de antemano).

Sin embargo, si lo hace:

RUN whoami
USER test
RUN whoami

Deberías ver rootentonces test.

Alternativamente, puede ejecutar un comando como un usuario diferente con sudo con algo como

sudo -u test whoami

Pero parece mejor utilizar las instrucciones oficiales admitidas.

Marcus Hughes
fuente
Tengo curiosidad por saber cómo asegurarme de que los comandos ejecutados previamente estén disponibles para el usuario configurado en el Dockerfile. Tengo una pregunta en la que las carpetas y los permisos establecidos previamente por root no están disponibles después de cambiar a otro usuario con la USERinstrucción.
Spencer Williams
3
Es posible que necesite COPY --chown=myuser ...más adelante.
x-yuri
39

Como un enfoque diferente a la otra respuesta, en lugar de indicar al usuario sobre la creación de la imagen en el Dockerfile, puede hacerlo a través de la línea de comandos en un contenedor en particular como por comando.

Con docker exec, use --userpara especificar qué cuenta de usuario usará la terminal interactiva (el contenedor debe estar ejecutándose y el usuario debe existir en el sistema contenedorizado):

docker exec -it --user [username] [container] bash

Ver https://docs.docker.com/engine/reference/commandline/exec/

Ese chico brasileño
fuente
6

Agregue esta línea al archivo de la ventana acoplable

USER <your_user_name>

Utilice la instrucción docker USER

vinay mavi
fuente
3

También debería poder hacer:

apt install sudo

sudo -i -u tomcat

Entonces deberías ser el usuario de tomcat. No está claro qué distribución de Linux está utilizando, pero esto funciona con Ubuntu 18.04 LTS, por ejemplo.

palabras por lo demás
fuente
1

En caso de que necesite realizar tareas con privilegios, como cambiar permisos de carpetas, puede realizar esas tareas como usuario raíz y luego crear un usuario sin privilegios y cambiar a él:

From <some-base-image:tag>

# Switch to root user
USER root # <--- Usually you won't be needed it - Depends on base image

# Run privileged command
RUN apt install <packages>
RUN apt <privileged command>

# Set user and group
ARG user=appuser
ARG group=appuser
ARG uid=1000
ARG gid=1000
RUN groupadd -g ${gid} ${group}
RUN useradd -u ${uid} -g ${group} -s /bin/sh -m ${user} # <--- the '-m' create a user home directory

# Switch to user
USER ${uid}:${gid}

# Run non-privileged command
RUN apt <non-privileged command>
RtmY
fuente
-8

No hay una forma real de hacer esto. Como resultado, cosas como mysqld_safe fallan y no se puede instalar mysql-server en un contenedor Docker de Debian sin pasar por 40 aros porque ... bueno ... aborta si no es root.

Puede usar USER, pero no podrá instalar apt-get install si no es root.

John Moser
fuente