Ini adalah alat sederhana yang tumbuh dari fakta sederhana bahwa su
dan sudo
memiliki perilaku tty dan penahan sinyal yang sangat aneh dan sering menjengkelkan. Mereka juga agak rumit untuk diatur dan digunakan (terutama dalam kasus sudo
), yang memungkinkan banyak ekspresif, tetapi jatuh datar jika semua yang Anda butuhkan adalah "jalankan aplikasi spesifik ini sebagai pengguna spesifik ini dan keluar dari pipa ".
Inti dari cara kerja gosu
dicuri langsung dari bagaimana Docker/libcontainer sendiri memulai aplikasi di dalam wadah (dan pada kenyataannya, menggunakan kode pemrosesan /etc/passwd
langsung dari basis kode libcontainer).
$ gosu
Usage: ./gosu user-spec command [args]
eg: ./gosu tianon bash
./gosu nobody:root bash -c 'whoami && id'
./gosu 1000:1 id
./gosu version: 1.1 (go1.3.1 on linux/amd64; gc)
Setelah pengguna/grup diproses, kami beralih ke pengguna itu, maka kami exec
proses yang ditentukan dan gosu
sendiri tidak lagi tinggal atau terlibat dalam siklus hidup proses sama sekali. Ini menghindari semua masalah lewat sinyal dan TTY, dan menyertai mereka ke proses yang memohon gosu
dan proses yang dipanggil oleh gosu
, di mana mereka berada.
Kasing penggunaan inti untuk gosu
adalah untuk mundur dari root
ke pengguna yang tidak istimewa selama startup kontainer (khususnya di ENTRYPOINT
, biasanya).
Penggunaan gosu
di luar yang bisa sangat menderita kerentanan seperti CVE-2016-2779 (dari mana case penggunaan Docker secara alami melindungi kita); Lihat tianon/gosu#37
untuk beberapa diskusi sekitar saat ini.
Langkah-langkah tingkat tinggi:
gosu-$(dpkg --print-architecture | awk -F- '{ print $NF }')
sebagai gosu
gosu-$(dpkg --print-architecture | awk -F- '{ print $NF }').asc
as gosu.asc
gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4
gpg --batch --verify gosu.asc gosu
chmod +x gosu
Untuk instruksi Dockerfile
eksplisit, lihat INSTALL.md
.
$ docker run -it --rm ubuntu:trusty su -c ' exec ps aux '
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 46636 2688 ? Ss+ 02:22 0:00 su -c exec ps a
root 6 0.0 0.0 15576 2220 ? Rs 02:22 0:00 ps aux
$ docker run -it --rm ubuntu:trusty sudo ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 3.0 0.0 46020 3144 ? Ss+ 02:22 0:00 sudo ps aux
root 7 0.0 0.0 15576 2172 ? R+ 02:22 0:00 ps aux
$ docker run -it --rm -v $PWD /gosu-amd64:/usr/local/bin/gosu:ro ubuntu:trusty gosu root ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 7140 768 ? Rs+ 02:22 0:00 ps aux
Selain itu, karena fakta bahwa gosu
menggunakan kode Docker sendiri untuk memproses user:group
, memiliki paritas 1: 1 yang tepat dengan bendera Docker sendiri --user
.
Jika Anda ingin tahu tentang kasus tepi yang ditangani gosu
, lihat Dockerfile.test-alpine
untuk "Test Suite" (dan skrip test.sh
terkait yang membungkus ini untuk menguji biner sewenang-wenang).
sudo
sudo
sudo
fork
exec
exec
chroot
Dengan bendera --userspec
, chroot
dapat memberikan manfaat/perilaku yang serupa:
$ docker run -it --rm ubuntu:trusty chroot --userspec=nobody / ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
nobody 1 5.0 0.0 7136 756 ? Rs+ 17:04 0:00 ps aux
setpriv
Tersedia di util-linux
yang lebih baru ( >= 2.32.1-0.2
, di Debian; https://manpages.debian.org/buster/util-linux/setpriv.1.en.html):
$ docker run -it --rm buildpack-deps:buster-scm setpriv --reuid=nobody --regid=nogroup --init-groups ps faux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
nobody 1 5.0 0.0 9592 1252 pts/0 RNs+ 23:21 0:00 ps faux
su-exec
Dalam ekosistem Alpine Linux, su-exec
adalah tulisan ulang minimal gosu
di C, membuat biner yang jauh lebih kecil, dan tersedia di repositori paket alpine main
. Namun, pada versi 0.2 ia memiliki bug parser yang cukup parah yang belum dirilis selama bertahun -tahun (dan perilaku kereta mana yang mengarah pada kode menjalankan sebagai root secara tidak terduga?).
Saya tidak terlalu terbiasa dengan mereka, tetapi beberapa alternatif lain yang saya ketahui termasuk:
chpst
(bagian dari runit
)