unshare --map-root-userは、設定後に元のuid /ユーザー名に切り替えます。

unshare --map-root-userは、設定後に元のuid /ユーザー名に切り替えます。

プロセス固有のインストールを作成するためにunshareを使用していますが、うまくいきます。

unshare -m --map-root-user

しかし、バインドマウントを作成した後

mount --bind src dst

whoamiUIDを元のユーザーに変更して、UID(および他のユーザー)が自分のユーザー名のようにエコーされるようにしたいと思いますecho $USER

私が試した答え unshareを使用したchrootシミュレーション

ただし、su – user1これを実行したchroot /

su: Authentication failure
(Ignored)
setgid: Invalid argument

私はこれをUbuntu 18.04 Beta、Debian Stretch、openSUSE-Leap-42.3でテストしました。すべて同じです。この回答が機能してからカーネルで何かが変わったようです。

これを行う効率的で正しい方法は何ですか(もちろん本物根)?

ベストアンサー1

これunshare(1)このコマンドは以下を実行できません。

-r, --map-root-user
[...] 純粋に便利な機能で、複数のUIDやGIDの範囲マッピングなど、より複雑なユースケースをサポートしていません。

とにかく、補足グループ(video、...)が失われる(またはマッピングされますnogroup)。

2番目の新しいユーザー名前空間に戻ってマッピングを復元できます。unshare(1)これを行わないので、カスタムプログラムが必要です。以下は、概念を証明するための非常にミニマルなCプログラムです(1人のユーザーのみ:uid / gid 1000/1000、エラーチェックなし)。私たちはそれを次のように呼びますrevertuid.c

#define _GNU_SOURCE
#include <sched.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <unistd.h>

int main(int argc, char *argv[]) {
    int fd;

    unshare(CLONE_NEWUSER);
    fd=open("/proc/self/setgroups",O_WRONLY);
    write(fd,"deny",4);
    close(fd);
    fd=open("/proc/self/uid_map",O_WRONLY);
    write(fd,"1000 0 1",8);
    close(fd);
    fd=open("/proc/self/gid_map",O_WRONLY);
    write(fd,"1000 0 1",8);
    close(fd);
    execvp(argv[1],argv+1);
}

これはマッピングdoneの逆マッピングに過ぎずunshare -r -m、次のようにルートとuseになるためには避けられませんmount

$ strace unshare -r -m /bin/sleep 1 2>&1 |sed -n '/^unshare/,/^execve/p'
unshare(CLONE_NEWNS|CLONE_NEWUSER)      = 0
open("/proc/self/setgroups", O_WRONLY)  = 3
write(3, "deny", 4)                     = 4
close(3)                                = 0
open("/proc/self/uid_map", O_WRONLY)    = 3
write(3, "0 1000 1", 8)                 = 8
close(3)                                = 0
open("/proc/self/gid_map", O_WRONLY)    = 3
write(3, "0 1000 1", 8)                 = 8
close(3)                                = 0
execve("/bin/sleep", ["/bin/sleep", "1"], [/* 18 vars */]) = 0

だからこれは以下を提供します:

user@stretch-amd64:~$ gcc -o revertuid revertuid.c
user@stretch-amd64:~$ mkdir -p /tmp/src /tmp/dst
user@stretch-amd64:~$ touch /tmp/src/file
user@stretch-amd64:~$ ls /tmp/dst
user@stretch-amd64:~$ id
uid=1000(user) gid=1000(user) groups=1000(user)
user@stretch-amd64:~$ unshare -r -m
root@stretch-amd64:~# mount --bind /tmp/src /tmp/dst
root@stretch-amd64:~# ls /tmp/dst
file
root@stretch-amd64:~# exec ./revertuid bash
user@stretch-amd64:~$ ls /tmp/dst
file
user@stretch-amd64:~$ id
uid=1000(user) gid=1000(user) groups=1000(user)

またはより短く:

user@stretch-amd64:~$ unshare -r -m sh -c 'mount --bind /tmp/src /tmp/dst; exec ./revertuid bash'
user@stretch-amd64:~$ ls /tmp/dst
file

カーネル3.19以降、次のように動作が変更されることがあります。user_namespaces(7):

これ/proc/[pid]/setgroupsこのファイルはLinux 3.19に追加されましたが、セキュリティ上の問題を解決したため、以前の多くの安定したカーネルシリーズにバックポートされました。問題は、「rwx---rwx」などの権限を持つファイルに関連しています。

おすすめ記事