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

Некоторые сайты Ubuntu утверждают, что это поставлется с конфигурацией для Linux (даже при том, что это не говорит так относительно упаковки). Это, кажется, является определенным для Ubuntu, и только для i686. Никакая подробная информация не предоставлена в моих беглых проверках.

Из любопытства я попробовал палку 3G Huawei (извините, неизвестная версия) на Fedora 17 некоторое время назад, и это работало из поля.

20
02.01.2015, 12:32
2 ответа

Непривилегированные контейнеры 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

Кроме того, добавьте подчиненные ID связки:

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

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

20
27.01.2020, 19:44

Чтобы продолжить работу над 0xC0000022L, чье решение мне подошло, я написал perl-скрипт increase-uid-gid.plдля автоматизации необходимых изменений прав собственности, необходимых для правильного сопоставления файлов в контейнерах 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

1
27.01.2020, 19:44

Теги

Похожие вопросы