Что это значит, если контейнер 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
). Если они есть (что обычно означает, что они были созданы пользователем root и запущены пользователем root), это совсем другая история.
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, решение которой работал отлично для меня, я написал increase-uid-gid.pl сценарий PERL , чтобы автоматизировать необходимые изменения собственности требуется для того , файлы в пределах Lxc контейнеров корректно отображаются.
Без этого при этой предложенной настройке файл в rootfs контейнера LXC, принадлежащий 0 / root на главном хосте, в самом контейнере LXC будет сопоставлен с 65534 / nobody. Чтобы быть сопоставленным с 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
. Последний инструмент также позволяет добавлять запущенные процессы в уже созданный контейнер без него. Поддержка пространства имен реализована в ядре.