如何让Linux系统中多个用户透明地拥有目录及其内容的所有权
我完全懂你的需求——你要的不是那种传统的多用户权限共享,而是让指定的几个用户(比如oli和jim)访问同一个目录时,每个用户都能看到文件是属于自己的,而且还想要内核级的高效方案,不想用FUSE那种用户态的对吧?刚好Linux内核里有几个专门做UID/GID映射的机制,完美匹配你的场景,我给你说两个最实用的:
方案1:使用ShiftFS(内核级,优先推荐)
ShiftFS是Linux内核专门为UID/GID动态映射开发的文件系统,一开始是给LXC容器做的,现在不少发行版(比如Ubuntu 20.04及以上)已经默认支持了。它能在挂载时自动转换文件的UID/GID,完全满足你“每个用户看文件都是自己的”需求,而且性能和原生文件系统几乎没差别。
操作步骤:
先确认内核支持ShiftFS:
运行modinfo shiftfs,如果能输出模块信息,说明你的系统支持;如果没有,要么换个支持的发行版,要么重新编译内核打开ShiftFS的开关。准备共享目录的实际所有权:
先给目标共享目录/shared-dir设置一个统一的“幕后”UID/GID,比如新建一个专门的共享用户(UID设为2000),然后把目录权限改成这个用户:useradd -u 2000 shared-user chown -R shared-user:shared-user /shared-dir为每个用户单独挂载映射:
给每个需要访问的用户创建专属挂载点,然后用ShiftFS做UID/GID映射:- 给oli(假设他的UID是1000)挂载:
这里的mkdir -p /home/oli/my-shared mount -t shiftfs -o uidmap=2000:1000:1,gidmap=2000:1000:1 /shared-dir /home/oli/my-shareduidmap=2000:1000:1意思是:把宿主系统中UID为2000的文件,在这个挂载点里映射成UID 1000(也就是oli的UID),GID同理。这样oli打开/home/oli/my-shared时,所有文件看起来都是自己的。 - 给jim(假设UID是1001)挂载:
同样,jim看到的所有文件都会显示成自己的UID。mkdir -p /home/jim/my-shared mount -t shiftfs -o uidmap=2000:1001:1,gidmap=2000:1001:1 /shared-dir /home/jim/my-shared
- 给oli(假设他的UID是1000)挂载:
让挂载永久生效:
把挂载命令加到/etc/fstab里,这样重启后也能自动挂载:
比如oli的条目:/shared-dir /home/oli/my-shared shiftfs uidmap=2000:1000:1,gidmap=2000:1000:1 0 0jim的条目照葫芦画瓢改一下UID就行。
方案2:用户命名空间+绑定挂载(备选方案)
如果你的系统不支持ShiftFS,用户命名空间也是个内核级的选择,就是配置稍微麻烦点。用户命名空间能给每个用户创建一个隔离的环境,把里面的UID/GID和宿主系统的真实ID做映射。
操作步骤:
开启用户命名空间支持:
运行sysctl kernel.unprivileged_userns_clone,如果输出是1就已经开启了;如果是0,临时开启用:sysctl -w kernel.unprivileged_userns_clone=1要永久生效的话,把
kernel.unprivileged_userns_clone=1加到/etc/sysctl.conf里,然后运行sysctl -p生效。给每个用户写启动脚本:
比如给oli写一个脚本/home/oli/enter-shared.sh:#!/bin/bash unshare -U -r --mount-proc bash -c " mount --bind /shared-dir /home/oli/my-shared chown -R 0:0 /home/oli/my-shared exec bash "给脚本加执行权限:
chmod +x /home/oli/enter-shared.sh。
当oli运行这个脚本时,会进入一个用户命名空间,里面的root(UID0)会映射成宿主的oli(UID1000),绑定挂载后的目录里所有文件都会显示成UID0(也就是oli自己的ID)。
给jim也写个类似的脚本,改一下路径就行。
这个方案需要用户通过脚本进入命名空间才能看到映射后的所有权,不如ShiftFS直接挂载就能用方便,所以优先选ShiftFS。
关于FUSE的bindfs
你提到了FUSE,虽然bindfs也能实现类似的功能(比如bindfs -u oli -g oli /shared-dir /home/oli/my-shared),但它是用户态的文件系统,性能比内核级的方案差不少,如果你对性能有要求,还是优先考虑上面的内核方案。
备注:内容来源于stack exchange,提问作者Oli




