Como adicionar usuários ao contêiner do Docker?


285

Eu tenho um contêiner de encaixe com alguns processos (uwsgi e aipo) em execução no interior. Desejo criar um usuário aipo e um usuário uwsgi para esses processos, bem como um grupo de trabalhadores ao qual ambos pertencerão, para atribuir permissões.

Tentei adicionar RUN adduser uwsgie RUN adduser celeryao meu Dockerfile, mas isso está causando problemas, pois esses comandos solicitam entrada (postamos as respostas da compilação abaixo).

Qual é a melhor maneira de adicionar usuários a um contêiner do Docker para definir permissões para trabalhadores em execução no contêiner?

Minha imagem do Docker foi criada a partir da base oficial do Ubuntu14.04.

Aqui está a saída do Dockerfile quando os comandos adduser são executados:

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] 

Respostas:


489

O truque é usar em useraddvez de seu wrapper interativo adduser. Eu costumo criar usuários com:

RUN useradd -ms /bin/bash newuser

que cria um diretório inicial para o usuário e garante que o bash é o shell padrão.

Você pode adicionar:

USER newuser
WORKDIR /home/newuser

ao seu dockerfile. Todos os comandos posteriores, bem como as sessões interativas, serão executados como usuário newuser:

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

Pode ser necessário fornecer newuserpermissões para executar os programas que você pretende executar antes de chamar o comando do usuário.

Usar usuários não privilegiados dentro de contêineres é uma boa idéia por motivos de segurança. Também tem algumas desvantagens. Mais importante, as pessoas que derivam imagens da sua imagem precisarão voltar ao root antes de poderem executar comandos com privilégios de superusuário.


141
Eu recomendo usar as opções de nome completo em um Dockerfile, como em um script, em vez das curtas (mais para serem usadas quando usadas IMO interativamente). useradd --create-home --shell /bin/bashé mais compreensível / legível para os colegas de trabalho.
Baptiste Mathus 22/03

25
A fim de senha definida, você poderia usar chpasswd como:RUN echo 'newuser:newpassword' | chpasswd
iuridiniz

3
Observe que, se você estiver criando um novo usuário com um ID de usuário grande, a janela de encaixe poderá travar / travar ao tentar criar lastlog - um arquivo esparso maciço. Evite isso com a --no-log-initopção de useradd.
DavidA

10
Boa dica, @iuridiniz! Não se esqueça de chamá-lo antes USER newuser. Se você também precisar que o usuário tenha privilégios de root, também poderá incluir adduser <username> sudo.
Yamaneko

6
/bin/sh: useradd: not foundalpino linux
deathangel908

91

Para evitar as perguntas interativas por adduser, você pode chamá-lo com estes parâmetros:

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

O --gecosparâmetro é usado para definir as informações adicionais. Neste caso, está apenas vazio.

Em sistemas com busybox (como Alpine), use

RUN adduser -D -g '' newuser

Consulte busybox adduser


3
Obrigado! Parece que addusera solução de alto nível é geralmente preferida ao uso de funções de baixo nível useradd.
Akhmed

adduser: unrecognized option: gecosIsso não parece funcionar no Alpine.
Weberc2

o que a senha --disabled faz e como podemos definir a senha para o usuário ao mesmo tempo no Dockerfile?
Hossein

72

Ubuntu

Tente as seguintes linhas em Dockerfile:

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

useraddopções (consulte man useradd:):

  • -r, --systemCrie uma conta do sistema. consulte: Implicações na criação de contas do sistema
  • -m, --create-homeCrie o diretório inicial do usuário.
  • -d, --home-dir HOME_DIRDiretório inicial da nova conta.
  • -s, --shell SHELLShell de login da nova conta.
  • -g, --gid GROUPNome ou ID do grupo principal.
  • -G, --groups GROUPSLista de grupos suplementares.
  • -u, --uid UIDEspecifique o ID do usuário. consulte: Entendendo como uid e gid funcionam em contêineres do Docker
  • -p, --password PASSWORDSenha criptografada da nova conta (por exemplo ubuntu).

Definindo a senha do usuário padrão

Para definir a senha do usuário, adicione -p "$(openssl passwd -1 ubuntu)"ao useraddcomando

Como alternativa, adicione as seguintes linhas ao seu Dockerfile:

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

A primeira instrução shell é garantir que a -o pipefailopção esteja ativada antes RUNcom um pipe nele. Leia mais: Hadolint: Conectando seu Dockerfile .


2
Por que o usuário estaria no grupo raiz? Não é o ponto de todo isso é ter um usuário não-root para fins de segurança
Novaterata

5
@Novaterata Dependendo do uso. rootO grupo não indica que eles têm acesso root, apenas têm mais acesso de leitura a alguns arquivos (como logs), o que é útil, mas depende do projeto.
21419 kenorb

Percebo que isso funciona, eu estou logado automaticamente como usuário, mas ainda estou gerando arquivos de propriedade do root. Eu até usei 'USER user', já que meu nome de usuário no grupo e usuário local é 'user'. Ainda gera arquivos de propriedade raiz. Há algo mais que eu deveria estar fazendo? Basicamente, estou criando um contêiner de docker que compila nossa base de código. Então ele verifica o código do svn, configura as variáveis ​​usando o bash source. Os comandos do bash podem fazer coisas como root, mesmo que nunca me perguntem a senha do root?
JoeManiaci 03/01

14

Adicionar usuário na janela de encaixe e executar seu aplicativo nesse usuário é uma prática muito boa do ponto de vista da segurança. Para fazer isso, eu recomendaria as etapas abaixo:

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

As etapas acima são um exemplo completo dos arquivos de projeto de cópia do NodeJS, criando um grupo e um usuário, atribuindo permissões ao usuário para a pasta do projeto, alternando para o usuário recém-criado e executando o aplicativo nesse usuário.


1
O addgroup falhou para mim, Etapa 11/15: EXECUTAR username do addgroup -S ---> Executando no db9fd22d469d As opções s são ambíguas (shell, sistema) adduser [--home DIR] [--shell SHELL] [--no-create -home] [--iduid ID] [--firstuid ID] [--lastuid ID] [--gecos GECOS] [--ingroup GROUP | --gid ID] [--disabled-password] [--disabled-login] [--encrypt-home] USUÁRIO Adicione um usuário normal
teoring

9

Você pode imitar o Dockerfile de código aberto, por exemplo:

Nó: node12-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

Eu acho que é uma boa maneira de seguir o código aberto.


3

Todo mundo tem seu favorito pessoal, e este é meu:

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

Referencia: man useradd

A RUNlinha adicionará o usuário e o grupo app:

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

Use um nome mais específico do que appse a imagem tiver que ser reutilizada como imagem de base. Como um aparte, inclua --shell /bin/bashse você realmente precisa.


Crédito parcial: resposta por Ryan M


1

Alternativamente, você pode fazer assim.

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

O primeiro comando cria um grupo chamado demo . O segundo comando cria um usuário demo e o adiciona ao grupo de demonstração criado anteriormente .

Flags significa:

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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.