Làm thế nào để tôi nói tôi đang chạy trong một chroot?


47

Tôi có một bản cài đặt unix được cho là có thể sử dụng được cả dưới dạng chroot và như một hệ thống độc lập. Nếu nó chạy như một chroot, tôi không muốn chạy bất kỳ dịch vụ nào (cron, inetd, v.v.), vì chúng sẽ xung đột với hệ thống máy chủ hoặc là dự phòng.

Làm cách nào để tôi viết một tập lệnh shell hoạt động khác nhau tùy thuộc vào việc nó có chạy trong một chroot không? Nhu cầu trước mắt của tôi là một hệ thống Linux hiện đại, /procđược gắn trong chroot và tập lệnh đang chạy với quyền root, nhưng cũng có nhiều câu trả lời di động hơn. (Xem Làm thế nào để tôi biết tôi đang chạy trong một chroot nếu / Proc không được gắn kết? Đối với trường hợp Linux không có /proc.)

Tổng quát hơn, các đề xuất hoạt động cho các phương pháp ngăn chặn khác sẽ rất thú vị. Câu hỏi thực tế là, hệ thống này có được cho là đang chạy bất kỳ dịch vụ nào không? (Câu trả lời là không có trong một chroot, và có trong một máy ảo chính thức; tôi không biết về các trường hợp trung gian như nhà tù hoặc container.)

Câu trả lời:


46

Những gì tôi đã làm ở đây là kiểm tra xem gốc của initquy trình (PID 1) có giống với gốc của quy trình hiện tại hay không. Mặc dù /proc/1/rootluôn luôn là một liên kết đến /(trừ khi initbản thân nó bị chroot, nhưng đó không phải là trường hợp tôi quan tâm), theo sau nó dẫn đến thư mục gốc của chủ master. Kỹ thuật này được sử dụng trong một vài tập lệnh bảo trì trong Debian, ví dụ như bỏ qua việc bắt đầu udev sau khi cài đặt trong một chroot.

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

(Bằng cách này, đây là một ví dụ nữa về việc tại sao chrootlà vô ích đối với an ninh nếu quá trình chroot có quyền truy cập root. Quá trình phi gốc không thể đọc được /proc/1/root, nhưng họ có thể làm theo /proc/1234/rootnếu có một quá trình chạy với PID 1234 chạy như giống nhau người dùng.)

Nếu bạn không có quyền root, bạn có thể xem /proc/1/mountinfo/proc/$$/mountinfo(ghi lại ngắn gọn trong filesystems/proc.txttài liệu nhân Linux ). Tệp này có thể đọc được trên thế giới và chứa nhiều thông tin về từng điểm gắn kết trong chế độ xem của hệ thống tệp. Các đường dẫn trong tệp đó bị hạn chế bởi chroot ảnh hưởng đến quá trình đọc, nếu có. Nếu quá trình đọc /proc/1/mountinfođược chroot vào một hệ thống tập tin khác với root toàn cầu (giả sử root của pid 1 là root toàn cầu), thì không có mục nào /xuất hiện trong /proc/1/mountinfo. Nếu quá trình đọc /proc/1/mountinfođược chroot vào một thư mục trên hệ thống tập tin gốc toàn cầu, thì một mục nhập /sẽ xuất hiện /proc/1/mountinfo, nhưng với một id gắn kết khác. Ngẫu nhiên, trường gốc ($4) cho biết vị trí của chroot trong hệ thống tập tin chính của nó.

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

Đây là một giải pháp Linux thuần túy. Nó có thể khái quát với các biến thể Unix khác có đủ độ tương tự /proc(Solaris có một điểm tương tự /proc/1/root, tôi nghĩ vậy, nhưng không mountinfo).


1
Điều này sẽ không hoạt động trong OpenBSD vì nó có các PID ngẫu nhiên ; quá trình root về cơ bản không bao giờ là PID 1. Bây giờ bạn đã biết tại sao!
Adam Katz

@AdamKatz "... với một vài ngoại lệ rõ ràng, ví dụ: init (8)." Vậy đó là cái gì?
muru

@muru: aw, shucks. Bạn đã bắn tôi xuống. Tôi không chắc tại sao init(8)hoàn toàn cần phải có vị trí số 1 trừ khi có một loại bản chất mã hóa cứng nào đó yêu cầu nó (trong đó tôi vẫn không chắc chắn về lý do tại sao ). Tất nhiên, các BSD có các nhà tù tiên tiến hơn nhiều so với chỉ chroot, vì vậy tôi thậm chí không chắc vấn đề này có vấn đề như thế nào.
Adam Katz

4
@AdamKatz Điều ngược lại: pid 1 có vai trò đặc biệt (nó phải gặt zombie và nó miễn nhiễm với SIGKILL). Chương trình init là một thực hiện vai trò đó. Lý do câu trả lời của tôi không hoạt động trong OpenBSD không liên quan gì đến điều này: đó là vì OpenBSD không có gì giống như Solaris / Linux /proc. Câu trả lời của tôi không nhằm giải quyết bất cứ điều gì ngoài Linux.
Gilles 'SO- ngừng trở nên xấu xa'

@Gilles Tôi hình dung OpenBSD sẽ đánh bại điều này bằng cách này hay cách khác. Tuy nhiên, tôi ngạc nhiên rằng tất cả các mục vai trò đặc biệt đó không có khả năng được áp dụng cho một PID tùy ý (không có hậu quả), đó là những gì tôi muốn nói trong phần "in nghiêng" của mình trước đó.
Adam Katz

22

Như đã đề cập trong Cách di động để tìm số inodePhát hiện nhà tù chroot từ bên trong , bạn có thể kiểm tra xem số inode của /2:

$ ls -di /
2 /

Một số inode khác với 2 chỉ ra rằng gốc rõ ràng không phải là gốc thực sự của một hệ thống tập tin. Điều này sẽ không phát hiện ra các chroots xảy ra bắt nguồn từ một điểm gắn kết hoặc trên các hệ điều hành có số inode gốc ngẫu nhiên .


Trên hệ thống tập tin nào heuristic này hoạt động?
Gilles 'SO- ngừng trở nên xấu xa'

Đã thử nghiệm trên ext3 và hfs.
l0b0

Vì vậy, tôi đã bị lừa và tôi nghĩ rằng tôi đã tìm thấy một phương pháp đáng tin cậy hơn mà không yêu cầu quyền root (chỉ dành cho Linux). Tôi vẫn mở cho các ví dụ ngược hoặc các phương thức di động hơn.
Gilles 'SO- ngừng trở nên xấu xa'

6
Điều này đúng với ext [234], nhưng không phải của tất cả các hệ thống tập tin. Nó cũng chỉ kiểm tra rằng root của bạn là root của hệ thống tập tin, có thể không được gắn kết như root thực sự. Nói cách khác, nếu bạn gắn một phân vùng khác vào / jail và chroot /jailsau đó nó sẽ trông giống như gốc thực sự của bài kiểm tra này.
psusi

1
@AdamKatz Rõ ràng là không. Đã được thử nghiệm trong openbsd 6.0 ổn định, số inode vẫn là 2 cho đường dẫn gốc thực tế trong khi đó là một số ngẫu nhiên cho chroot.
Dmitri DB

5

Mặc dù rõ ràng không dễ mang theo như nhiều tùy chọn khác được liệt kê ở đây, nếu bạn đang sử dụng hệ thống dựa trên Debian, hãy thử ischroot.

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

Để nhận trạng thái trong bảng điều khiển trực tiếp, sử dụng ischroot:

ischroot;echo $?

Mã thoát:

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).
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.