Jak dodać użytkowników do kontenera Docker?

285

Mam wewnątrz kontener dokera z niektórymi procesami (uwsgi i seler). Chcę utworzyć użytkownika selera i użytkownika uwsgi dla tych procesów, a także grupę roboczą, do której oboje będą należeć, w celu przypisania uprawnień.

Próbowałem dodać RUN adduser uwsgii RUN adduser celerydo mojego pliku Docker, ale powoduje to problemy, ponieważ te polecenia proszą o podanie danych (opublikowałem odpowiedzi z kompilacji poniżej).

Jaki jest najlepszy sposób dodawania użytkowników do kontenera Docker, aby ustawić uprawnienia dla pracowników działających w kontenerze?

Mój obraz Dockera jest zbudowany z oficjalnej bazy Ubuntu14.04.

Oto dane wyjściowe z pliku Docker po uruchomieniu poleceń 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] 
rfj001
źródło

Odpowiedzi:

489

Sztuką jest użycie useraddzamiast interaktywnego opakowania adduser. Zwykle tworzę użytkowników za pomocą:

RUN useradd -ms /bin/bash newuser

który tworzy katalog domowy dla użytkownika i zapewnia, że ​​bash jest domyślną powłoką.

Następnie możesz dodać:

USER newuser
WORKDIR /home/newuser

do twojego pliku dokującego. Każde kolejne polecenie, a także sesje interaktywne będą wykonywane jako użytkownik newuser:

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

Być może będziesz musiał udzielić newuseruprawnień do uruchamiania programów, które zamierzasz uruchomić przed wywołaniem polecenia użytkownika.

Używanie nieuprzywilejowanych użytkowników w kontenerach jest dobrym pomysłem ze względów bezpieczeństwa. Ma również kilka wad. Co najważniejsze, osoby pobierające obrazy z twojego obrazu będą musiały przełączyć się z powrotem na root, zanim będą mogły wykonywać polecenia z uprawnieniami administratora.

Paul Staab
źródło
142
Polecam użycie opcji pełnej nazwy w Dockerfile, jak w skrypcie, zamiast krótkich (więcej do wykorzystania, gdy używa się interaktywnie IMO). useradd --create-home --shell /bin/bashjest bardziej zrozumiały / czytelny dla współpracowników.
Baptiste Mathus
25
Aby ustawić hasło, możesz użyć chpasswd jak:RUN echo 'newuser:newpassword' | chpasswd
iuridiniz
3
Pamiętaj, że jeśli tworzysz nowego użytkownika z dużym identyfikatorem użytkownika, okno dokowane może zawiesić się / zawiesić, gdy próbuje utworzyć plik lastlog - ogromny, rzadki plik. Unikaj tego dzięki --no-log-initopcji useradd.
davidA
10
Dobra wskazówka, @iuridiniz! Nie zapomnij zadzwonić wcześniej USER newuser. Jeśli potrzebujesz również uprawnień użytkownika root, możesz również dołączyć adduser <username> sudo.
Yamaneko
6
/bin/sh: useradd: not foundalpine linux
deathangel908
91

Aby uniknąć interaktywnych pytań według adduser, możesz wywołać je za pomocą następujących parametrów:

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

Ten --gecosparametr służy do ustawiania dodatkowych informacji. W tym przypadku jest po prostu pusty.

W systemach z busybox (takich jak Alpine) użyj

RUN adduser -D -g '' newuser

Zobacz adduser busybox

Raffael
źródło
3
Dzięki! Wygląda na to, że adduserrozwiązanie wysokiego poziomu jest ogólnie preferowane niż korzystanie z funkcji niskiego poziomu, takich jak useradd.
akhmed
adduser: unrecognized option: gecosTo nie wydaje się działać na Alpine.
weberc2
co robi --disabled-password i jak możemy ustawić hasło dla użytkownika w tym samym czasie w Dockerfile?
Hossein
72

Ubuntu

Wypróbuj następujące linie w Dockerfile:

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

useraddopcje (patrz man useradd:):

Ustawienie domyślnego hasła użytkownika

Aby ustawić hasło użytkownika, dodaj -p "$(openssl passwd -1 ubuntu)"do useraddpolecenia.

Możesz też dodać następujące wiersze do Dockerfile:

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

Pierwszą instrukcją powłoki jest upewnienie się, że -o pipefailopcja jest wcześniej włączona RUNz rurką w niej. Czytaj więcej: Hadolint: Linting your Dockerfile .

kenorb
źródło
2
Dlaczego użytkownik miałby być w grupie głównej? Nie o to chodzi w tym, żeby mieć użytkownika innego niż root ze względów bezpieczeństwa
Novaterata
5
@Novaterata W zależności od zastosowania. rootgrupa nie oznacza, że ​​mają dostęp do katalogu głównego, po prostu mają większy dostęp do odczytu niektórych plików (takich jak logi), co jest przydatne, ale zależy to od projektu.
kenorb
Widzę, że to działa, jestem automatycznie zalogowany jako użytkownik, ale nadal generuję pliki należące do roota. Użyłem nawet „użytkownika UŻYTKOWNIKA”, ponieważ moją nazwą użytkownika lokalnego i grupy jest „użytkownik”. Nadal generuje pliki należące do roota. Czy jest coś jeszcze, co powinienem robić? Zasadniczo tworzę kontener dokerów, który kompiluje naszą bazę kodów. Sprawdza więc kod z svn, konfiguruje zmienne przy użyciu źródła bash. Czy polecenia bash mogą działać jako root, nawet jeśli nigdy nie będę proszony o hasło roota?
JoeManiaci
14

Dodawanie użytkownika w oknie dokowanym i uruchamianie aplikacji pod tym użytkownikiem jest bardzo dobrą praktyką z punktu widzenia bezpieczeństwa. Aby to zrobić, polecam poniższe kroki:

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

Powyższe kroki to pełny przykład kopiowania plików projektu NodeJS, tworzenia grupy użytkowników i użytkownika, przypisywania uprawnień do folderu projektu, przełączania do nowo utworzonego użytkownika i uruchamiania aplikacji pod tym użytkownikiem.

S.Mishra
źródło
1
addgroup dla mnie nie powiodło się, Krok 11/15: URUCHOM addgroup -S nazwa użytkownika ---> Uruchomiony w db9fd22d469d Opcja s jest niejednoznaczna (powłoka, system) 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] UŻYTKOWNIK Dodaj zwykłego użytkownika
naucza
9

Możesz naśladować plik Dockerfile typu open source, na przykład:

Węzeł: 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

Myślę, że to dobry sposób na podążanie za open source.

Ryan Miao
źródło
3

Każdy ma swojego ulubionego, a to jest moje:

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

Odniesienie: man useradd

RUNLinia doda użytkownika i grupę app:

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

Użyj bardziej szczegółowej nazwy, niż appjeśli obraz ma zostać ponownie użyty jako obraz podstawowy. Na marginesie, uwzględnij, --shell /bin/bashjeśli naprawdę potrzebujesz.


Częściowe uznanie: odpowiedź Ryana M.

Acumenus
źródło
1

Możesz to zrobić w ten sposób.

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

Pierwsze polecenie tworzy grupę o nazwie demo . Drugie polecenie tworzy użytkownika demonstracyjnego i dodaje go do wcześniej utworzonej grupy demonstracyjnej .

Flagi oznaczają:

-G Group
-D Don't assign password
-H Don't create home directory
Łukasz Dynowski
źródło
0

Dodaj tę linię do pliku Docker (możesz w ten sposób uruchomić dowolne polecenie linux)

RUN useradd -ms /bin/bash yourNewUserName
K - Toksyczność w SO rośnie.
źródło