จะเพิ่มผู้ใช้ในคอนเทนเนอร์ Docker ได้อย่างไร?


285

ฉันมีตัวเทียบท่าที่มีกระบวนการบางอย่าง (uwsgi และขึ้นฉ่าย) ที่ทำงานอยู่ภายใน ฉันต้องการสร้างผู้ใช้คื่นฉ่ายและผู้ใช้ uwsgi สำหรับกระบวนการเหล่านี้รวมถึงกลุ่มผู้ปฏิบัติงานที่พวกเขาจะเป็นของทั้งคู่เพื่อกำหนดสิทธิ์

ฉันพยายามเพิ่มRUN adduser uwsgiและRUN adduser celeryการ Dockerfile ของฉัน แต่นี้จะก่อให้เกิดปัญหาตั้งแต่เหล่านี้คำสั่งพรอมต์สำหรับการป้อนข้อมูล (ผมเคยโพสต์ตอบจากการสร้างด้านล่าง)

วิธีที่ดีที่สุดในการเพิ่มผู้ใช้ลงในคอนเทนเนอร์ Docker คือการตั้งค่าการอนุญาตสำหรับพนักงานที่ทำงานในคอนเทนเนอร์

ภาพของฉันเทียบท่าที่ถูกสร้างขึ้นอย่างเป็นทางการจากฐาน Ubuntu14.04

นี่คือเอาต์พุตจาก Dockerfile เมื่อรันคำสั่ง 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] 

คำตอบ:


489

เคล็ดลับคือการใช้แทนเสื้อคลุมแบบโต้ตอบuseradd adduserฉันมักจะสร้างผู้ใช้ด้วย:

RUN useradd -ms /bin/bash newuser

ซึ่งสร้างโฮมไดเร็กทอรีสำหรับผู้ใช้และทำให้แน่ใจว่า bash เป็นเชลล์เริ่มต้น

จากนั้นคุณสามารถเพิ่ม:

USER newuser
WORKDIR /home/newuser

ไปที่ dockerfile ของคุณ ทุกคำสั่งหลังจากนั้นรวมถึงเซสชันแบบโต้ตอบจะถูกดำเนินการในฐานะผู้ใช้newuser:

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

คุณอาจต้องให้newuserสิทธิ์ในการใช้งานโปรแกรมที่คุณตั้งใจจะใช้งานก่อนที่จะเรียกใช้คำสั่ง

การใช้ผู้ใช้ที่ไม่มีสิทธิพิเศษภายในคอนเทนเนอร์เป็นความคิดที่ดีสำหรับเหตุผลด้านความปลอดภัย นอกจากนี้ยังมีไม่กี่ข้อบกพร่อง สิ่งสำคัญที่สุดคือคนที่ได้รับภาพจากภาพของคุณจะต้องเปลี่ยนกลับไปที่รูทก่อนที่พวกเขาจะสามารถดำเนินการคำสั่งด้วยสิทธิ์พิเศษของผู้ใช้


142
ฉันขอแนะนำให้ใช้ตัวเลือกชื่อเต็มใน Dockerfile เช่นเดียวกับในสคริปต์แทนที่จะเป็นตัวย่อ (มากกว่าที่จะใช้เมื่อใช้ IMO แบบโต้ตอบ) useradd --create-home --shell /bin/bashมีความเข้าใจ / อ่านง่ายสำหรับผู้ร่วมงาน
Baptiste Mathus

25
เพื่อที่จะตั้งรหัสผ่านที่คุณสามารถใช้ chpasswd ที่ชอบ:RUN echo 'newuser:newpassword' | chpasswd
iuridiniz

3
โปรดทราบว่าหากคุณกำลังสร้างผู้ใช้ใหม่ด้วย ID ผู้ใช้ขนาดใหญ่นักเทียบท่าอาจแฮงค์ / ขัดข้องเนื่องจากพยายามสร้างLastlogซึ่งเป็นไฟล์ขนาดใหญ่ หลีกเลี่ยงปัญหานี้ด้วยตัวเลือกในการ--no-log-init useradd
Davida

10
คำแนะนำที่ดี @iuridiniz! USER newuserอย่าลืมที่จะเรียกมันก่อน หากคุณยังต้องให้ผู้ใช้มีสิทธิ์ root adduser <username> sudoคุณยังสามารถรวม
Yamaneko

6
/bin/sh: useradd: not foundอัลไพน์ลินุกซ์
deathangel908

91

เพื่อหลีกเลี่ยงคำถามโต้ตอบโดยผู้ใช้คุณสามารถเรียกมันด้วยพารามิเตอร์เหล่านี้:

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

--gecosใช้พารามิเตอร์การตั้งค่าข้อมูลเพิ่มเติม ในกรณีนี้มันว่างเปล่า

สำหรับระบบที่มี busybox (เช่น Alpine) ให้ใช้

RUN adduser -D -g '' newuser

ดูเครื่องมือเพิ่มbusybox


3
ขอบคุณ! ดูเหมือนว่าการแก้ปัญหาในระดับสูงเป็นที่ต้องการโดยทั่วไปจะใช้ฟังก์ชั่นในระดับต่ำเช่นadduser useradd
akhmed

adduser: unrecognized option: gecosดูเหมือนจะไม่ได้ผลกับอัลไพน์
weberc2

--disabled-password ทำอะไรและเราจะตั้งรหัสผ่านให้กับผู้ใช้พร้อมกันใน Dockerfile ได้อย่างไร?
Hossein

72

อูบุนตู

ลองบรรทัดต่อไปนี้ในDockerfile:

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

useraddตัวเลือก (ดู:) man useradd:

การตั้งรหัสผ่านเริ่มต้นของผู้ใช้

ในการตั้งค่ารหัสผ่านผู้ใช้เพิ่ม-p "$(openssl passwd -1 ubuntu)"การuseraddคำสั่ง

หรือเพิ่มบรรทัดต่อไปนี้ในDockerfile:

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

คำสั่งเชลล์แรกคือเพื่อให้แน่ใจว่า-o pipefailเปิดใช้งานตัวเลือกก่อนหน้านี้RUNด้วยไพพ์ อ่านเพิ่มเติม: Hadolint: linting Dockerfile


2
ทำไมผู้ใช้ถึงอยู่ในกลุ่มรูท ไม่ใช่ประเด็นทั้งหมดของเรื่องนี้คือการมีผู้ใช้ที่ไม่ใช่ผู้ใช้รูทเพื่อความปลอดภัย
4322

5
@Novaterata ขึ้นอยู่กับการใช้งาน rootกลุ่มไม่ได้ระบุว่าพวกเขามีสิทธิ์เข้าถึงระดับรูท แต่พวกเขามีสิทธิ์เข้าถึงแบบอ่านไฟล์บางไฟล์มากขึ้น (เช่นบันทึก) ซึ่งมีประโยชน์ แต่ขึ้นอยู่กับโครงการ
kenorb

ฉันเห็นว่ามันใช้งานได้ฉันเข้าสู่ระบบโดยอัตโนมัติในฐานะผู้ใช้ แต่ฉันยังคงสร้างไฟล์โดย root ฉันเพิ่งใช้ 'ผู้ใช้ USER' เนื่องจากชื่อผู้ใช้ของฉันในผู้ใช้ท้องถิ่นและกลุ่มคือ 'ผู้ใช้' ยังคงสร้างไฟล์ที่เป็นเจ้าของรูท มีอะไรอีกบ้างที่ฉันควรทำ? ฉันทำพื้นภาชนะนักเทียบท่าที่รวบรวม codebase ของเรา ดังนั้นจึงตรวจสอบรหัสจาก svn ตั้งค่าตัวแปรโดยใช้ bash source คำสั่ง bash สามารถทำสิ่งต่าง ๆ ได้เหมือนรูทแม้ว่าฉันจะไม่ถามรหัสผ่านรูทหรือไม่?
JoeManiaci

14

การเพิ่มผู้ใช้ในนักเทียบท่าและเรียกใช้แอปของคุณภายใต้ผู้ใช้นั้นเป็นวิธีปฏิบัติที่ดีมากสำหรับมุมมองความปลอดภัย ในการทำเช่นนั้นฉันขอแนะนำขั้นตอนด้านล่าง:

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

ขั้นตอนข้างต้นเป็นตัวอย่างเต็มรูปแบบของการคัดลอกไฟล์โครงการ NodeJS สร้างกลุ่มผู้ใช้และผู้ใช้กำหนดสิทธิ์ให้กับผู้ใช้สำหรับโฟลเดอร์โครงการสลับไปยังผู้ใช้ที่สร้างขึ้นใหม่และเรียกใช้แอปภายใต้ผู้ใช้นั้น


1
addgroup ล้มเหลวสำหรับฉันขั้นตอนที่ 11/15: RUN addgroup -S ชื่อผู้ใช้ ---> การทำงานใน db9fd22d469d ตัวเลือก s ไม่ชัดเจน (เชลล์, ระบบ) adduser [- home DIR] [- เชลล์ SHELL] [- ไม่สร้าง -home] [--uid ID] [--firstuid ID] [--lastuid ID] [--gecos GECOS] [- กลุ่ม GROUP | --gid ID] [- ปิดการใช้งานรหัสผ่าน] [- ปิดการใช้งานเข้าสู่ระบบ] [- เข้ารหัสลับบ้าน] USER เพิ่มผู้ใช้ปกติ
teoring

9

คุณสามารถเลียนแบบโอเพ่นซอร์ส Dockerfile ตัวอย่างเช่น:

โหนด: 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

ฉันคิดว่ามันเป็นวิธีที่ดีในการติดตามโอเพ่นซอร์ส


3

ทุกคนมีความชื่นชอบส่วนตัวและนี่คือของฉัน:

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

ข้อมูลอ้างอิง: man useradd

RUNสายจะเพิ่มผู้ใช้และกลุ่มapp:

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

ใช้ชื่อที่เฉพาะเจาะจงยิ่งกว่าappถ้ารูปภาพนั้นจะถูกนำมาใช้ซ้ำเป็นภาพฐาน นอกเหนือจากนี้--shell /bin/bashถ้าคุณต้องการ


เครดิตบางส่วน: คำตอบโดยไรอัน M


1

หรือคุณสามารถทำเช่นนี้

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

คำสั่งแรกสร้างกลุ่มที่เรียกว่าการสาธิต คำสั่งที่สองสร้างผู้ใช้สาธิตและเพิ่มเขาในกลุ่มตัวอย่างที่สร้างขึ้นก่อนหน้านี้

ธงย่อมาจาก:

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.