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 chroot
bê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 --mount
lệnh, lưu ý rằng nó được ghi lại để áp dụng mount --make-rprivate
theo 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ư /proc
thư 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_root
yê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 đó umount
là 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 chroot
là 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 chroot
trì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ì chroot
thiế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_root
cho 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.
chroot
chỉ đặ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 chroot
là nsenter --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ó :-).
pivot_root
vàchroot
: 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ạichroot
, 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.