Làm thế nào để thực hiện chroot với không gian tên Linux?


14

Sau khi đọc về các không gian tên Linux, tôi có ấn tượng rằng chúng là một trong số các tính năng khác, một sự thay thế cho chroot. Ví dụ, trong bài viết này :

Các cách sử dụng khác [của không gian tên] bao gồm [...] chroot () - cách ly kiểu của một tiến trình với một phần của hệ thống phân cấp thư mục đơn.

Tuy nhiên, khi tôi sao chép không gian tên mount, ví dụ với lệnh sau, tôi vẫn thấy toàn bộ cây gốc.

unshare --mount -- /bin/bash

Tôi hiểu rằng bây giờ tôi có thể thực hiện các gắn kết bổ sung trong không gian tên mới không được chia sẻ với không gian tên gốc và do đó điều này cung cấp sự cô lập, nhưng nó vẫn là cùng một gốc, ví dụ như /etcvẫn giống nhau cho cả hai không gian tên. Tôi vẫn cần chrootphải thay đổi root hoặc có một sự thay thế?

Tôi đã mong đợi rằng câu hỏi này sẽ cung cấp một câu trả lời, nhưng câu trả lời chỉ sử dụng chroot, một lần nữa.

EDIT # 1

Có một bình luận đã bị xóa mà đề cập pivot_root. Vì đây thực sự là một phần của linux/fs/namespace.c, nên trên thực tế nó là một phần của việc thực hiện không gian tên. Điều này cho thấy rằng chỉ thay đổi thư mục gốc bằng unsharemountkhông thể, nhưng không gian tên cung cấp một phiên bản riêng - thông minh hơn chroot. Tuy nhiên, tôi không có ý tưởng chính về phương pháp này làm cho nó khác về cơ bản chroot, ngay cả sau khi đọc mã nguồn (theo nghĩa là bảo mật hoặc cách ly tốt hơn).

EDIT # 2

Đây không phải là một bản sao của câu hỏi này . Sau khi thực hiện tất cả các lệnh từ câu trả lời, tôi có /tmp/tmp.vyM9IwnKuY (hoặc tương tự) riêng biệt, nhưng thư mục gốc vẫn giống nhau!


Về sự khác biệt giữa pivot_rootchroot: Tôi đã xem xét các nguồn Docker và thấy rằng nếu nó không thực thipivot_root , nó sẽ quay trở lại chroot, tức là các cơ chế này được coi là ít nhất tương tự về chức năng cho các mục đích container.
Danila Kiver 17/07/18

Câu trả lời:


13

Nhập một không gian tên mount trước khi thiết lập a chroot, cho phép bạn tránh làm lộn xộn không gian tên máy chủ với các mount bổ sung, ví dụ như cho /proc. Bạn có thể sử dụng chrootbên trong một không gian tên mount như một bản hack đẹp và đơn giản.

Tôi nghĩ rằng có những lợi thế để hiểu pivot_root, nhưng nó có một chút đường cong học tập. Tài liệu này không hoàn toàn giải thích mọi thứ ... mặc dù có một ví dụ sử dụng trong man 8 pivot_root(đối với lệnh shell). man 2 pivot_root(đối với cuộc gọi hệ thống) có thể rõ ràng hơn nếu nó thực hiện tương tự và bao gồm một chương trình C mẫu.

Cách sử dụng p Pivot_root

Ngay sau khi vào không gian tên mount, bạn cũng cần mount --make-rslave /hoặc tương đương. Mặt khác, tất cả các thay đổi gắn kết của bạn lan truyền đến các gắn kết trong không gian tên ban đầu, bao gồm cả pivot_root. Bạn không muốn điều đó :).

Nếu bạn đã sử dụng unshare --mountlệnh, lưu ý rằng nó được ghi lại để áp dụng mount --make-rprivatetheo mặc định. AFAICS đây là một mặc định xấu và bạn không muốn điều này trong mã sản xuất. Ví dụ, tại thời điểm này, nó sẽ ngừng hoạt ejectđộng trên DVD hoặc USB được gắn trong không gian tên máy chủ. DVD hoặc USB sẽ vẫn được gắn bên trong cây gắn kết riêng tư và hạt nhân sẽ không cho phép bạn nhả đĩa DVD.

Khi bạn đã thực hiện điều đó, bạn có thể gắn kết, ví dụ như /procthư mục bạn sẽ sử dụng. Giống như cách bạn sẽ làm chroot.

Không giống như khi bạn sử dụng chroot , pivot_rootyêu cầu hệ thống tập tin gốc mới của bạn là một điểm gắn kết. Nếu nó chưa phải là một cái, bạn có thể đáp ứng điều này bằng cách áp dụng một mount mount : mount --rbind new_root new_root.

Sử dụng pivot_root- và sau đó umountlà hệ thống tập tin gốc cũ, với tùy chọn -l/ MNT_DETACH. ( Bạn không cần umount -R, có thể mất nhiều thời gian hơn. ).

Về mặt kỹ thuật, sử dụng pivot_root thường cần liên quan đến việc sử dụng chrootlà tốt; nó không phải là "hoặc - hoặc".

Theo man 2 pivot_root, nó chỉ được định nghĩa là hoán đổi gốc của không gian tên mount. Nó không được xác định để thay đổi thư mục vật lý mà root process đang trỏ tới. Hoặc thư mục làm việc hiện tại (/proc/self/cwd ). Nó sẽ xảy ra rằng nó không làm như vậy, nhưng đây là một hack để đề xử lý hạt nhân. Trang này nói rằng có thể thay đổi trong tương lai.

Thông thường bạn muốn trình tự này:

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

Các bài đăng của chroottrình tự này là một chi tiết tinh tế khác . Mặc dù quan điểm củapivot_root việc sắp xếp lại không gian tên mount, mã kernel dường như tìm thấy hệ thống tập tin gốc để di chuyển bằng cách nhìn vào root mỗi tiến trình, đó là những gì chrootthiết lập.

Tại sao nên sử dụng p Pivot_root

Về nguyên tắc, nó có ý nghĩa để sử dụng pivot_rootcho an ninh và cách ly. Tôi thích nghĩ về lý thuyết bảo mật dựa trên năng lực . Bạn chuyển vào một danh sách các tài nguyên cụ thể cần thiết và quá trình có thể truy cập không có tài nguyên nào khác. Trong trường hợp này, chúng ta đang nói về các hệ thống tập tin được truyền vào một không gian tên mount. Ý tưởng này thường áp dụng cho tính năng "không gian tên" của Linux, mặc dù có lẽ tôi không thể hiện nó tốt lắm.

chrootchỉ đặt gốc quy trình, nhưng quy trình vẫn đề cập đến không gian tên gắn kết đầy đủ. Nếu một quá trình duy trì đặc quyền để thực hiện chroot, thì nó có thể đi ngược lại không gian tên hệ thống tập tin. Như được nêu chi tiết man 2 chroot, "siêu người dùng có thể thoát khỏi 'nhà tù chroot' bằng cách ...".

Một cách kích thích tư duy khác để hoàn tác chrootnsenter --mount=/proc/self/ns/mnt. Đây có lẽ là một lập luận mạnh mẽ hơn cho nguyên tắc. nsenter/ setns()nhất thiết phải tải lại root tiến trình, từ gốc của không gian tên mount ... mặc dù thực tế là điều này hoạt động khi cả hai tham chiếu đến các thư mục vật lý khác nhau, có thể được coi là một lỗi kernel. (Lưu ý kỹ thuật: có thể có nhiều hệ thống tập tin được gắn chồng lên nhau ở gốc;setns() sử dụng cùng, gần đây nhất).

Điều này minh họa một lợi thế của việc kết hợp không gian tên mount với "không gian tên PID". Ở trong một không gian tên PID sẽ ngăn bạn vào không gian tên gắn kết của một quy trình không được kiểm soát. Nó cũng ngăn bạn nhập vào gốc của một quy trình không được kiểm soát ( /proc/$PID/root). Và tất nhiên, một không gian tên PID cũng ngăn bạn giết bất kỳ tiến trình nào nằm ngoài nó :-).


Điều này đã giúp rất nhiều. Tuy nhiên, tôi không chắc ý của bạn là gì bởi "đỉnh ở trên cùng của không gian tên". Và có cách nào để thay đổi nó?
koalo

1
@koalo đã chỉnh sửa :-). ps tôi không biết tại sao bạn lại cần fstab cho "make-rslave" / "make-rprivate". switch-root.c của systemd chỉ cần làmmount(NULL, "/", NULL, MS_REC|MS_PRIVATE, NULL)
sourcejedi

1
@koalo và sau đó các nhà phát triển nhân linux đã sử dụng "rootfs" khi họ đặt tên cho thứ thứ tư :-P. unix.stackexchange.com/questions/152029/ từ
sourcejedi

1
Câu trả lời này và những câu trả lời khác của @sourcejedi đặc biệt hữu ích, tôi sẽ hỏi "p Pivot_root: không thể đưa ra bận rộn" nhưng câu trả lời đã có ở đây, hãy lười biếng vì lực lượng sẽ không hoạt độngumount -l ./oldroot
Earcam

1
Gần đây, có một bản cập nhật cho trang man p Pivot_root (2) với một số giải thích rõ ràng và hiện tại nó bao gồm một chương trình ví dụ. Bạn có thể muốn cập nhật câu trả lời của bạn để phản ánh điều này? Trang người đàn ông bây giờ cũng giải thích pivot_root(".", ".")thủ thuật hay, đây thực sự là cách dễ nhất để sử dụng pivot_roottrong hầu hết các trường hợp (không chrootcần thiết).
Philipp Wendler
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.