我观察到以下几点:
作为 1 号 shell 中的非特权用户:
user@box:~$ sysctl kernel.unprivileged_userns_clone
kernel.unprivileged_userns_clone = 1
user@box:~$ unshare --mount --user
nobody@box:~$ echo $$
18655
以 root 身份进入 2 号 shell:
root@box:~# mkdir -p /tmp/myns
root@box:~# touch /tmp/myns/{user,mnt}
root@box:~# mount --bind /proc/18655/ns/user /tmp/myns/user
root@box:~# mount --bind /proc/18655/ns/mnt /tmp/myns/mnt
mount: /tmp/myns/mnt: wrong fs type, bad option, bad superblock on /proc/18655/ns/mnt, missing codepage or helper program, or other error.
该错误令人惊讶:我无法将安装命名空间绑定安装到文件,但我可以将用户命名空间绑定安装到文件?为什么会这样,我怎样才能让这个挂载命名空间可供非特权用户使用user
?
为什么我想要这个:为了测试程序,我想覆盖~user
一个临时文件系统,最初共享原始内容。它可以由 root 按照以下方式设置
tmp='/tmp/GAtcNNeSfM8b'
mkdir -p "$tmp"
mount -t tmpfs -o size=100m tmpfs "$tmp"
mkdir -p "${tmp}/"{upper,work,lower}
mount --bind -o ro /home/user "${tmp}/lower"
unshare -m
mount -t overlay -o"lowerdir=${tmp}/lower,upperdir=${tmp}/upper,workdir=${tmp}/work" overlay /home/user
touch /tmp/namespace
mount --bind /proc/self/ns/mnt /tmp/namespace
但最后一行失败了。
目的是非特权用户可以nsenter --mount=/tmp/namespace
看到与以前相同的系统,只是对的更改/home/user
不是持久的。实际上,我什至不想取消共享用户名称空间。
我有意识地试图避免 LXC、Docker 甚至 VirtualBox 的开销。我认为使用 Linux 标准工具应该可以实现这一点。
更新:我正在运行最新的 ArchLinux,
$ uname -r
5.0.10-arch1-1-ARCH
答案1
鉴于它只影响挂载命名空间,我非常怀疑这是由于其中之一环路预防检查用于挂载命名空间。我不认为这与链接中讨论的情况完全相同,因为unshare --mount
默认将安装传播设置为private
,即禁用它。
但是,为了防止某些竞争条件,我认为完全正确可能需要您将挂载命名空间挂载到具有private
挂载传播的挂载内。我还认为如果您使用unbindable
. (我认为unbindable
已经包括了所有的影响private
)。
即,将挂载命名空间挂载到使用以下命令准备的目录中:
mount --bind /var/local/lib/myns/ /var/local/lib/myns/
mount --make-unbindable /var/local/lib/myns/
总的来说,我认为这是最安全的方法,可以避免触发此类问题。
我的比赛条件是假设的。我不希望你大部分时间都能击中它。所以我不知道你的实际问题是什么。