Що це означає, якщо контейнер Linux (контейнер LXC) називається "непривілейованим"?
Що це означає, якщо контейнер Linux (контейнер LXC) називається "непривілейованим"?
Відповіді:
Непривілейовані контейнери LXC - це ті, що використовують простори імен користувачів ( userns ). Тобто функція ядра, яка дозволяє відобразити діапазон UID на хості в простір імен, всередині якого знову може існувати користувач з UID 0.
Всупереч моєму первісному сприйняттю непривілейованих контейнерів LXC деякий час, це не означає, що контейнер повинен належати непривілейованому користувачеві хосту. Це лише одна можливість.
Релевантним є:
usermod [-v|-w|--add-sub-uids|--add-sub-gids]
)lxc.id_map = ...
)Таким чином, навіть root
можна володіти непривілейованими контейнерами, оскільки ефективні UID контейнерних процесів на хості виявляться в межах діапазону, визначеного відображенням.
Однак для початку root
потрібно визначити підпорядковані ідентифікатори. На відміну від користувачів, створених через adduser
, root
не матиме діапазон підпорядкованих ідентифікаторів, визначених за замовчуванням.
Також майте на увазі, що весь набір, який ви надаєте, є у вашому розпорядженні, щоб у вас могли бути 3 контейнери із такими рядками конфігурації (показано лише відображення UID):
lxc.id_map = u 0 100000 100000
lxc.id_map = u 0 200000 100000
lxc.id_map = u 0 300000 100000
якщо припустити, що root
належить йому підпорядковані UID між 100000 і 400000. Уся документація, яку я знайшов, пропонує використовувати 65536 підпорядкованих ідентифікаторів на контейнер, деякі використовують 100000, щоб зробити його більш зрозумілим для людини.
Іншими словами: Вам не потрібно призначати однаковий діапазон кожному контейнеру.
Маючи понад 4 мільярди (~ 2^32
) можливих підпорядкованих ідентифікаторів, це означає, що ви можете бути щедрими в роботі з підпорядкованими діапазонами для своїх хостових користувачів.
Потерти це знову. Непривілейований гість LXC не потребує керування непривілейованим користувачем на хості.
Налаштування вашого контейнера за допомогою підпорядкованого UID / GID-відображення таким чином:
lxc.id_map = u 0 100000 100000
lxc.id_map = g 0 100000 100000
там, де користувач root
хоста має власність даного підпорядкованого діапазону ідентифікаторів, дозволить вам обмежити гостей ще краще.
Однак є одна важлива додаткова перевага в такому сценарії (і так, я переконався, що він працює): ви можете автозапустити контейнер при запуску системи.
Зазвичай під час пошуку в Інтернеті інформації про LXC вам скажуть, що неможливо автозапустити непривілейованого гостя LXC. Однак це справедливо за замовчуванням лише для тих контейнерів, які не знаходяться в загальносистемному сховищі для контейнерів (зазвичай щось подібне /var/lib/lxc
). Якщо вони є (що, як правило, означає, що вони були створені коренем і розпочаті під корінь), це зовсім інша історія.
lxc.start.auto = 1
зробить цю роботу досить непогано, як тільки ви помістите її в конфігурацію контейнера.
Я трохи боровся з цим, тому додаю тут розділ.
На додаток до фрагменту конфігурації, включеному в lxc.include
який, як правило, походить ім'я /usr/share/lxc/config/$distro.common.conf
(де $distro
назва імені дистрибутива), слід перевірити, чи є /usr/share/lxc/config/$distro.userns.conf
у вашій системі також і включити це. Наприклад:
lxc.include = /usr/share/lxc/config/ubuntu.common.conf
lxc.include = /usr/share/lxc/config/ubuntu.userns.conf
Крім того, додайте відображення підпорядкованих ідентифікаторів:
lxc.id_map = u 0 100000 65535
lxc.id_map = g 0 100000 65535
що означає , що хост UID 100000 знаходиться root
всередині робочих просторів імен гостя LXC.
Тепер переконайтеся, що дозволи були правильними. Якщо ім’я вашого гостя буде збережено в змінній оточення $lxcguest
, виконайте такі дії:
# 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
Це повинно дозволяти запускати контейнер після першої спроби, можливо, помилки, пов’язані з дозволом.
chroot
цим може допомогти, але LXC поєднує різні простори імен (UTS, mount тощо) для контейнеру всієї системи.
unshare
вже сказав, це вже чудово робить для будь-якого / всіх різних просторів імен - і навіть отримає вам окреме, приватне /proc
кріплення з одним кліп-перемикачем. Якщо ваша одиночна заявка є init
і ваша chroot
, initramfs
то ви отримуєте весь контейнер за кілька секунд.
Для подальшої роботи на 0xC0000022L, рішення якої для мене справно працювало, я написав сценарій perl збільшення- uid-gid.pl для автоматизації необхідних змін власності, необхідних для того, щоб файли в контейнерах LXC були правильно відображені.
Без цього, при запропонованій установці, файл у коренях контейнера LXC, що належить 0 / root, на головному хості, в межах самого контейнера LXC буде відображено до 65534 / none. Щоб бути відображеними на 0 / root у контейнері LXC, вони повинні належати 100000 хосту.
Про це описано тут https://yeupou.wordpress.com/2017/06/23/setting-up-lxc-containers-with-mapped-giduid/, а сценарій можна отримати безпосередньо на gitlab https://gitlab.com /yeupou/stalag13/blob/master/usr/local/bin/increase-uid-gid.pl
lxc
це не є необхідністю для подібних речей. Ви можете створити контейнер простору імен будь-якого типу за допомогоюutil-linux
інструментуunshare
. Ви можете ввести зазначений контейнер за допомогоюutil-linux
інструментуnsenter
. Останній інструмент також дозволяє додавати запущені процеси до вже створеного контейнера без нього. Підтримка простору імен реалізована в ядрі.