나는 네트워킹 없이 부모와 똑같이 동작하는 쉘을 실행하고 싶습니다. 왜 내가 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 디버거도 제공합니다.