Debian 12 + LXD/LXC security.idmap.isolated 失败

Debian 12 + LXD/LXC security.idmap.isolated 失败

运行 LXD/LXC 且在非特权容器设置上的 Debian 12.1(6.1.0-11-amd64)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.2apt以及 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 维护者 Stéphane Graber 对此给出了很好的解释:

在 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

要禁用此功能,可以:

有一个环境变量可以通过在其 systemd 单元中添加覆盖来传递给 LXD。LXD_IDMAPPED_MOUNTS_DISABLE=1

然而,根据 Graber 先生的说法,我们不应该这样做:

好的,所以您的系统运行完全正常,并且目前的开销尽可能低,无需担心。

旧的启动前转移方法非常缓慢,而且非常危险,因为崩溃或转移特定元数据位(ACL、xattr 等)失败可能会导致容器出现安全问题。这对 CoW 文件系统来说也很糟糕,因为它实际上使容器中的每个文件看起来都已被修改,可能会重复 GB 的数据。

shiftfs(这是 Ubuntu 特有的 hack)和现在正确的 VFS idmap 转换,只需让内核在任何文件系统操作上将反向 uidmap/gidmap 应用于标记为 idmapped 的挂载即可。这是一项非常简单的操作,允许动态更改容器映射(对于隔离非常有用),允许在容器之间共享数据,并正确支持可以保存 uid/gid 的所有内容(ioctl、xattr、acl 等),从而消除遗漏某些内容的风险。

相关内容