首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
V2EX  ›  问与答

创建一个 UST Namespace not permitted?

  •  
  •   salamanderMH · 27 天前 · 362 次点击

    问题

    照书写了段使用 UTS Namespace 的代码:

    import (
    	"os/exec"
    	"syscall"
    	"os"
    	"log"
    )
    
    func main() {
    	cmd := exec.Command("sh")
    	cmd.SysProcAttr = &syscall.SysProcAttr{
    		Cloneflags: syscall.CLONE_NEWUTS,
    	}
    	cmd.Stdin = os.Stdin
    	cmd.Stdout = os.Stdout
    	cmd.Stderr = os.Stderr
    
    	if err := cmd.Run(); err != nil {
    		log.Fatal(err)
    	}
    }
    

    执行go run uts.go发现提示fork/exec /bin/sh: operation not permitted,我改用 root 用户跑是可以解决问题的,看书上的环境是 Ubuntu 14.04 ,内核版本是 3.13.0-83-generic,书上跑这段代码是没这个权限问题的(因为它没说),我的环境是 Ubuntu 18.04.3,内核 5.0.0-32-generic,这个问题应该高版本内核导致的,是有什么改动吗?

    8 回复  |  直到 2019-11-19 21:51:34 +08:00
        1
    billlee   27 天前
    man 2 clone 上写的是要 CAP_SYS_ADMIN 权限的
        2
    salamanderMH   27 天前
    @billlee 感谢。
        3
    salamanderMH   27 天前
    看了下 doc
    If CLONE_NEWUTS is set, then create the process in a new UTS
    namespace, whose identifiers are initialized by duplicating
    the identifiers from the UTS namespace of the calling process.
    If this flag is not set, then (as with fork(2)) the process is
    created in the same UTS namespace as the calling process.
    This flag is intended for the implementation of containers.

    A UTS namespace is the set of identifiers returned by
    uname(2); among these, the domain name and the hostname can be
    modified by setdomainname(2) and sethostname(2), respectively.
    Changes made to the identifiers in a UTS namespace are visible
    to all other processes in the same namespace, but are not
    visible to processes in other UTS namespaces.

    Only a privileged process (CAP_SYS_ADMIN) can employ
    CLONE_NEWUTS.
        4
    codehz   27 天前
    (其实免特权跑容器一般都是先开一个(实际上可以同时) User namespace,然后设置 uid 映射
        5
    salamanderMH   21 天前
    我增加了一个 Mount Namespace,添加了 CAP_SYS_ADMIN,但是进入容器还是需要 root 权限?
    ````
    package main

    import (
    "log"
    "os"
    "os/exec"
    "syscall"
    )

    // Mount Namespace
    func main() {
    cmd := exec.Command("sh")
    cmd.SysProcAttr = &syscall.SysProcAttr{
    Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWIPC | syscall.CLONE_NEWPID | syscall.CLONE_NEWNS,
    }
    cmd.Stdin = os.Stdin
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr

    if err := cmd.Run(); err != nil {
    log.Fatal(err)
    }
    }
    ```
    sudo setcap CAP_SYS_ADMIN+ep app // 赋予 CAP_SYS_ADMIN
    然后`mount -t proc proc /proc`提示
    mount: 只有 root 用户能使用“--types”选项
    @billlee
        6
    billlee   21 天前
    @salamanderMH #5 mount(8) 是個 setuid 程序,會自己檢查權限的。你可以直接調 mount(2) 系統調用試試
        7
    salamanderMH   21 天前
    @billlee
    -rwsr-xr-x 1 root root 43088 8 月 23 07:47 /bin/mount
    有点不太懂,看网上资料 setuid 是会让进程运行时自己提升为 root 用户
    看了这篇文章,有点不太懂,https://here2say.com/39/ 晚上我再去研究研究哈哈
        8
    billlee   20 天前
    @salamanderMH #7 mount(8) 有 setuid 权限是为了非 root 用户也可以挂载 /etc/fstab 里面设置了 user 选项的文件系统。由于 setuid 了,就无法依赖内核来做权限检查,必须自己再实现一遍权限检查。可能这里的检查就没有考虑非 root 用户有 CAP_SYS_ADMIN 的情况。
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   4181 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 23ms · UTC 07:45 · PVG 15:45 · LAX 23:45 · JFK 02:45
    ♥ Do have faith in what you're doing.