如何使命名空间在 chrooted/NEWPID 进程中可见

如何使命名空间在 chrooted/NEWPID 进程中可见

我使用CLONE_NEWPID和创建一个新流程chroot/mnt/

除此之外,我使用该ip netns命令创建一个新的 netns。

例如

ip netns add test1

知道如何让 chrooted 进程或其子进程看到这个新的 netns 吗?

根据我在 strace 上看到的内容,我尝试了:

touch /mnt/var/run/netns/test1
ip netns exec test1 mount --bind /proc/self/ns/net /mnt/var/run/netns/test1

但没有成功

答案1

请注意,这/var/run是一个符号链接/run,应该提前“解析”或可能使用各种命令/mnt/var/run指向。/run

乍一看,来自初始命名空间的这个更简单的命令(而不是像最后一个注释中所解释的那样永远无法工作的 OP)应该足以允许ip netns exec从 chroot 工作PID命名空间:

mount --bind /run/netns/test1 /mnt/run/netns/test1

但事实并非如此。这与PID命名空间,但要chroot。实际上,当不切换到新的时,整个问题是一样的PID完全没有命名空间。

ip netns exec不只操纵网络命名空间,但也必须操作命名空间和使用安装(2)系统调用的原因我在 SF Q/A 中解释过:无法创建嵌套网络命名空间


问题:chroot

/proc应安装在 chroot 内才能正确操作。至少/proc从 chroot 中安装后,使用strace可以看到ip netns exec test1 ...将进入一个新的命名空间并无法重新挂载/

getuid()                                = 0
openat(AT_FDCWD, "/run/netns/test1", O_RDONLY|O_CLOEXEC) = 3
setns(3, CLONE_NEWNET)                  = 0
close(3)                                = 0
unshare(CLONE_NEWNS)                    = 0
mount("", "/", 0x5595a749373f, MS_REC|MS_SLAVE, NULL) = -1 EINVAL (Invalid argument)
write(2, "\"mount --make-rslave /\" failed: "..., 49) = 49
exit_group(-1)                          = ?
+++ exited with 255 +++

重新安装失败并显示EINVAL:因为chroot/不再是挂载点。

请注意,网络命名空间部分本身没有问题。例如,从 chroot 端执行此操作:

nsenter --net=/run/netns/test1 ip link

将成功并显示测试1的网络接口,但如果需要的话,不会/sys/像会做的那样切换可用的相关条目(如我之前的链接中所述)。ip netns exec


解决方案:在自身之上添加绑定挂载

修复:绑定挂载chroot以自身为目标,强制将其变成挂载点,最好是在私有模式下,以避免交互(特别是当系统转为/共享)之前做chroot

我用 shell 命令重现了下面的工作设置。

我省略了一些样板,比如可能从 tmpfs 等安装/run(又名 init ),但实际上应该从 chroot 内安装。/mnt/run/proc

第 1 项中的第一个:

~# unshare --fork --pid bash
~# echo $$
1
~# mount --bind --make-private /mnt /mnt
~# chroot /mnt bash
/# mount -t proc proc /proc

那么在一个不相关的术语2中:

 ~# ip netns add test1
 ~# mkdir -p /mnt/run/netns
 ~# touch /mnt/run/netns/test1
 ~# mount --bind /run/netns/test1 /mnt/run/netns/test1

再次在第 1 学期:

/# ip netns exec test1 ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noqueue state DOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

笔记:

  • 如前所述,此问题与PID命名空间。删除该命令unshare --fork --pid bash将解决仅使用chroot没有PID命名空间。

  • 安装命令应该绝不从命令中运行ip netns exec。请记住,它ip netns exec本身会创建一个临时安装命名空间。结束时无论坐骑完成什么都会消失ip netns exec。这在我之前的链接中也有解释。这样做仍然可以:

    nsenter --net=/run/netns/test1 mount --bind /proc/self/ns/net /mnt/var/run/netns/test1
    

    但当然不需要,因为它是完全相同的实体,可以通过在国家科学基金虚拟文件系统:

    ~# stat -f -c %T /run/netns/test1; stat -c %i /run/netns/test1
    nsfs
    4026533129
    ~# nsenter --net=/run/netns/test1 sh -c 'stat -f -L -c %T /proc/self/ns/net; stat -L -c %i /proc/self/ns/net'
    nsfs
    4026533129
    

相关内容