私はネットワーキングなしで親と同じように動作するシェルを実行したいと思います。なぜ私はsu <login>
後に来るべきですかunshare
?
答え1
私はあなたがまだそうすることができるという事実に驚きました。 Linuxカーネル3.19以降は、コマンドが混乱する可能性があることsu user
を知っているからです。su
unshareコマンドはこれを行うのに十分柔軟ではありません。ルートディレクトリへのマッピングのみを許可します。その後、直接マッピングする必要があります。unshare
、しかし、フォーク/実行前に書く"<user> <user> 1"
(/proc/self/uid_map
と同じ/proc/self/gid_map
)。すべての最新のカーネルは最初に書き込みを要求しますdeny
。/proc/$$/setgroups
すべてのサプリメントグループ(ビデオなど)は失われなければなりませんunshare -U/-r
。
これはとても簡単ですCプログラムは概念証明であり、要求されたタスクを実行するためのチェックを実行せずにuid / gid 1000 / 1000:Lost Networkを使用してユーザーが実行している場合にのみ実行します。自由に改善してください。
#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|CLONE_NEWNET);
fd=open("/proc/self/setgroups",O_WRONLY);
write(fd,"deny",4);
close(fd);
fd=open("/proc/self/uid_map",O_WRONLY);
write(fd,"1000 1000 1",11);
close(fd);
fd=open("/proc/self/gid_map",O_WRONLY);
write(fd,"1000 1000 1",11);
close(fd);
execvp(argv[1],argv+1);
}
ファイルが呼び出されると、removenet.c
を使用してコンパイルされますgcc -o removenet removenet.c
。
$ id
uid=1000(user) gid=1000(user) groups=1000(user),44(video)
$ ip -br a
lo UNKNOWN 127.0.0.1/8 ::1/128
eth0@if11 UP 10.0.3.66/24 fe80::216:3eff:fe6a:c1e9/64
$ ./removenet bash
$ id
uid=1000(user) gid=1000(user) groups=1000(user),65534(nogroup)
$ ip -br a
lo DOWN
また、新しいネットワーク名前空間のlo
インターフェイスがダウンしており、ルートではないため設定することもできません。
このプログラムのバリアントを実行して、以前のユーザーに戻すことができます。後ろにunshare -r -n -m
たとえば、次のように変更してルートになります。再び新しいユーザーの名前空間を入力します。これにより、/sys
以前のインターフェイスが見えないようにインストールしたり、インターフェイスを取り出すlo
など、いくつかの環境を最初に設定できます。同様の質問に対する私の答えを参照してください(同じコードを使用して再度追加できます|CLONE_NEWNET
)。
unshare --map-root-userは、設定後に元のuid /ユーザー名に切り替えます。
明確に言えば、単純なシェルコマンドで要求されたタスクを実行する標準ユーティリティはありません。したがって、シェル以外の言語(C、Python...でも)を使用する必要があります。ctypes.sh bash 外部関数インタフェース。
私の他の答えは、いくつかの追加情報と別の「言語」であるgdbデバッガも提供します。