Что такое непривилегированный контейнер LXC?


20

Что это значит, если контейнер Linux (контейнер LXC) называется «непривилегированным»?

Ответы:


20

Непривилегированные контейнеры LXC - это те, которые используют пространства имен пользователей ( ). Т.е. функции ядра, которая позволяет отобразить диапазон UID на хосте в пространство имен, внутри которого может снова существовать пользователь с UID 0.

Вопреки моему первоначальному восприятию непривилегированных контейнеров LXC на некоторое время, это не означает, что контейнер должен принадлежать непривилегированному пользователю хоста. Это только одна возможность.

Актуальным является:

  1. что диапазон подчиненных UID и GID определен для пользователя хоста ( usermod [-v|-w|--add-sub-uids|--add-sub-gids])
  2. ... и что этот диапазон отображается в конфигурации контейнера ( lxc.id_map = ...)

Таким образом, даже rootвладельцы непривилегированных контейнеров могут владеть, поскольку эффективные UID контейнерных процессов на хосте окажутся в пределах диапазона, определенного сопоставлением.

Тем не менее, rootвы должны сначала определить подчиненные идентификаторы. В отличие от пользователей, созданных с помощью adduser, rootне будет иметь диапазон подчиненных идентификаторов, определенных по умолчанию.

Также имейте в виду, что полный диапазон, который вы предоставляете, находится в вашем распоряжении, так что вы можете иметь 3 контейнера со следующими строками конфигурации (показано только отображение UID):

  1. lxc.id_map = u 0 100000 100000
  2. lxc.id_map = u 0 200000 100000
  3. lxc.id_map = u 0 300000 100000

Предполагая, что ему rootпринадлежат подчиненные UID между 100000 и 400000. Вся документация, которую я нашел, предлагает использовать 65536 подчиненных идентификаторов на контейнер, хотя некоторые используют 100000, чтобы сделать его более читабельным для человека.

Другими словами: вам не нужно назначать одинаковый диапазон для каждого контейнера.

Имея более 4 миллиардов (~ 2^32) возможных идентификаторов подчиненных, это означает, что вы можете быть щедрыми при передаче подчиненных диапазонов вашим пользователям хоста.

Непривилегированный контейнер принадлежит и запускается пользователем root

Втирать это снова. Непривилегированный гость 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

Это должно позволить вам запустить контейнер после того, как ваша первая попытка могла привести к ошибкам, связанным с разрешениями.


4
Хороший ответ - но lxcэто не обязательно для такого рода вещей. Вы можете создать контейнер пространства имен любого вида, используя util-linuxинструмент unshare. Вы можете войти в указанный контейнер с помощью util-linuxинструмента nsenter. Последний инструмент также позволяет добавлять запущенные процессы в уже созданный контейнер без него. Поддержка пространства имен реализована в ядре.
mikeserv

4
@mikeserv: вы имеете в виду, что вам не нужен LXC, чтобы использовать userns ? Я знал это. Я также знаю, что у Docker теперь есть собственная библиотека, использующая эти возможности. Но как бы вы упаковали всю систему без помощи средств, предлагаемых LXC? И зачем ты это делаешь? Я имею в виду, чтобы содержать одно приложение и в сочетании с chrootэтим может помочь, но LXC объединяет различные пространства имен (UTS, mount и т. Д.) Для контейнеризации всей системы.
0xC0000022L

2
Ну ... Как я unshareуже сказал, он уже делает это превосходно для любого / всех различных пространств имен - и даже даст вам отдельное частное /procмонтирование с одним кли-переключателем. Если одно приложение является initи вашим chrootявляется initramfsто вы получите весь контейнер в секундах квартиру.
mikeserv

0

Для прослеживания на 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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.