Debian 12.1 (6.1.0-11-amd64) que ejecuta LXD/LXC y en una configuración de contenedor sin privilegios security.idmap.isolated=true
parece no poder actualizar el propietario/grupo de los archivos del contenedor.
Aquí hay un ejemplo:
# 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
Ahora, si enumero los archivos en el volumen contenedor, obtendré que todos son propiedad del root
usuario host:
# 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
Probé varias versiones de LXD/LXC. Esto sucede tanto con la versión 5.0.2 apt
como con la 4.0 y 5.17 (la más reciente) desde snap
.
Curiosamente, tengo otro Debian 10 (4.19.0-25-amd64) ejecutándose y un LXD 4 anterior a partir de snap
ahí, las cosas funcionan como se esperaba:
# 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
Como puede ver en estos sistemas, todos los archivos son propiedad de 1065536:1065536
.
Actualizar:
Intenté explorar los mapas lxc config show debian
en ambas máquinas y vi esto:
Máquina que ejecuta 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}]'
Máquina que ejecuta 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: '[]'
Actualizar:
También probé una nueva instalación deDebian 11 (5.10.0-25-amd64) y funciona como se esperaba:
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
¿Por qué no se pobló volatile.last_state.idmap: '[]'
? Al igual que con Debian 10 y 11, aparentemente esto puede estar relacionado con el nuevo kernel y/o su configuración.
¿Cómo puedo arreglarlo? Gracias.
Respuesta1
Aparentemente, esto es por diseño una característica de los núcleos más nuevos. Aquí hay una buena explicación de Stéphane Graber, mantenedor de LXC:
Antes de que VFS idmap estuviera disponible, necesitábamos solucionar la propiedad de los archivos haciendo que LXD reescribiera manualmente el propietario de cada archivo en el disco. Eso es lo que estás mostrando aquí en un kernel más antiguo.
En los kernels más nuevos, esto ya no es necesario ya que podemos hacer que el kernel mantenga los permisos en el disco sin cambios y simplemente los cambie dentro del kernel para que la propiedad se vea correcta dentro del contenedor.
Lo que estás mostrando arriba parece una configuración que funciona perfectamente en un kernel que admite VFS idmap.
De hecho, podría configurar esto en la máquina host:
root@vm-debian-12-cli:~# lxc info | grep 'shift\|idmap'
- storage_shifted
idmapped_mounts: "true"
shiftfs: "false"
idmapped_mounts_v2: "true"
Y dentro de los contenedores, el punto de montaje raíz también se muestra como idmapped
(última línea):
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
Para desactivar esto se puede:
Hay una variable de entorno que se puede pasar a LXD agregando una anulación en su unidad systemd. LXD_IDMAPPED_MOUNTS_DISABLE=1
Sin embargo, y según el señor Graber no deberíamos hacer eso:
Bien, entonces su sistema está funcionando perfectamente normalmente y con la menor sobrecarga posible en este momento, no hay nada de qué preocuparse.
El antiguo método de cambio previo al inicio era muy lento y muy riesgoso, ya que una falla o falla al cambiar un bit particular de metadatos (ACL, xattr,…) podría generar un problema de seguridad con el contenedor. También fue horrible para los sistemas de archivos CoW, ya que efectivamente hacía que pareciera que cada archivo en el contenedor había sido modificado, duplicando potencialmente GB de datos.
shiftfs (que era un truco específico de Ubuntu) y ahora el cambio de mapa de id de VFS adecuado, simplemente haga que el kernel aplique el uidmap/gidmap inverso en cualquier operación del sistema de archivos a un montaje que esté marcado como idmapped. Es una operación extremadamente trivial de realizar, permite cambios dinámicos en los mapas de contenedores (muy útil para aislados), permite compartir datos entre contenedores y admite adecuadamente todo lo que pueda contener un uid/gid (ioctl, xattr, acl,…), por lo que eliminando el riesgo de haber pasado por alto algo.