rootに変更せずに「-n共有を解除」するには?

rootに変更せずに「-n共有を解除」するには?

私はネットワーキングなしで親と同じように動作するシェルを実行したいと思います。なぜ私は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デバッガも提供します。

現在のプロセスのネットワーク共有をキャンセルする方法

関連情報