You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux下clone/unshare命名空间隔离后能否以普通用户权限挂载CIFS?

命名空间隔离下非root权限挂载CIFS的问题解析

问题解答

1. 能否在命名空间隔离环境中以非root权限完成CIFS挂载?

不行。CIFS作为内核级文件系统,挂载操作依赖CAP_SYS_ADMIN权限,普通用户(即使在隔离命名空间内)默认不具备该权限,无法直接执行挂载。

2. 是否需要隔离命名空间内的root权限才能成功挂载?

是的。必须通过CLONE_NEWUSER创建用户命名空间,将宿主环境的普通用户映射为命名空间内的root(UID 0),此时该进程在命名空间内会拥有CAP_SYS_ADMIN权限,再结合CLONE_NEWNS挂载命名空间,就能合法执行CIFS挂载操作。

你的代码问题分析

你当前的代码已经尝试了CLONE_NEWUSER+CLONE_NEWNS的组合,但仍出现Operation not permitted错误,可能存在以下问题:

  • 挂载命名空间未完全隔离:新创建的挂载命名空间默认会继承父环境的挂载点,需确保挂载点的隔离性,避免父环境属性干扰
  • CIFS依赖缺失:需确保系统已安装cifs-utils工具包,内核已加载cifs模块(可通过modprobe cifs手动加载)
  • 网络配置(若隔离网络命名空间):如果后续添加CLONE_NEWNET,需在新命名空间内配置网络(如veth对、IP地址),否则无法访问远程SMB服务器

修改后的示例代码

#define _GNU_SOURCE
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mount.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sched.h>
#include <errno.h>

void write_to_file(const char *path, const char *format, ...) {
    FILE *fp = fopen(path, "w");
    if (!fp) {
        perror("fopen");
        exit(EXIT_FAILURE);
    }

    va_list args;
    va_start(args, format);
    if (vfprintf(fp, format, args) < 0) {
        perror("vfprintf");
        exit(EXIT_FAILURE);
    }
    fclose(fp);
    va_end(args);
}

int create_directory_if_needed(const char *path) {
    if (mkdir(path, 0777) == -1 && errno != EEXIST) {
        perror("mkdir");
        return -1;
    }
    return 0;
}

static int setup_mount_environment() {
    const char *mount_point = "/tmp/test/smb_share";
    const char *smb_share = "//192.168.1.1/shared_folder";

    if (create_directory_if_needed(mount_point)) {
        return -1;
    }
    printf("[*] do mount!\n");
    // 根据SMB共享配置调整参数,sec=none适配guest访问
    if (mount(smb_share, mount_point, "cifs", 0,
            "username=guest,password=,uid=1000,gid=1000,vers=3.0,sec=none") == -1) {
        int saved_errno = errno;  
        printf("[DEBUG] Mount failed: %s\n", strerror(saved_errno));  
        system("dmesg | tail -n 10");  
        return -1;
    }

    return 0;
}

int main() {
    printf("[*] Unsharing namespaces...\n");
    
    if (unshare(CLONE_NEWUSER | CLONE_NEWNS) == -1) {
        perror("unshare failed");
        return EXIT_FAILURE;
    }

    printf("[*] Setting UID/GID mappings...\n");
    write_to_file("/proc/self/uid_map", "0 %d 1", getuid());
    write_to_file("/proc/self/setgroups", "deny");
    write_to_file("/proc/self/gid_map", "0 %d 1", getgid());

    // 确保挂载命名空间完全隔离
    if (mount("", "/", NULL, MS_SLAVE | MS_REC, NULL) == -1) {
        perror("mount --make-rslave / failed");
        return EXIT_FAILURE;
    }

    printf("[*] Attempting SMB mount...\n");
    if (setup_mount_environment() == -1) {
        return EXIT_FAILURE;
    }

    printf("[*] SMB mount success!\n");
    // 保持命名空间存活以便验证挂载结果
    sleep(30);
    umount("/tmp/test/smb_share");
    return EXIT_SUCCESS;
}

额外注意事项

  • 编译时需链接pthread库:gcc your_code.c -o cifs_mount -lpthread
  • 若SMB服务器需要认证,需调整username、password及sec参数(如sec=ntlmv2)
  • 挂载后的文件权限由uid、gid参数控制,建议设置为宿主环境的普通用户ID,避免权限混乱

内容的提问来源于stack exchange,提问作者김한서

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 17:10:56