Bagaimana cara menambahkan pengguna ke wadah Docker?


286

Saya memiliki wadah buruh pelabuhan dengan beberapa proses (uwsgi dan seledri) berjalan di dalam. Saya ingin membuat pengguna seledri dan pengguna uwsgi untuk proses-proses ini dan juga kelompok pekerja yang akan menjadi bagian keduanya, untuk menetapkan izin.

Saya mencoba menambahkan RUN adduser uwsgidan RUN adduser celeryke Dockerfile saya, tetapi ini menyebabkan masalah, karena perintah ini meminta input (saya sudah memposting tanggapan dari build di bawah).

Apa cara terbaik untuk menambahkan pengguna ke wadah Docker untuk mengatur izin bagi pekerja yang menjalankan dalam wadah?

Gambar Docker saya dibuat dari basis Ubuntu14.04 resmi.

Ini adalah output dari Dockerfile ketika perintah adduser dijalankan:

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] 

Jawaban:


489

Caranya adalah dengan menggunakan useraddalih-alih pembungkus interaktifnya adduser. Saya biasanya membuat pengguna dengan:

RUN useradd -ms /bin/bash newuser

yang membuat direktori home untuk pengguna dan memastikan bahwa bash adalah shell default.

Anda kemudian dapat menambahkan:

USER newuser
WORKDIR /home/newuser

ke dockerfile Anda. Setiap perintah sesudahnya serta sesi interaktif akan dieksekusi sebagai pengguna newuser:

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

Anda mungkin harus memberikan newuserizin untuk menjalankan program yang ingin Anda jalankan sebelum menjalankan perintah pengguna.

Menggunakan pengguna yang tidak memiliki hak istimewa di dalam wadah adalah ide bagus untuk alasan keamanan. Ini juga memiliki beberapa kekurangan. Yang paling penting, orang yang memperoleh gambar dari gambar Anda harus beralih kembali ke root sebelum mereka dapat menjalankan perintah dengan hak superuser.


143
Saya akan merekomendasikan menggunakan opsi nama lengkap di Dockerfile, seperti dalam skrip, bukan yang pendek (lebih banyak digunakan saat digunakan secara interaktif IMO). useradd --create-home --shell /bin/bashlebih mudah dimengerti / dibaca untuk rekan kerja.
Baptiste Mathus

25
Untuk mengatur kata sandi, Anda dapat menggunakan chpasswd seperti:RUN echo 'newuser:newpassword' | chpasswd
iuridiniz

3
Perhatikan bahwa jika Anda membuat pengguna baru dengan ID pengguna besar, buruh pelabuhan dapat hang / crash saat mencoba membuat lastlog - file besar jarang. Hindari ini dengan --no-log-initopsi untuk useradd.
davidA

10
Tip yang bagus, @iuridiniz! Jangan lupa untuk menyebutnya sebelumnya USER newuser. Jika Anda juga membutuhkan pengguna untuk memiliki hak akses root, Anda juga bisa memasukkan adduser <username> sudo.
Yamaneko

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

92

Untuk menghindari pertanyaan interaktif dengan adduser, Anda dapat menyebutnya dengan parameter berikut:

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

The --gecosparameter digunakan untuk mengatur informasi tambahan. Dalam hal ini hanya kosong.

Pada sistem dengan busybox (seperti Alpine), gunakan

RUN adduser -D -g '' newuser

Lihat adduser busybox


3
Terima kasih! Sepertinya addusersolusi tingkat tinggi umumnya lebih disukai daripada menggunakan fungsi tingkat rendah seperti useradd.
akhmed

adduser: unrecognized option: gecosIni sepertinya tidak berhasil di Alpine.
weberc2

apa yang dilakukan --disabled-password lakukan dan bagaimana kita dapat mengatur kata sandi kepada pengguna pada saat yang sama di Dockerfile?
Hossein

72

Ubuntu

Coba baris berikut di Dockerfile:

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

useraddopsi (lihat man useradd:):

  • -r, --systemBuat akun sistem. lihat: Implikasi membuat akun sistem
  • -m, --create-homeBuat direktori home pengguna.
  • -d, --home-dir HOME_DIRDirektori rumah dari akun baru.
  • -s, --shell SHELLLogin shell dari akun baru.
  • -g, --gid GROUPNama atau ID grup utama.
  • -G, --groups GROUPSDaftar kelompok tambahan.
  • -u, --uid UIDTentukan ID pengguna. lihat: Memahami bagaimana uid dan gid bekerja dalam wadah Docker
  • -p, --password PASSWORDKata sandi terenkripsi dari akun baru (misalnya ubuntu).

Pengaturan kata sandi pengguna default

Untuk mengatur kata sandi pengguna, tambahkan -p "$(openssl passwd -1 ubuntu)"ke useraddperintah.

Atau tambahkan baris berikut ke Anda Dockerfile:

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

Instruksi shell pertama adalah untuk memastikan bahwa -o pipefailopsi diaktifkan sebelum RUNdengan pipa di dalamnya. Baca selengkapnya: Hadolint: Linting Dockerfile Anda .


2
Mengapa pengguna berada di grup root? Bukankah intinya adalah memiliki pengguna non-root untuk tujuan keamanan
Novaterata

5
@Novaterata Tergantung penggunaannya. rootgrup tidak mengindikasikan mereka telah mengakses root, hanya saja mereka lebih banyak membaca akses ke beberapa file (seperti log), yang berguna, tetapi itu tergantung pada proyek.
kenorb

Saya dapat melihat bahwa ini berfungsi, saya secara otomatis masuk sebagai pengguna, tetapi saya masih menghasilkan file yang dimiliki oleh root. Saya bahkan baru saja menggunakan 'pengguna USER' karena nama pengguna saya pada pengguna lokal dan grup adalah 'pengguna'. Masih menghasilkan file yang dimiliki root. Apakah ada hal lain yang harus saya lakukan? Saya pada dasarnya membuat wadah buruh pelabuhan yang menyusun basis kode kami. Jadi memeriksa kode dari svn, mengatur variabel menggunakan sumber bash. Bisakah perintah bash melakukan hal-hal sebagai root bahkan jika saya tidak pernah meminta kata sandi root?
JoeManiaci

14

Menambahkan pengguna di buruh pelabuhan dan menjalankan aplikasi Anda di bawah pengguna itu adalah praktik yang sangat baik untuk sudut pandang keamanan. Untuk melakukan itu saya akan merekomendasikan langkah-langkah di bawah ini:

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

Langkah-langkah di atas adalah contoh lengkap dari menyalin file proyek NodeJS, membuat grup pengguna dan pengguna, memberikan izin kepada pengguna untuk folder proyek, beralih ke pengguna yang baru dibuat dan menjalankan aplikasi di bawah pengguna itu.


1
addgroup gagal untuk saya, Langkah 11/15: Jalankan addgroup -S username ---> Berjalan di db9fd22d469d Opsi s adalah penambah ambigu (shell, sistem) [- home DIR] [--shell SHELL] [--no-create -rumah] [- ID cairan] [- ID cairan pertama] [- ID cairan] [- gecos GECOS] [--kelompok GRUP | --gid ID] [--disabled-password] [--disabled-login] [--encrypt-home] PENGGUNA Tambahkan pengguna normal
membuat

9

Anda dapat meniru open source Dockerfile, misalnya:

Node: 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

Saya pikir ini cara yang baik untuk mengikuti open source.


3

Setiap orang memiliki favorit pribadi mereka, dan ini milik saya:

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

Referensi: man useradd

The RUNline akan menambahkan user dan group app:

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

Gunakan nama yang lebih spesifik daripada appjika gambar tersebut akan digunakan kembali sebagai gambar dasar. Sebagai tambahan, sertakan --shell /bin/bashjika Anda benar-benar membutuhkannya.


Penghargaan parsial: dijawab oleh Ryan M


1

Atau Anda dapat melakukannya seperti ini.

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

Perintah pertama membuat grup bernama demo . Perintah kedua membuat pengguna demo dan menambahkannya ke grup demo yang dibuat sebelumnya .

Bendera adalah singkatan:

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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.