Debian 12 + LXD/LXC security.idmap.isolated не работает

Debian 12 + LXD/LXC security.idmap.isolated не работает

В Debian 12.1 (6.1.0-11-amd64) под управлением LXD/LXC и с непривилегированными настройками контейнера, security.idmap.isolated=trueпо-видимому, не удается обновить владельца/группу файлов контейнера.

Вот пример:

# lxc launch images:debian/12 debian
(...)

# lxc config get debian volatile.idmap.base
296608

# lxc stop debian
Error: The instance is already stopped

# lxc config set debian security.idmap.isolated true

# lxc config get debian security.idmap.isolated
true

# lxc start debian

Теперь, если я перечислю файлы на томе контейнера, то все они принадлежат rootпользователю хоста:

# ls -la /mnt/NVME1/lxd/containers/debian/rootfs/
total 24
drwxr-xr-x 1 root   root  154 Sep  5 06:28 .
d--x------ 1 296608 root   78 Sep  5 15:59 ..
lrwxrwxrwx 1 root   root    7 Sep  5 06:25 bin -> usr/bin
drwxr-xr-x 1 root   root    0 Jul 14 17:00 boot
drwxr-xr-x 1 root   root    0 Sep  5 06:28 dev
drwxr-xr-x 1 root   root 1570 Sep  5 06:28 etc

Я пробовал несколько версий LXD/LXC. Это происходит как с 5.0.2, aptтак и с 4.0 и 5.17 (последняя) из snap.

Достаточно интересно, что у меня запущен еще один Debian 10 (4.19.0-25-amd64) и более старая версия LXD 4, с snapкоторой все работает так, как и ожидалось:

# ls -la /mnt/NVME1/lxd/containers/debian/rootfs/
total 0
drwxr-xr-x 1 1065536 1065536  138 Oct 29  2020 .
d--x------ 1 1065536 root      78 Oct 14  2020 ..
drwxr-xr-x 1 1065536 1065536 1328 Jul 24 19:07 bin
drwxr-xr-x 1 1065536 1065536    0 Sep 19  2020 boot
drwxr-xr-x 1 1065536 1065536    0 Oct 14  2020 dev
drwxr-xr-x 1 1065536 1065536 1716 Jul 24 19:08 etc

Как вы можете видеть, в этой системе все файлы принадлежат 1065536:1065536.


Обновлять:

Я попробовал изучить карты на lxc config show debianобеих машинах и увидел следующее:

Машина под управлением Debian 10:

security.idmap.isolated: "true"
(...)
volatile.idmap.base: "1065536"
volatile.idmap.current: '[{"Isuid":true,"Isgid":false,"Hostid":1065536,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":1065536,"Nsid":0,"Maprange":65536}]'
volatile.idmap.next: '[{"Isuid":true,"Isgid":false,"Hostid":1065536,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":1065536,"Nsid":0,"Maprange":65536}]'
volatile.last_state.idmap: '[{"Isuid":true,"Isgid":false,"Hostid":1065536,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":1065536,"Nsid":0,"Maprange":65536}]'

Машина под управлением Debian 12:

security.idmap.isolated: "true"
(...)
volatile.idmap.base: "231072"
volatile.idmap.current: '[{"Isuid":true,"Isgid":false,"Hostid":231072,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":231072,"Nsid":0,"Maprange":65536}]'
volatile.idmap.next: '[{"Isuid":true,"Isgid":false,"Hostid":231072,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":231072,"Nsid":0,"Maprange":65536}]'
volatile.last_state.idmap: '[]'

Обновлять:

Я также попробовал новую установкуDebian 11 (5.10.0-25-amd64) и он работает как и ожидалось:

root@vm-debian-11-cli:~# ls -la /mnt/NVME1/lxd/containers/debian/rootfs/
total 24
drwxr-xr-x 1 1065536 1065536  154 Sep  6 06:28 .
d--x------ 1 1065536 root      78 Sep  6 15:31 ..
lrwxrwxrwx 1 1065536 1065536    7 Sep  6 06:25 bin -> usr/bin
drwxr-xr-x 1 1065536 1065536    0 Jul 14 17:00 boot
drwxr-xr-x 1 1065536 1065536    0 Sep  6 06:28 dev
drwxr-xr-x 1 1065536 1065536 1570 Sep  6 06:28 etc

Почему он не заполнился volatile.last_state.idmap: '[]'? Как и в случае с Debian 10 и 11, по-видимому, это может быть связано с новым ядром и/или его конфигурацией.

Как это исправить? Спасибо.

решение1

Видимо, это изначально заложено в новых ядрах. Вот хорошее объяснение от Стефана Грабера, сопровождающего LXC:

До того, как VFS idmap стал доступен, нам приходилось обходить владение файлами, заставляя LXD вручную переписывать владельца каждого отдельного файла на диске. Это то, что вы здесь показываете на старом ядре.

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

То, что вы показываете выше, выглядит как идеально работающая настройка на ядре, которое поддерживает VFS idmap.

Я действительно мог бы настроить это на хост-машине:

root@vm-debian-12-cli:~# lxc info | grep 'shift\|idmap'
- storage_shifted
    idmapped_mounts: "true"
    shiftfs: "false"
    idmapped_mounts_v2: "true"

А внутри контейнеров корневая точка монтирования также отображается как idmapped(последняя строка):

root@debian:~# cat /proc/self/uid_map
         0     231072      65536

root@debian:~# cat /proc/self/gid_map
         0     231072      65536

root@debian:~# cat /proc/self/mountinfo
490 460 0:24 /@rootfs/mnt/NVME1/lxd/containers/debian/rootfs / rw,relatime,idmapped shared:251 master:1 - btrfs /dev/sda1 rw,space_cache=v2,user_subvol_rm_allowed,subvolid=259,subvol=/@rootfs/mnt/NVME1/lxd/containers/debian

Чтобы отключить это, можно:

Существует переменная среды, которую можно передать в LXD, добавив переопределение в ее модуль systemd. LXD_IDMAPPED_MOUNTS_DISABLE=1

Однако, по словам г-на Грабера, нам не следует этого делать:

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

Старый метод смещения перед запуском был очень медленным и очень рискованным, поскольку сбой или неудача при смещении определенного бита метаданных (ACL, xattr, …) могли привести к проблеме безопасности с контейнером. Это также было ужасно для файловых систем CoW, поскольку фактически создавало видимость того, что каждый файл в контейнере был изменен, что потенциально дублировало ГБ данных.

shiftfs (который был хаком, специфичным для Ubuntu) и теперь правильное смещение VFS idmap, просто заставляют ядро ​​применять обратный uidmap/gidmap к любой операции файловой системы для монтирования, помеченного как idmapped. Это чрезвычайно тривиальная операция для выполнения, позволяет динамически изменять карты контейнеров (очень полезно для изолированных), позволяет обмениваться данными между контейнерами и должным образом поддерживает все, что может содержать uid/gid (ioctl, xattr, acl, …), что устраняет риск что-то упустить.

Связанный контент