以root运行Golang代码时出现Fork/exec /bin/sh权限拒绝问题
问题原因
当以root运行时,你先调用os.Setuid(1000)切换到普通用户,此时进程失去了创建CLONE_NEWUSER用户命名空间所需的CAP_SYS_ADMIN权限,导致后续执行/bin/sh时触发权限错误。而以uid1000运行时,Manjaro默认允许普通用户创建用户命名空间,因此可以正常执行。
修复后的代码
package main import ( "fmt" "os" "os/exec" "syscall" ) func main() { cmd := exec.Command("/bin/sh") cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.Env = []string{"PS1=-[ns-process]- # "} cmd.SysProcAttr = &syscall.SysProcAttr{ Cloneflags: syscall.CLONE_NEWNS | syscall.CLONE_NEWUTS | syscall.CLONE_NEWIPC | syscall.CLONE_NEWPID | syscall.CLONE_NEWNET | syscall.CLONE_NEWUSER, UidMappings: []syscall.SysProcIDMap{ { ContainerID: 0, HostID: 1000, Size: 1, }, }, GidMappings: []syscall.SysProcIDMap{ { ContainerID: 0, HostID: 1000, Size: 1, }, }, } if err := cmd.Run(); err != nil { fmt.Printf("Error running the /bin/sh command - %s\n", err) os.Exit(1) } }
关键修改说明
- 移除
os.Setuid(1000)调用:保留root权限以满足创建CLONE_NEWUSER命名空间的权限要求。 - 修改Uid/Gid映射的HostID为1000:让新命名空间内的root用户(ContainerID 0)直接映射到宿主机的1000用户/组,这样新启动的
/bin/sh在命名空间内拥有root权限,但在宿主机层面以普通用户身份运行,兼顾权限需求与安全性。
内容的提问来源于stack exchange,提问作者stackflow-crystal
相关产品推荐
相关产品推荐

