هذه أداة بسيطة نمت من الحقيقة البسيطة التي تفيد بأن su
و sudo
لهما سلوك غريب للغاية ومزعج في كثير من الأحيان ويعزز الإشارة. إنها أيضًا معقدة إلى حد ما لإعداد واستخدام (خاصة في حالة 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
، حيث ينتمون.
تتمثل حالة الاستخدام الأساسية لـ gosu
في التنحي من root
إلى مستخدم غير محدد أثناء بدء تشغيل الحاوية (على وجه التحديد في ENTRYPOINT
، عادة).
يمكن أن تعاني استخدامات 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
as 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 مع علامة Docker الخاصة --user
.
إذا كنت مهتمًا بحالات الحافة التي يتعامل معها gosu
، راجع Dockerfile.test-alpine
لـ "جناح الاختبار" (ونصي test.sh
المرتبط به الذي يختتم هذا لاختبار الثنائيات التعسفية).
(لاحظ أن sudo
لديه أهداف مختلفة من هذا المشروع ، وليس المقصود منه أن يكون بديلاً sudo
؛ على سبيل المثال ، راجع إجابة الفائض هذه للحصول على شرح قصير عن سبب قيام sudo
fork
+ exec
بدلاً من 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 Ecosystem ، su-exec
هو الحد الأدنى من إعادة كتابة gosu
في C ، مما يجعله ثنائيًا أصغر بكثير ، وهو متوفر في مستودع حزمة جبال الألب main
. ومع ذلك ، في الإصدار 0.2 ، يحتوي على خطأ محلل كبير جدًا لم يكن في إصدار لسنوات عديدة (وأي سلوك عربات التي تجرها الدواب هو أن الأخطاء المطبعية تؤدي إلى تشغيل رمز بشكل غير متوقع؟).
أنا لست على دراية بهم بشكل رهيب ، لكن بعض البدائل الأخرى التي أعرفها تتضمن:
chpst
(جزء من runit
)