私は許可されていない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
rootで実行すると機能する機能の問題のようです。
これは私のものです/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)