You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何让Linux系统中多个用户透明地拥有目录及其内容的所有权

如何让Linux系统中多个用户透明地拥有目录及其内容的所有权

我完全懂你的需求——你要的不是那种传统的多用户权限共享,而是让指定的几个用户(比如oli和jim)访问同一个目录时,每个用户都能看到文件是属于自己的,而且还想要内核级的高效方案,不想用FUSE那种用户态的对吧?刚好Linux内核里有几个专门做UID/GID映射的机制,完美匹配你的场景,我给你说两个最实用的:

方案1:使用ShiftFS(内核级,优先推荐)

ShiftFS是Linux内核专门为UID/GID动态映射开发的文件系统,一开始是给LXC容器做的,现在不少发行版(比如Ubuntu 20.04及以上)已经默认支持了。它能在挂载时自动转换文件的UID/GID,完全满足你“每个用户看文件都是自己的”需求,而且性能和原生文件系统几乎没差别。

操作步骤:

  1. 先确认内核支持ShiftFS
    运行modinfo shiftfs,如果能输出模块信息,说明你的系统支持;如果没有,要么换个支持的发行版,要么重新编译内核打开ShiftFS的开关。

  2. 准备共享目录的实际所有权
    先给目标共享目录/shared-dir设置一个统一的“幕后”UID/GID,比如新建一个专门的共享用户(UID设为2000),然后把目录权限改成这个用户:

    useradd -u 2000 shared-user
    chown -R shared-user:shared-user /shared-dir
    
  3. 为每个用户单独挂载映射
    给每个需要访问的用户创建专属挂载点,然后用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-shared
      
      这里的uidmap=2000:1000:1意思是:把宿主系统中UID为2000的文件,在这个挂载点里映射成UID 1000(也就是oli的UID),GID同理。这样oli打开/home/oli/my-shared时,所有文件看起来都是自己的。
    • 给jim(假设UID是1001)挂载:
      mkdir -p /home/jim/my-shared
      mount -t shiftfs -o uidmap=2000:1001:1,gidmap=2000:1001:1 /shared-dir /home/jim/my-shared
      
      同样,jim看到的所有文件都会显示成自己的UID。
  4. 让挂载永久生效
    把挂载命令加到/etc/fstab里,这样重启后也能自动挂载:
    比如oli的条目:

    /shared-dir /home/oli/my-shared shiftfs uidmap=2000:1000:1,gidmap=2000:1000:1 0 0
    

    jim的条目照葫芦画瓢改一下UID就行。

方案2:用户命名空间+绑定挂载(备选方案)

如果你的系统不支持ShiftFS,用户命名空间也是个内核级的选择,就是配置稍微麻烦点。用户命名空间能给每个用户创建一个隔离的环境,把里面的UID/GID和宿主系统的真实ID做映射。

操作步骤:

  1. 开启用户命名空间支持
    运行sysctl kernel.unprivileged_userns_clone,如果输出是1就已经开启了;如果是0,临时开启用:

    sysctl -w kernel.unprivileged_userns_clone=1
    

    要永久生效的话,把kernel.unprivileged_userns_clone=1加到/etc/sysctl.conf里,然后运行sysctl -p生效。

  2. 给每个用户写启动脚本
    比如给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

火山引擎 最新活动