Làm cách nào để thêm người dùng vào Docker container?


285

Tôi có một container docker với một số quy trình (uwsgi và cần tây) chạy bên trong. Tôi muốn tạo một người dùng cần tây và một người dùng uwsgi cho các quy trình này cũng như một nhóm công nhân mà cả hai sẽ thuộc về, để gán quyền.

Tôi đã thử thêm RUN adduser uwsgiRUN adduser celeryvào Dockerfile của mình, nhưng điều này gây ra sự cố, vì các lệnh này nhắc nhở cho đầu vào (Tôi đã đăng các phản hồi từ bản dựng bên dưới).

Cách tốt nhất để thêm người dùng vào bộ chứa Docker để đặt quyền cho công nhân chạy trong bộ chứa là gì?

Hình ảnh Docker của tôi được xây dựng từ cơ sở Ubuntu14.04 chính thức.

Đây là đầu ra từ Dockerfile khi các lệnh adduser được chạy:

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] 

Câu trả lời:


489

Bí quyết là sử dụng useraddthay vì trình bao bọc tương tác của nó adduser. Tôi thường tạo người dùng bằng:

RUN useradd -ms /bin/bash newuser

tạo thư mục chính cho người dùng và đảm bảo rằng bash là shell mặc định.

Sau đó bạn có thể thêm:

USER newuser
WORKDIR /home/newuser

đến dockerfile của bạn. Mọi lệnh sau đó cũng như các phiên tương tác sẽ được thực thi với tư cách là người dùng newuser:

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

Bạn có thể phải cấp newuserquyền để thực thi các chương trình bạn định chạy trước khi gọi lệnh người dùng.

Sử dụng người dùng không có đặc quyền trong các container là một ý tưởng tốt vì lý do bảo mật. Nó cũng có một vài nhược điểm. Quan trọng nhất, mọi người lấy hình ảnh từ hình ảnh của bạn sẽ phải chuyển về root trước khi họ có thể thực thi các lệnh với đặc quyền siêu người dùng.


141
Tôi khuyên bạn nên sử dụng các tùy chọn tên đầy đủ trong Dockerfile, như trong tập lệnh, thay vì các tùy chọn ngắn (sẽ được sử dụng nhiều hơn khi được sử dụng IMO tương tác). useradd --create-home --shell /bin/bashdễ hiểu hơn / dễ đọc hơn cho đồng nghiệp.
Baptiste Mathus 22/03/2016

25
Để đặt mật khẩu, bạn có thể sử dụng chpasswd như:RUN echo 'newuser:newpassword' | chpasswd
iuridiniz 21/07/2016

3
Lưu ý rằng nếu bạn đang tạo một người dùng mới có ID người dùng lớn, docker có thể bị treo / sập khi nó cố gắng tạo Lastlog - một tệp thưa thớt lớn. Tránh điều này với --no-log-inittùy chọn để useradd.
davidA

10
Mẹo hay, @iuridiniz! Đừng quên gọi nó trước USER newuser. Nếu bạn cũng cần người dùng có quyền root, bạn cũng có thể bao gồm adduser <username> sudo.
Yamaneko

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

91

Để tránh các câu hỏi tương tác của người dùng, bạn có thể gọi nó với các tham số sau:

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

Các --gecostham số được sử dụng để thiết lập các thông tin bổ sung. Trong trường hợp này, nó chỉ là trống rỗng.

Trên các hệ thống có busybox (như Alpine), hãy sử dụng

RUN adduser -D -g '' newuser

Xem trình bổ sung busybox


3
Cảm ơn! Có vẻ như addusergiải pháp cấp cao thường được ưa thích hơn là sử dụng các hàm cấp thấp như thế nào useradd.
akhmed

adduser: unrecognized option: gecosĐiều này dường như không hoạt động trên Alps.
weberc2

--disables-password làm gì và làm cách nào chúng ta có thể đặt mật khẩu cho người dùng cùng lúc trong Dockerfile?
Hossein

72

Ubuntu

Hãy thử các dòng sau trong Dockerfile:

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

useraddtùy chọn (xem man useradd:)

  • -r, --systemTạo một tài khoản hệ thống. xem: Hàm ý tạo tài khoản hệ thống
  • -m, --create-homeTạo thư mục nhà của người dùng.
  • -d, Thư mục --home-dir HOME_DIRchính của tài khoản mới.
  • -s, --shell SHELLĐăng nhập vỏ của tài khoản mới.
  • -g, --gid GROUPTên hoặc ID của nhóm chính.
  • -G, --groups GROUPSDanh sách các nhóm bổ sung.
  • -u, --uid UIDChỉ định ID người dùng. xem: Hiểu cách uid và gid hoạt động trong các container Docker
  • -p, --password PASSWORDMật khẩu được mã hóa của tài khoản mới (ví dụ ubuntu).

Đặt mật khẩu người dùng mặc định

Để đặt mật khẩu người dùng, thêm -p "$(openssl passwd -1 ubuntu)"vào useraddlệnh.

Hoặc thêm các dòng sau vào Dockerfile:

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

Hướng dẫn shell đầu tiên là đảm bảo rằng -o pipefailtùy chọn được bật trước khi RUNcó một đường ống trong đó. Đọc thêm: Hadolint: Linting Dockerfile của bạn .


2
Tại sao người dùng sẽ ở trong nhóm gốc? Không phải toàn bộ vấn đề này là có một người dùng không root cho mục đích bảo mật
Novaterata

5
@Novaterata Tùy thuộc vào việc sử dụng. rootnhóm không cho biết họ có quyền truy cập root, chỉ là họ có quyền truy cập đọc nhiều hơn vào một số tệp (chẳng hạn như nhật ký), điều này rất hữu ích, nhưng nó phụ thuộc vào dự án.
kenorb

Tôi có thể thấy rằng điều này hoạt động, tôi tự động đăng nhập với tư cách người dùng, nhưng tôi vẫn đang tạo các tệp thuộc sở hữu của root. Tôi thậm chí chỉ sử dụng 'người dùng USER' vì tên người dùng của tôi trên nhóm và người dùng cục bộ là 'người dùng'. Vẫn tạo tập tin sở hữu root. Có điều gì khác tôi nên làm không? Về cơ bản, tôi đang tạo ra một container docker biên dịch codebase của chúng tôi. Vì vậy, nó kiểm tra mã từ svn, thiết lập các biến bằng cách sử dụng nguồn bash. Các lệnh bash có thể thực hiện mọi thứ với quyền root ngay cả khi tôi không bao giờ được hỏi mật khẩu gốc không?
JoeManiaci

14

Thêm người dùng vào docker và chạy ứng dụng của bạn dưới người dùng đó là cách thực hành rất tốt cho quan điểm bảo mật. Để làm điều đó tôi muốn giới thiệu các bước dưới đây:

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

Các bước trên là một ví dụ đầy đủ về sao chép các tệp dự án NodeJS, tạo nhóm người dùng và người dùng, gán quyền cho người dùng cho thư mục dự án, chuyển sang người dùng mới được tạo và chạy ứng dụng theo người dùng đó.


1
addgroup không thành công với tôi, Bước 11/15: RUN addgroup -S username ---> Chạy trong db9fd22d469d Tùy chọn s không rõ ràng (shell, system) adduser [--home DIR] [--shell SHELL] [--no-created -home] [--uid ID] [--firstuid ID] [--lastuid ID] [--gecos GECOS] [- nhóm NHÓM | ID --gid] [--disabled mật khẩu] [--disabled đăng nhập] [--encrypt nhà] USER Thêm một người dùng bình thường
teoring

9

Bạn có thể bắt chước Dockerfile mã nguồn mở, ví dụ:

Nút: nút12-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

Tôi nghĩ rằng đó là một cách tốt để theo dõi nguồn mở.


3

Mọi người đều có sở thích cá nhân của họ, và đây là của tôi:

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

Tham khảo: người dùng

Các RUNdòng sẽ thêm người dùng và nhóm app:

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

Sử dụng tên cụ thể hơn appnếu hình ảnh được sử dụng lại làm hình ảnh cơ sở. Như một bên, bao gồm --shell /bin/bashnếu bạn thực sự cần.


Tín dụng một phần: câu trả lời của Ryan M


1

Hoặc bạn có thể làm như thế này.

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

Lệnh đầu tiên tạo nhóm được gọi là demo . Lệnh thứ hai tạo người dùng demo và thêm anh ta vào bản demo được tạo trước đó nhóm .

Cờ là viết tắt của:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.