Cách đáng tin cậy để tống giam các tiến trình con bằng cách sử dụng `nsenter:`


15

Tôi biết rằng các không gian tên Linux, trong số nhiều thứ khác, có thể được tận dụng để xử lý việc hạn chế và bỏ tù các quy trình con một cách an toàn mà không có bất kỳ cơ hội nào để chúng được khoanh vùng và bỏ đi init. Nhưng tôi mờ về chi tiết thực hiện. Làm cách nào tôi có thể sử dụng các công cụ được cung cấp util-linuxnhư mountnsenterđể theo dõi, giám sát và đảm bảo rằng tất cả các quy trình được khởi chạy là hậu duệ không gian tên trực tiếp của quy trình khác?

Câu trả lời:


18

Tạo một không gian tên PID

Lệnh chính xác để sử dụng ở đây là unshare. Lưu ý rằng các tùy chọn cần thiết để làm điều này chỉ có sẵn từ util-linux 2.23. Ý tưởng là tạo ra một không gian tên PID mới cho chương trình bạn đang chạy sao cho tất cả các phần tử con của nó cũng được tạo trong không gian tên này. Bạn có thể chạy một lệnh trong một không gian tên PID mới chỉ bằng cách thực hiện:

sudo unshare -fp some_command

Để chạy shell, chỉ cần bỏ qua lệnh. Điều này sẽ tạo ra một quy trình, cùng với bất kỳ đứa con nào của nó, sẽ có một PID như bình thường trong không gian tên cha (hệ thống). Tuy nhiên, trong không gian tên mới, nó sẽ có một bộ vi xử lý 1cùng với một số đặc điểm đặc biệt của initquy trình. Có lẽ đặc điểm phù hợp nhất từ ​​góc độ giám sát là nếu bất kỳ hậu duệ nào của nó mồ côi, họ sẽ được cấp lại cho quy trình này chứ không phải là initquy trình thực .

Đơn giản chỉ cần làm điều này có thể là đủ cho hầu hết các trường hợp giám sát. Như đã đề cập trước đó, tất cả các quy trình trong không gian tên đều có các PID trong không gian tên cha mẹ để các lệnh thông thường có thể được sử dụng để giám sát hoạt động của chúng. Chúng tôi cũng đảm bảo rằng nếu bất kỳ quy trình nào trong không gian tên trở thành mồ côi, nó sẽ không rơi ra khỏi các nhánh cây quy trình bên dưới PID của chương trình cấp cao nhất có nghĩa là nó vẫn có thể dễ dàng theo dõi.

Kết hợp với một không gian tên mount

Tuy nhiên, những gì chúng ta không thể làm là theo dõi quá trình liên quan đến PID mà nó nghĩ là có. Để làm điều này và đặc biệt để có thể sử dụng pslệnh trong không gian tên mới, bạn cần gắn một procfshệ thống tệp riêng cho không gian tên. Điều này dẫn đến một vấn đề khác vì vị trí duy nhất pschấp nhận procfs/proc. Một giải pháp sẽ là tạo ra một chrootnhà tù và gắn kết cái mới procfsở đó. Nhưng đây là một cách tiếp cận rườm rà vì ở mức tối thiểu chúng ta sẽ cần sao chép (hoặc ít nhất là liên kết cứng) bất kỳ nhị phân nào chúng ta dự định sử dụng cùng với bất kỳ thư viện nào mà chúng phụ thuộc vào root mới.

Giải pháp là cũng sử dụng một không gian tên mount mới . Trong phạm vi này, chúng ta có thể gắn kết cái mới procfstheo cách sử dụng /procthư mục gốc thực sự , có thể sử dụng được trong không gian tên PID và không can thiệp vào bất cứ điều gì khác. Để làm cho quá trình này rất đơn giản, unsharelệnh đưa ra --mount-proctùy chọn:

sudo unshare -fp --mount-proc some_command

Bây giờ chạy pstrong các không gian tên kết hợp sẽ chỉ hiển thị các quy trình với không gian tên PID và nó sẽ hiển thị quy trình cấp cao nhất khi có một PID 1.

Thế còn nsenter?

Như tên cho thấy, nsentercó thể được sử dụng để nhập một không gian tên đã được tạo unshare. Điều này hữu ích nếu chúng tôi muốn nhận thông tin chỉ có sẵn từ bên trong không gian tên từ một tập lệnh không liên quan. Cách đơn giản nhất là truy cập cung cấp cho PID của bất kỳ chương trình nào đang chạy trong không gian tên. Để rõ ràng, đây phải là bộ vi xử lý của chương trình đích trong không gian tên nsenterđang được chạy (vì không gian tên có thể được lồng vào nhau, nên có thể một quy trình có nhiều bộ vi xử lý). Để chạy shell trong không gian tên PID / mount đích, chỉ cần làm:

sudo nsenter -t $PID -m -p

Nếu không gian tên này được thiết lập như trên, psbây giờ sẽ chỉ liệt kê các quy trình trong không gian tên đó.


Cảm ơn, Graeme. Điều này đã trả lời câu hỏi và nhiều hơn nữa. Điều thực sự khiến tôi phải hỏi là đọc các ghi chú từ trang man của Procfs trên các tệp khác nhau trong / Proc / pid / ns / * có nội dung: "Ràng buộc gắn tệp này (xem mount (2)) ở một nơi khác trong hệ thống tệp giữ ... không gian tên của quy trình được chỉ định bởi pid còn sống ngay cả khi tất cả các quy trình hiện tại trong không gian tên kết thúc. " Tôi cũng biết câu hỏi tương tự, nhưng điều này thật tuyệt vời. Tôi nghĩ rằng nếu bạn cảm thấy nó có liên quan, bạn có thể muốn thêm nó vào. Linux.die.net/man/5/proc
mikeerv

Điều này được đề cập trong phần cuối cùng của bài viết LWN (chỉ cần tìm kiếm liên kết gắn kết). Tôi không thực sự chắc chắn về điểm của nó mặc dù nó giữ cho không gian tên PID tồn tại nhưng sau khi initquá trình kiểu cấp cao nhất bị chết, bạn không thể tạo thêm nữa.
Graeme

Vâng, tôi cũng không chắc lắm về phần còn lại. Nhưng với câu trả lời này manvà một ngày cuối tuần với bản thân tôi, tôi muốn làm quen với nó hơn một chút. Cảm ơn một lần nữa. Có lẽ nó có liên quan nhiều hơn trong --user không gian tên.
mikeerv
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.