크기 1로 사용자 네임스페이스를 생성하면 작동하지만 크기가 1보다 크면 실패하는 이유

크기 1로 사용자 네임스페이스를 생성하면 작동하지만 크기가 1보다 크면 실패하는 이유

저는 권한이 없는 Linux 컨테이너를 실험 중이며 미니멀리스트 컨테이너를 생성하는 Go 프로그램을 작성 중입니다. 프로그램은 자신을 분기하고 프로세스 내에 네임스페이스를 만듭니다. 그런데 어떤 이유에서인지 사용자 네임스페이스 크기를 1보다 크게 설정하면 일반 사용자로 실행할 때 실패합니다.

    cmd := exec.Command("/proc/self/exe", "run-container")
    cmd.SysProcAttr = &syscall.SysProcAttr{
        Cloneflags:   syscall.CLONE_NEWUSER | syscall.CLONE_NEWUTS | syscall.CLONE_NEWPID | syscall.CLONE_NEWNS,
        Unshareflags: syscall.CLONE_NEWNS,
        UidMappings: []syscall.SysProcIDMap{
            {
                ContainerID: 0,
                HostID:      os.Getuid(),
                Size:        1,   // set this to 2 or more and it fails
            },
        },
        GidMappings: []syscall.SysProcIDMap{
            {
                ContainerID: 0,
                HostID:      os.Getgid(),
                Size:        1,
            },
        },
    }
    // other flags: CLONE_NEWNET, CLONE_NEWIPC, CLONE_NEWCGROUP, CLONE_NEWUSER,
    cmd.Stdin = os.Stdin
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr

    err := cmd.Run()
    if err != nil {
        fmt.Println("ERROR: parent cmd.Run", err)
        os.Exit(1)
    }

위의 코드(및 피봇루트 등과 같은 다른 모든 항목)는 정상적으로 작동합니다. 하지만 Size를 2로 설정하면 충돌이 발생합니다.

ERROR: parent cmd.Run fork/exec /proc/self/exe: operation not permitted

루트로 실행할 때 작동하는 기능 문제인 것 같습니다.

이 내 꺼야 /etc/subuid:

lxd:1000:1
root:1000:1
lxd:100000:65536
root:100000:65536
developer:165536:65536
mounter:231072:65536

고쳐 쓰다:

현재 항목을 다른 항목에 매핑하려면 CAP_SETUID가 필요하다는 것을 알았습니다 euid(참조사용자 네임스페이스 매뉴얼 페이지).

sudo setcap cap_setuid=eip /my/binary그러나 실패 하더라도 . 오류 메시지가 다음과 같이 변경되었습니다.

ERROR: parent cmd.Run fork/exec /proc/self/exe: permission denied

strace실행 하면 .EPERM/proc/xx/uid_map

openat(AT_FDCWD, "/proc/25233/uid_map", O_RDWR) = 5
write(5, "0 1000 100\n\0", 12)          = -1 EPERM (Operation not permitted)

관련 정보