Estou surpreso que você ainda possa su user
, afaik depois que o kernel do Linux 3.19 o comando su
possa ficar confuso.
O comando unshare não é flexível o suficiente para fazê-lo: permite apenas um mapeamento para root. Você precisa mapear para si mesmo, depois de unshare
, mas antes de qualquer garfo / exec escrevendo "<user> <user> 1"
para /proc/self/uid_map
(e mesmo para /proc/self/gid_map
). Todos os kernels recentes também precisam escrever primeiro deny
a /proc/$$/setgroups
: todos os grupos suplementares (por exemplo: vídeo) terão que ser perdidos, isso é inevitável, como acontece com unshare -U/-r
.
Aqui está um programa muito simples C apenas como prova de conceito, que não faz nenhuma verificação para apenas fazer o que você pediu, mas somente se executado por um usuário com uid / gid 1000/1000 : perder a rede. Sinta-se à vontade para melhorá-lo.
#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);
}
Se o arquivo é chamado de removenet.c
, compile-o com 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
Note também que o novo namespace de rede tem sua interface lo
iniciando, e como você não é root, não é possível configurá-lo.
Você pode executar variantes deste programa para reverter para o seu antigo usuário após tornar-se root com, por exemplo, unshare -r -n -m
, alterando novamente para um novo namespace de usuário. Isso permite configurar alguns ambientes primeiro, como /sys
de montagem para não ver as interfaces anteriores, trazendo a interface lo
para cima, etc. Veja minha resposta para uma pergunta semelhante lá (com o mesmo código, você só precisa adicione novamente |CLONE_NEWNET
):
Para ser claro: não conheço nenhum utilitário padrão que possa fazer o que você está pedindo com um simples comando shell. Então você tem que recorrer para usar uma outra linguagem que não shell: C, python, ... há mesmo interface de função estrangeira ctypes.sh para o bash .
Esta outra resposta minha também fornece algumas informações adicionais e uma outra "linguagem", o depurador gdb:
como cancelar a rede de compartilhamento para o processo atual