Это простой инструмент, выращенный из того, что su
и sudo
имеют очень странное и часто раздражающее поведение TTY и сигнал. Они также несколько сложны для настройки и использования (особенно в случае sudo
), что обеспечивает большую экспрессив трубопровод ".
Ядро того, как работает gosu
, украдена непосредственно из того, как Docker/Libcontainer запускает приложение внутри контейнера (и на самом деле использует код обработки /etc/passwd
непосредственно из кодовой базы 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)
После того, как пользователь/группа обработана, мы переключаемся на этого пользователя, тогда мы exec
указанный процесс, а сам gosu
больше не участвует в жизненном цикле процесса. Это позволяет избежать всех проблем передачи сигнала и TTY, и приводит их в процесс, вызывая gosu
, и процесс, вызываемый gosu
, где они принадлежат.
root
вариант использования ядра ENTRYPOINT
gosu
Использование gosu
за пределами этого вполне может пострадать от уязвимостей, таких как CVE-2016-2779 (из которого пример использования Docker естественным образом защищает нас); См tianon/gosu#37
для некоторого обсуждения по этому вопросу.
Шаги высокого уровня:
gosu-$(dpkg --print-architecture | awk -F- '{ print $NF }')
как gosu
gosu-$(dpkg --print-architecture | awk -F- '{ print $NF }').asc
как gosu.asc
gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4
gpg --batch --verify gosu.asc gosu
chmod +x gosu
Для явных инструкций Dockerfile
см. В 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
Кроме того, из -за того, что gosu
использует собственный код Docker для обработки этого user:group
, он имеет точную паритет 1: 1 с собственным флагом --user
.
Если вам любопытно о краевых случаях, которые обрабатывает gosu
, см. Dockerfile.test-alpine
для «набора тестов» (и связанного сценария test.sh
, который завершает это для тестирования произвольных двоичных файлов).
(Обратите внимание, что sudo
имеет разные цели от этого проекта, и он не предназначен для замены sudo
; например, см. Этот ответ переполнения стека для краткого объяснения того, почему sudo
делает fork
+ exec
вместо Just exec
.)
chroot
С флагом --userspec
chroot
может обеспечить аналогичные преимущества/поведение:
$ 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
Доступно в новом util-linux
( >= 2.32.1-0.2
, в 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
В экосистеме Alpine Linux su-exec
представляет собой минимальный перепись gosu
в C, создающий гораздо меньший бинар и доступен в репозитории main
альпийского пакета. Однако, как и в версии 0.2, у него довольно серьезная ошибка анализатора, которая не была в релизе в течение многих лет (и какое поведение багги состоит в том, что опечатки приводят к запуску кода как неожиданно корень?).
Я не очень знаком с ними, но некоторые другие альтернативы, о которых я знаю, включают:
chpst
(часть runit
)