วิธีการดำเนินการ chroot กับ namespaces Linux?


14

หลังจากอ่านเกี่ยวกับเนมสเปซลินุกซ์ฉันก็รู้สึกว่ามันมีคุณสมบัติอื่น ๆ มากมายซึ่งเป็นทางเลือกสำหรับ chroot ตัวอย่างเช่นในบทความนี้ :

การใช้งานอื่น ๆ [ของ namespaces] รวมถึง [... ] chroot () - การแยกลักษณะของกระบวนการเป็นส่วนหนึ่งของลำดับชั้นไดเรกทอรีเดียว

อย่างไรก็ตามเมื่อฉันโคลนเนมสเปซ Mount ตัวอย่างเช่นด้วยคำสั่งต่อไปนี้ฉันยังคงเห็นต้นไม้รากเดิมทั้งหมด

unshare --mount -- /bin/bash

ฉันเข้าใจว่าตอนนี้ฉันสามารถทำการเมาท์เพิ่มเติมในเนมสเปซใหม่ที่ไม่ได้ใช้ร่วมกับเนมสเปซดั้งเดิมได้ดังนั้นจึงให้การแยก แต่ก็ยังคงเป็นรูทเดียวกันเช่น/etcจะยังคงเหมือนเดิมสำหรับเนมสเปซทั้งสอง ฉันยังต้องchrootเปลี่ยนรูทหรือมีทางเลือกอื่นหรือไม่?

ฉันคาดหวังว่าคำถามนี้จะให้คำตอบ แต่คำตอบนั้นใช้chrootอีกครั้งเท่านั้น

แก้ไข # 1

pivot_rootมีความคิดเห็นที่ถูกลบในขณะนี้ว่าเป็นที่กล่าวถึง เนื่องจากนี่เป็นส่วนหนึ่งของlinux/fs/namespace.cความเป็นจริงมันเป็นส่วนหนึ่งของการติดตั้งเนมสเปซ นี้แสดงให้เห็นว่าการเปลี่ยนไดเรกทอรีรากเท่านั้นที่มีunshareและmountเป็นไปไม่ได้ แต่ namespaces ให้ตัวเอง - ฉลาดมากขึ้น - chrootรุ่นของ ถึงกระนั้นฉันก็ยังไม่ได้รับแนวคิดหลักของวิธีการนี้ที่ทำให้มันแตกต่างจากchrootเดิมแม้หลังจากอ่านซอร์สโค้ด (ในแง่ของความปลอดภัยและการแยกที่ดีกว่า)

แก้ไข # 2

นี้ไม่ซ้ำกับคำถามนี้ หลังจากรันคำสั่งทั้งหมดจากคำตอบฉันมี /tmp/tmp.vyM9IwnKuY แยกต่างหาก (หรือคล้ายกัน) แต่ไดเรกทอรีรูทยังคงเหมือนเดิม!


เกี่ยวกับความแตกต่างระหว่างpivot_rootและchroot: ฉันลองดูที่แหล่งข้อมูลนักเทียบท่าและพบว่าหากการดำเนินการล้มเหลวpivot_rootมันกลับไปchrootเช่นกลไกเหล่านี้ถือว่ามีความคล้ายคลึงกันอย่างน้อยในการทำงานเพื่อวัตถุประสงค์ในการจัดเก็บ
Danila Kiver

คำตอบ:


13

ป้อนติด namespace ก่อนที่จะตั้งขึ้นchrootจะช่วยให้คุณหลีกเลี่ยง cluttering namespace /procโฮสต์กับม้าเพิ่มเติมเช่นสำหรับ คุณสามารถใช้chrootใน namespace เมานต์เป็นแฮ็คที่ดีและเรียบง่าย

ฉันคิดว่ามันมีข้อดีที่จะเข้าใจpivot_rootแต่มันมีช่วงของการเรียนรู้เล็กน้อย เอกสารไม่ได้อธิบายทุกอย่าง ... แม้ว่าจะมีตัวอย่างการใช้งานในman 8 pivot_root(สำหรับคำสั่งเชลล์) man 2 pivot_root(สำหรับการเรียกของระบบ) อาจชัดเจนขึ้นถ้าทำเช่นเดียวกันและรวมโปรแกรมตัวอย่าง C ไว้ด้วย

วิธีใช้ pivot_root

ทันทีหลังจากเข้าสู่ Mount namespace คุณต้องmount --make-rslave /หรือเทียบเท่า มิฉะนั้นการเปลี่ยนแปลงติดของคุณทั้งหมดเผยแพร่สู่ม้าใน namespace pivot_rootเดิมรวมทั้ง คุณไม่ต้องการที่ :)

หากคุณใช้unshare --mountคำสั่งให้สังเกตว่ามีการบันทึกไว้เพื่อให้ใช้เป็นmount --make-rprivateค่าเริ่มต้น AFAICS นี่เป็นค่าเริ่มต้นที่ไม่ดีและคุณไม่ต้องการสิ่งนี้ในรหัสการผลิต เช่น ณ จุดนี้มันจะหยุดejectทำงานบน DVD หรือ USB ที่ติดตั้งในเนมสเปซโฮสต์ DVD หรือ USB จะยังคงติดตั้งอยู่ภายในแผนผังเมาท์ส่วนตัวและเคอร์เนลจะไม่อนุญาตให้คุณนำแผ่นดีวีดีออก

เมื่อคุณทำเช่นนั้นคุณสามารถติดตั้งเช่น/procไดเรกทอรีที่คุณจะใช้ chrootเช่นเดียวกับที่คุณต้องการสำหรับ

ซึ่งแตกต่างจากเมื่อคุณใช้chroot, pivot_rootต้องการให้ระบบแฟ้มรากใหม่ของคุณเป็นจุดติด mount --rbind new_root new_rootถ้ามันไม่ได้เป็นหนึ่งแล้วคุณสามารถตอบสนองนี้โดยเพียงแค่ใช้การผูกติด:

ใช้pivot_root- จากนั้นumountระบบไฟล์รูทแบบเก่าด้วยตัวเลือก-l/ MNT_DETACH( คุณไม่ต้องการumount -Rซึ่งอาจใช้เวลานานกว่า )

ในทางเทคนิคแล้วการใช้pivot_rootโดยทั่วไปจำเป็นต้องเกี่ยวข้องกับการใช้chrootเช่นกัน ไม่ใช่ "อย่างใดอย่างหนึ่งหรือ"

ตามที่man 2 pivot_rootกำหนดไว้เท่านั้นเป็นการแลกเปลี่ยนรูทของการเมาท์เนมสเปซ ไม่ได้กำหนดให้เปลี่ยนไดเรกทอรีทางกายภาพที่กระบวนการของกระบวนการกำลังชี้ไป หรือไดเรกทอรีทำงานปัจจุบัน ( /proc/self/cwd) มันเกิดขึ้นว่ามันไม่ทำเช่นนั้น แต่นี้เป็นสับที่จะจัดการกับหัวข้อเคอร์เนล manpage บอกว่าสามารถเปลี่ยนแปลงได้ในอนาคต

โดยปกติคุณต้องการลำดับนี้:

chdir(new_root);            // cd new_root
pivot_root(".", put_old);   // pivot_root . put_old
chroot(".");                // chroot .

postition ของchrootในลำดับนี้เป็นอีกหนึ่งรายละเอียดที่ลึกซึ้ง แม้ว่าจุดประสงค์pivot_rootคือการจัดเรียงเมาท์เนมสเปซใหม่อีกครั้งรหัสเคอร์เนลดูเหมือนว่าจะค้นหาระบบไฟล์รูทเพื่อย้ายโดยดูที่รูตต่อกระบวนการซึ่งเป็นchrootชุด

ทำไมถึงใช้ pivot_root

โดยหลักการแล้วมันสมเหตุสมผลที่จะใช้pivot_rootเพื่อความปลอดภัยและการแยก ฉันชอบคิดเกี่ยวกับทฤษฎีความปลอดภัยตามความสามารถ คุณส่งรายการทรัพยากรเฉพาะที่จำเป็นและกระบวนการไม่สามารถเข้าถึงทรัพยากรอื่นได้ ในกรณีนี้เรากำลังพูดถึงระบบไฟล์ที่ส่งผ่านไปยังเมานต์เนมสเปซ แนวคิดนี้ใช้โดยทั่วไปกับคุณลักษณะ "namespaces" ของ Linux แม้ว่าฉันอาจจะไม่ได้แสดงความเป็นไปได้ดีนัก

chrootตั้งค่ากระบวนการรากเท่านั้น แต่กระบวนการยังคงอ้างถึงเนมสเปซการเมาท์แบบเต็ม หากกระบวนการยังคงมีสิทธิ์ดำเนินการchrootดังนั้นจะสามารถสำรองข้อมูลเนมสเปซระบบไฟล์ได้ ตามรายละเอียดในman 2 chroot"superuser สามารถหลบหนีจาก 'คุก chroot' โดย ... "

อีกวิธีหนึ่งที่กระตุ้นความคิดที่จะเลิกเป็นchroot nsenter --mount=/proc/self/ns/mntนี่อาจเป็นเหตุผลที่ดีกว่าสำหรับหลักการ nsenter/ setns()จำเป็นต้องโหลดรูทกระบวนการอีกครั้งจากรูทของเนมสเปซเมาต์ ... แม้ว่าข้อเท็จจริงนี้จะใช้งานได้เมื่อทั้งสองอ้างถึงฟิสิคัลไดเร็กทอรีที่ต่างกันอาจถูกพิจารณาว่าเป็นข้อบกพร่องเคอร์เนล (หมายเหตุทางเทคนิค: อาจมีหลายระบบไฟล์ติดตั้งที่ด้านบนของแต่ละอื่น ๆ ที่รูท; setns()ใช้ด้านบนติดตั้งล่าสุดหนึ่ง)

สิ่งนี้แสดงให้เห็นถึงข้อดีอย่างหนึ่งของการรวม mount namespace เข้ากับ "PID namespace" การอยู่ภายใน PID เนมสเปซจะป้องกันคุณจากการป้อนเมานต์เนมสเปซของกระบวนการที่ไม่ได้กำหนดไว้ นอกจากนี้ยังป้องกันไม่ให้คุณเข้าสู่รูทของกระบวนการที่ไม่ได้กำหนดไว้ ( /proc/$PID/root) และแน่นอนเนมสเปซ PID ยังป้องกันไม่ให้คุณฆ่ากระบวนการใด ๆ ที่อยู่นอก :-)


สิ่งนี้ช่วยได้มากแล้ว ถึงกระนั้นฉันก็ไม่แน่ใจในสิ่งที่คุณหมายถึงโดย "ภูเขาที่ด้านบนของ namespace" และมีวิธีที่จะเปลี่ยนหรือไม่
koalo

1
@koalo แก้ไข :-) ป.ล. ฉันไม่รู้ว่าทำไมคุณต้องใช้ fstab สำหรับ "make-rslave" / "make-rprivate" switch-root.c ของ systemd ทำงานได้mount(NULL, "/", NULL, MS_REC|MS_PRIVATE, NULL)
sourcejedi

1
@koalo จากนั้นผู้พัฒนาเคอร์เนล linux ใช้ "rootfs" เมื่อพวกเขาตั้งชื่อสิ่งที่สี่ :-P unix.stackexchange.com/questions/152029/…
sourcejedi

1
คำตอบนี้และคนอื่น ๆ โดย @sourcejedi มีประโยชน์เป็นพิเศษฉันจะถาม"pivot_root: ไม่สามารถนับ put_old ไม่ว่าง"แต่คำตอบอยู่ที่นี่แล้วขี้เกียจเพราะแรงไม่ทำงานumount -l ./oldroot
earcam

1
เมื่อเร็ว ๆ นี้มีการอัปเดตไปยังหน้า man pivot_root (2)พร้อมคำอธิบายที่หลากหลายและตอนนี้ก็มีโปรแกรมตัวอย่าง คุณอาจต้องการอัพเดทคำตอบเพื่อสะท้อนสิ่งนี้? หน้าคนตอนนี้ยังอธิบายpivot_root(".", ".")เคล็ดลับที่ดีซึ่งเป็นวิธีที่ง่ายที่สุดที่จะใช้pivot_rootในสถานการณ์ส่วนใหญ่ (ไม่chrootจำเป็น)
Philipp Wendler
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.