これは、 su
とsudo
非常に奇妙で迷惑なttyと信号を強化する行動を持っているという単純な事実から成長した単純なツールです。また、セットアップと使用(特にsudo
の場合)を使用するのがやや複雑です。これにより、多くの表現力が可能になりますが、必要なのは「この特定のアプリケーションをこの特定のユーザーとして実行し、パイプライン」。
gosu
仕組みの中核は、Docker/LibContainer自体がコンテナ内でアプリケーションを開始する方法から直接盗まれます(実際、LibContainerのコードベースから/etc/passwd
処理コードを直接使用しています)。
$ 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
によって呼び出されるプロセスにパントします。
gosu
のコアユースケースは、コンテナの起動中に(特にENTRYPOINT
で、通常)、 root
から非適切なユーザーに辞任することです。
それを超えた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
これらのuser:group
しているため、Docker独自の--user
フラグと正確に1:1パリティがあります。
gosu
が処理するエッジケースに興味がある場合は、 Dockerfile.test-alpine
for "test suite"(および任意のバイナリをテストするためにこれをラップする関連test.sh
スクリプト)を参照してください。
( sudo
このプロジェクトとは異なる目標があり、 sudo
代替品であることを意図していないことに注意してください。たとえば、 sudo
exec
代わりにfork
+ 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
newer 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
Cのgosu
の最小限の書き直しであり、はるかに小さなバイナリを作成し、 main
Alpineパッケージリポジトリで利用できます。ただし、バージョン0.2の時点では、長年にわたってリリースされていない非常に深刻なパーサーバグがあります(そして、タイプミスは予期せずにコードを実行することにつながるバグの動作は?)。
私はそれらにひどく馴染みがありませんが、私が知っている他のいくつかの選択肢は次のとおりです。
chpst
( runit
の一部)