นี่เป็นเครื่องมือง่ายๆที่ปลูกออกมาจากความจริงง่ายๆที่ su
และ sudo
มีพฤติกรรม TTY ที่แปลกและน่ารำคาญและมักจะน่ารำคาญและพฤติกรรมการส่งสัญญาณ พวกเขายังค่อนข้างซับซ้อนในการติดตั้งและใช้งาน (โดยเฉพาะในกรณีของ sudo
) ซึ่งช่วยให้การแสดงออกอย่างมาก แต่ก็แบนถ้าคุณต้องการคือ "เรียกใช้แอปพลิเคชันเฉพาะนี้เป็นผู้ใช้เฉพาะนี้และออกจาก ท่อ "
แกนกลางของวิธีการทำงาน gosu
ถูกขโมยโดยตรงจากวิธีที่ Docker/Libcontainer เริ่มต้นแอปพลิเคชันภายในคอนเทนเนอร์ (และในความเป็นจริงคือการใช้รหัสการประมวลผล /etc/passwd
โดยตรงจาก codebase ของ 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 และ punts พวกเขาไปยังกระบวนการเรียกใช้ gosu
และกระบวนการที่ถูกเรียกโดย gosu
ที่พวกเขาอยู่
กรณีการใช้งานหลักสำหรับ gosu
คือการก้าว ลง จาก root
ไปยังผู้ใช้ที่ไม่ได้อยู่ในระหว่างการเริ่มต้นคอนเทนเนอร์ (โดยเฉพาะใน ENTRYPOINT
โดยปกติ)
การใช้ gosu
เกินกว่าที่อาจได้รับความทุกข์ทรมานจากช่องโหว่เช่น CVE-2016-2779 (ซึ่งกรณีการใช้นักเทียบท่าตามธรรมชาติปกป้องเรา); ดู 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 กับ Docker's --user
Flag
หากคุณอยากรู้เกี่ยวกับกรณีขอบที่ gosu
จัดการให้ดู Dockerfile.test-alpine
สำหรับ "Test Suite" (และสคริปต์ 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
ในระบบนิเวศของอัลไพน์ Linux, su-exec
เป็น gosu
ที่เขียนขึ้นใหม่น้อยที่สุดใน C ทำให้เป็นไบนารีที่เล็กกว่ามากและมีอยู่ในพื้นที่เก็บข้อมูลแพ็คเกจอัลไพน์ main
อย่างไรก็ตามในรุ่น 0.2 มันมีข้อผิดพลาดของตัวแยกวิเคราะห์ที่ค่อนข้างรุนแรงซึ่งไม่ได้อยู่ในการเปิดตัวเป็นเวลาหลายปี (และพฤติกรรมของรถบั๊กกี้คือการพิมพ์ผิดนำไปสู่การเรียกใช้รหัสเป็นรากโดยไม่คาดคิด?)
ฉันไม่คุ้นเคยกับพวกเขาอย่างมาก แต่มีทางเลือกอื่นอีกสองสามทางที่ฉันรู้ว่ารวมถึง:
chpst
(ส่วนหนึ่งของ runit
)