ฉันจะบอกได้อย่างไรว่าฉันทำงานเป็น chroot?


46

ฉันมีการติดตั้งยูนิกซ์ที่ควรจะใช้งานได้ทั้งแบบ chroot และแบบสแตนด์อโลน หากทำงานเป็น chroot ฉันไม่ต้องการเรียกใช้บริการใด ๆ (cron, inetd และอื่น ๆ ) เพราะพวกเขาจะขัดแย้งกับระบบโฮสต์หรือซ้ำซ้อน

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

โดยทั่วไปคำแนะนำที่ใช้ได้กับวิธีการกักเก็บอื่น ๆ นั้นน่าสนใจ คำถามที่ปฏิบัติได้คือระบบนี้ควรใช้บริการใด ๆ หรือไม่? (คำตอบที่ไม่ได้อยู่ใน chroot และใช่ในเครื่องเสมือนที่เต็มเปี่ยมฉันไม่รู้เกี่ยวกับตัวพิมพ์กลางเช่นคุกหรือตู้คอนเทนเนอร์)

คำตอบ:


45

สิ่งที่ฉันทำที่นี่คือการทดสอบว่ารากของinitกระบวนการ (PID 1) เหมือนกับรากของกระบวนการปัจจุบันหรือไม่ แม้ว่า/proc/1/rootจะเป็นลิงก์ไปยัง/(เว้นแต่initตัวเองจะถูก chrooted แต่ไม่ใช่กรณีที่ฉันสนใจ) หลังจากนั้นมันจะนำไปสู่ไดเรกทอรีราก "หลัก" เทคนิคนี้ใช้ในสคริปต์บำรุงรักษาสองสามตัวใน Debian เช่นข้ามการเริ่มต้น udev หลังจากติดตั้งใน chroot

if [ "$(stat -c %d:%i /)" != "$(stat -c %d:%i /proc/1/root/.)" ]; then
  echo "We are chrooted!"
else
  echo "Business as usual"
fi

(โดยวิธีนี้เป็นอีกตัวอย่างหนึ่งของเหตุผลที่อื่นchrootเป็นประโยชน์สำหรับการรักษาความปลอดภัยถ้ากระบวนการ chrooted มีการเข้าถึงราก. กระบวนการที่ไม่ใช่รากไม่สามารถอ่าน/proc/1/rootแต่พวกเขาสามารถทำตาม/proc/1234/rootถ้ามีกระบวนการทำงานด้วย PID 1234 ทำงานตามที่เดียวกัน ผู้ใช้.)

หากคุณไม่มีสิทธิ์รูทคุณสามารถดู/proc/1/mountinfoและ/proc/$$/mountinfo(จัดทำเอกสารสั้น ๆ ในfilesystems/proc.txtเอกสารประกอบเคอร์เนล Linux ) ไฟล์นี้สามารถอ่านได้ทั่วโลกและมีข้อมูลจำนวนมากเกี่ยวกับจุดเชื่อมต่อแต่ละจุดในมุมมองของกระบวนการของระบบไฟล์ พา ธ ในไฟล์นั้นถูก จำกัด โดย chroot ที่มีผลต่อกระบวนการของผู้อ่านหากมี ถ้าอ่านกระบวนการ/proc/1/mountinfoเป็น chrooted เข้าสู่ระบบแฟ้มที่แตกต่างจากรากทั่วโลก (สมมติว่าราก pid 1 เป็นรากที่ทั่วโลก) แล้วเข้าไม่ปรากฏใน/ /proc/1/mountinfoหากการอ่านกระบวนการ/proc/1/mountinfoถูก chrooted ไปยังไดเร็กทอรีบนระบบไฟล์โกลบอลรูทแล้วรายการสำหรับ/จะปรากฏขึ้น/proc/1/mountinfoแต่มีเมาต์ id ต่างกัน อนึ่งฟิลด์รูต ($4) ระบุตำแหน่งที่ chroot อยู่ในระบบไฟล์หลัก

[ "$(awk '$5=="/" {print $1}' </proc/1/mountinfo)" != "$(awk '$5=="/" {print $1}' </proc/$$/mountinfo)" ]

นี่เป็นโซลูชัน Linux ที่แท้จริง มันอาจจะเป็น generalizable สำหรับตัวแปร Unix อื่น ๆ ที่มีความคล้ายคลึงกันพอสมควร/proc(Solaris มีความคล้ายคลึงกัน/proc/1/rootฉันคิดว่า แต่ไม่ใช่mountinfo)


1
นี้จะไม่ทำงานใน OpenBSD เพราะมันมีPIDs สุ่ม ; กระบวนการรูทนั้นไม่เคยใช้ PID 1. ตอนนี้คุณรู้แล้วว่าทำไม!
Adam Katz

@AdamKatz "... มีข้อยกเว้นที่ชัดเจนสองสามอย่างเช่น init (8)" แล้วมันคืออะไร?
muru

@muru: aw, shucks คุณทำให้ฉันผิดหวัง ฉันไม่แน่ใจว่าทำไมinit(8)ต้องมีสล็อต # 1 อย่างแน่นอนเว้นแต่จะมีลักษณะของการกำหนดรหัสแบบยาก (ซึ่งฉันยังไม่แน่ใจว่าทำไม ) แน่นอน BSDs มีคุกขั้นสูงมากกว่า chroot ดังนั้นฉันจึงไม่แน่ใจด้วยซ้ำว่าปัญหานี้เกิดขึ้นได้อย่างไร
Adam Katz

4
@ AdamKatz มันตรงกันข้าม: pid 1 มีบทบาทพิเศษ (มันต้องเก็บเกี่ยวซอมบี้และมันจะมีภูมิคุ้มกันต่อ SIGKILL) โปรแกรม init คือการนำไปปฏิบัติของบทบาทนั้น เหตุผลที่คำตอบของฉันไม่ทำงานใน OpenBSD มีอะไรจะทำอย่างไรกับนี้มันเป็นเพราะ OpenBSD ไม่ได้มีอะไรที่เหมือน /procSolaris คำตอบของฉันไม่ได้หมายถึงการจัดการอะไรนอกจากลินุกซ์อยู่ดี
Gilles 'ดังนั้นหยุดความชั่วร้าย'

@Gilles ฉันคิดว่า OpenBSD น่าจะมีสิ่งนี้พ่ายแพ้ไม่ทางใดก็ทางหนึ่ง ถึงกระนั้นฉันก็ยังประหลาดใจที่รายการบทบาทพิเศษเหล่านั้นทั้งหมดไม่สามารถนำไปใช้กับ PID ตามอำเภอใจได้
Adam Katz

22

ตามที่กล่าวไว้ในวิธีพกพาเพื่อค้นหาหมายเลขไอโหนดและการตรวจจับคุก chroot จากภายในคุณสามารถตรวจสอบว่าหมายเลขไอโหนด/เป็น2:

$ ls -di /
2 /

หมายเลขไอโหนดที่แตกต่างจาก 2 บ่งชี้ว่ารูทที่ชัดเจนไม่ได้เป็นรูทจริงของระบบไฟล์ นี้จะไม่ตรวจสอบ chroots ที่เกิดขึ้นจะถูกฝังในจุดติดหรือบนระบบปฏิบัติการที่มีหมายเลขไอโหนดรากสุ่ม


ระบบฮิวริสติกนี้ทำงานอย่างไร
Gilles 'หยุดความชั่วร้าย'

ทดสอบกับ ext3 และ hfs
l0b0

ดังนั้นฉันจึงหลอกไปมาและฉันคิดว่าฉันพบวิธีที่น่าเชื่อถือมากกว่าที่ไม่ต้องการการอนุญาตราก (Linux เท่านั้น) ฉันยังคงเปิดตัวอย่างเคาน์เตอร์หรือวิธีพกพา
Gilles 'หยุดความชั่วร้าย'

6
สิ่งนี้เป็นจริงสำหรับ ext [234] แต่ไม่ใช่ทุกระบบไฟล์ นอกจากนี้ยังทำการทดสอบว่ารูทของคุณเป็นรูทของระบบไฟล์ซึ่งอาจไม่ได้เมาท์เป็นรูทจริง กล่าวอีกนัยหนึ่งถ้าคุณติดตั้งพาร์ทิชันอื่นใน / คุกchroot /jailแล้วมันจะดูเหมือนรากที่แท้จริงในการทดสอบนี้
psusi

1
@ AdamKatz เห็นได้ชัดว่าไม่ ทดสอบใน openbsd 6.0-stable หมายเลข inode ยังคงเป็น 2 สำหรับเส้นทางรูทจริงในขณะที่เป็นหมายเลขสุ่มสำหรับ chroot
Dmitri DB

5

ในขณะที่ชัดเจนไม่ได้เป็นแบบพกพาเป็นตัวเลือกอื่น ๆ อยู่ที่นี่ถ้าคุณอยู่ในระบบ Debian-based ischrootลอง

ดู: https://manpages.debian.org/jessie/debianutils/ischroot.1.en.html

ในการรับสถานะในคอนโซลโดยตรงโดยใช้ ischroot:

ischroot;echo $?

รหัสออก:

0 if currently running in a chroot
1 if currently not running in a chroot
2 if the detection is not possible (On GNU/Linux this happens if the script is not run as root).
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.