Điều đó có nghĩa là gì nếu một bộ chứa Linux (bộ chứa LXC) được gọi là "không có đặc quyền"?
Điều đó có nghĩa là gì nếu một bộ chứa Linux (bộ chứa LXC) được gọi là "không có đặc quyền"?
Câu trả lời:
Các thùng chứa LXC không có đặc quyền là những thùng chứa sử dụng các không gian tên người dùng ( userns ). Tức là một tính năng hạt nhân cho phép ánh xạ một phạm vi UID trên máy chủ thành một không gian tên bên trong mà người dùng có UID 0 có thể tồn tại lại.
Trái với nhận thức ban đầu của tôi về các container LXC không được ưu tiên trong một thời gian, điều này không có nghĩa là container phải được sở hữu bởi một người dùng máy chủ không có đặc quyền. Đó chỉ là một khả năng.
Có liên quan là:
usermod [-v|-w|--add-sub-uids|--add-sub-gids]
)lxc.id_map = ...
)Vì vậy, thậm chí root
có thể sở hữu các container không có đặc quyền, vì các UID hiệu quả của các quá trình chứa trên máy chủ sẽ kết thúc bên trong phạm vi được xác định bởi ánh xạ.
Tuy nhiên, trước tiên root
bạn phải xác định ID cấp dưới. Không giống như người dùng được tạo thông qua adduser
, root
sẽ không có một phạm vi ID cấp dưới được xác định theo mặc định.
Ngoài ra, hãy nhớ rằng toàn bộ phạm vi bạn cung cấp là theo ý của bạn, vì vậy bạn có thể có 3 thùng chứa với các dòng cấu hình sau (chỉ ánh xạ UID được hiển thị):
lxc.id_map = u 0 100000 100000
lxc.id_map = u 0 200000 100000
lxc.id_map = u 0 300000 100000
giả sử root
sở hữu UID cấp dưới trong khoảng từ 100000 đến 400000. Mặc dù vậy, tất cả các tài liệu tôi tìm thấy đều đề xuất sử dụng 65536 ID cấp dưới cho mỗi container, tuy nhiên một số sử dụng 100000 để dễ đọc hơn cho con người.
Nói cách khác: Bạn không phải gán cùng một phạm vi cho mỗi vùng chứa.
Với hơn 4 tỷ (~ 2^32
) ID cấp dưới có thể có nghĩa là bạn có thể hào phóng khi giao dịch các phạm vi cấp dưới cho người dùng máy chủ của mình.
Để chà xát nó một lần nữa. Một khách LXC không có đặc quyền không cần phải được điều hành bởi người dùng không có đặc quyền trên máy chủ.
Định cấu hình vùng chứa của bạn với ánh xạ UID / GID cấp dưới như thế này:
lxc.id_map = u 0 100000 100000
lxc.id_map = g 0 100000 100000
nơi người dùng root
trên máy chủ sở hữu phạm vi ID cấp dưới đó, sẽ cho phép bạn giới hạn khách tốt hơn.
Tuy nhiên, có một lợi thế bổ sung quan trọng trong kịch bản như vậy (và vâng, tôi đã xác minh rằng nó hoạt động): bạn có thể tự động khởi động container của mình khi khởi động hệ thống.
Thông thường khi lướt web để biết thông tin về LXC, bạn sẽ được thông báo rằng không thể tự động đăng ký một khách LXC không có đặc quyền. Tuy nhiên, điều đó chỉ đúng theo mặc định cho những container không có trong bộ lưu trữ trên toàn hệ thống cho các container (thường là như thế /var/lib/lxc
). Nếu chúng là (thường có nghĩa là chúng được tạo bởi root và được bắt đầu bằng root), thì đó là một câu chuyện hoàn toàn khác.
lxc.start.auto = 1
sẽ thực hiện công việc khá độc đáo, một khi bạn đặt nó vào cấu hình container của bạn.
Tôi đã vật lộn với điều này một chút, vì vậy tôi đang thêm một phần ở đây.
Ngoài đoạn mã cấu hình được bao gồm thông qua lxc.include
tên thường đi theo tên /usr/share/lxc/config/$distro.common.conf
(nơi $distro
là tên của một bản phân phối), bạn nên kiểm tra xem có một /usr/share/lxc/config/$distro.userns.conf
hệ thống nào trên hệ thống của bạn không và bao gồm cả tên đó. Ví dụ:
lxc.include = /usr/share/lxc/config/ubuntu.common.conf
lxc.include = /usr/share/lxc/config/ubuntu.userns.conf
Hơn nữa, thêm ánh xạ ID cấp dưới:
lxc.id_map = u 0 100000 65535
lxc.id_map = g 0 100000 65535
có nghĩa là máy chủ lưu trữ UID 100000 nằm root
trong không gian tên người dùng của khách LXC.
Bây giờ hãy chắc chắn rằng các quyền là chính xác. Nếu tên của khách của bạn sẽ được lưu trữ trong biến môi trường, $lxcguest
bạn sẽ chạy như sau:
# Directory for the container
chown root:root $(lxc-config lxc.lxcpath)/$lxcguest
chmod ug=rwX,o=rX $(lxc-config lxc.lxcpath)/$lxcguest
# Container config
chown root:root $(lxc-config lxc.lxcpath)/$lxcguest/config
chmod u=rw,go=r $(lxc-config lxc.lxcpath)/$lxcguest/config
# Container rootfs
chown 100000:100000 $(lxc-config lxc.lxcpath)/$lxcguest/rootfs
chmod u=rwX,go=rX $(lxc-config lxc.lxcpath)/$lxcguest/rootfs
Điều này sẽ cho phép bạn chạy container sau lần thử đầu tiên của bạn có thể đã đưa ra một số lỗi liên quan đến quyền.
chroot
điều này có thể giúp ích, nhưng LXC kết hợp nhiều không gian tên khác nhau (UTS, mount, v.v.) để chứa toàn bộ hệ thống.
unshare
đã thực hiện điều này một cách đáng ngưỡng mộ cho bất kỳ / tất cả các không gian tên khác nhau - và thậm chí sẽ giúp bạn có một giá trị riêng, riêng biệt /proc
với một công tắc duy nhất. Nếu bạn ứng dụng duy nhất là init
và bạn chroot
là initramfs
sau đó bạn sẽ có được một container toàn trong vài giây bằng phẳng.
Để theo dõi 0xC0000022L, giải pháp của tôi hoạt động tốt với tôi, tôi đã viết một kịch bản tăng- uid-gid.pl perl để tự động hóa các thay đổi quyền sở hữu cần thiết để các tệp trong các thùng chứa LXC được ánh xạ chính xác.
Nếu không có nó, với thiết lập được đề xuất này, một tệp trong rootfs container của LXC thuộc 0 / root trên máy chủ chính, trong chính bộ chứa LXC, sẽ được ánh xạ tới 65534 / none. Để được ánh xạ tới 0 / root trong vùng chứa LXC, chúng phải thuộc 100000 trên máy chủ.
Điều này được mô tả ở đây https://yeupou.wordpress.com/2017/06/23/setting-up-lxc-containers-with-mapped-giduid/ và tập lệnh có thể được lấy trực tiếp trên gitlab https://gitlab.com /yeupou/stalag13/blob/master/usr/local/bin/increas-uid-gid.pl
lxc
không phải là điều cần thiết cho loại điều này. Bạn có thể tạo một vùng chứa không gian tên của bất kỳ loại nào bằng cách sử dụngutil-linux
công cụunshare
. Bạn có thể nhập container nói bằng cách sử dụngutil-linux
công cụnsenter
. Công cụ thứ hai cũng cho phép bạn thêm các tiến trình đang chạy vào một thùng chứa đã được tạo mà không có nó. Hỗ trợ không gian tên được triển khai trong kernel.