unix socket 跨namespace

UNIX socket that spans two different mount namespaces

 

The “init” process can establish a communication channel between the parent namespace and the child namespace.

This channel can be based on UNIX sockets or can even use TCP. To create a UNIX socket that spans two different mount namespaces,

you need to first create the child process, then create the UNIX socket, and then isolate the child into a separate mount namespace. But how can we create the process first, and isolate it later? Linux provides unshare(). This special system call allows a process to isolate itself from the original namespace, instead of having the parent isolate the child in the first place. For example, the following code has the exact same effect as the code previously mentioned in the network namespace section:

 

 

 

af_unix: Allow connecting to sockets in other network namespaces.

unix_find_other(struct net *net,

        unix_find_socket_byinode

 

 

 

 

 

1、启动server

 

 

 

 

 

2、 同一个namespace启动client

 

 

 

3、新的namespace启动

 

3、chroot

docker export $(docker create nginx) | tar -C rootfs -xvf -

root@ubuntu:~/docker/container# ls
config.json  rootfs
root@ubuntu:~/docker/container# chroot rootfs /bin/bash
root@ubuntu:/# ls
bin  boot  client  dev  docker-entrypoint.d  docker-entrypoint.sh  etc  home  lib  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@ubuntu:/# ./client 
connect: No such file or directory
root@ubuntu:/# 

 

 

root@ubuntu:~/docker/container# unshare --user --mount --ipc --pid --net --uts -r --fork --propagation private bash
root@ubuntu:~/docker/container# ls
config.json  rootfs
root@ubuntu:~/docker/container# cd rootfs/
root@ubuntu:~/docker/container/rootfs# ./client 
connect: No such file or directory
root@ubuntu:~/docker/container/rootfs# ls
bin  boot  client  dev  docker-entrypoint.d  docker-entrypoint.sh  etc  home  lib  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@ubuntu:~/docker/container/rootfs# 

 

 https://segmentfault.com/a/1190000006913509

 

采用mount bind

root@ubuntu:~/docker/container# unshare --user --mount --ipc --pid --net --uts -r --fork --propagation private bash
root@ubuntu:~/docker/container# mkdir unix_sock
root@ubuntu:~/docker/container# ls ~/docker/unix-domain-socket-example
bin  client.c  ipc.h  Makefile  server.c
root@ubuntu:~/docker/container# mount --bind  ~/docker/unix-domain-socket-example  ./unix_sock
root@ubuntu:~/docker/container# ls unix_sock/
bin  client.c  ipc.h  Makefile  server.c
root@ubuntu:~/docker/container# cd unix_sock/
root@ubuntu:~/docker/container/unix_sock# ls
bin  client.c  ipc.h  Makefile  server.c
root@ubuntu:~/docker/container/unix_sock# cd bin/
root@ubuntu:~/docker/container/unix_sock/bin# ls
client  server  server.sock
root@ubuntu:~/docker/container/unix_sock/bin# ./client 
sent iccExchangeAPDU
receive 15 transmit good!
root@ubuntu:~/docker/container/unix_sock/bin# 

 

重新建立mount bind

 

 

root@ubuntu:~/docker/container# mkdir rootfs/unixsock
root@ubuntu:~/docker/container# mount --bind  ~/docker/unix-domain-socket-example  ./rootfs/unix_sock
mount: ./rootfs/unix_sock: mount point does not exist.
root@ubuntu:~/docker/container# ls rootfs/unixsock
root@ubuntu:~/docker/container# mount --bind  ~/docker/unix-domain-socket-example  ./rootfs/unixsock/
root@ubuntu:~/docker/container# chroot rootfs /bin/bash
root@ubuntu:/# ls
bin  boot  client  dev  docker-entrypoint.d  docker-entrypoint.sh  etc  home  lib  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  unixsock  usr  var
root@ubuntu:/# cd unixsock/
root@ubuntu:/unixsock# ls  
Makefile  bin  client.c  ipc.h  server.c
root@ubuntu:/unixsock# cd bin/
root@ubuntu:/unixsock/bin# ls
client  server  server.sock
root@ubuntu:/unixsock/bin# ./client 
sent iccExchangeAPDU
receive 15 transmit good!
root@ubuntu:/unixsock/bin# cd ..
root@ubuntu:/unixsock# cd ..
root@ubuntu:/# ./client 
connect: No such file or directory
root@ubuntu:/# netstat -lpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
netstat: /proc/net/tcp: No such file or directory
netstat: /proc/net/tcp6: No such file or directory
netstat: /proc/net/udp: No such file or directory
netstat: /proc/net/udp6: No such file or directory
netstat: /proc/net/raw: No such file or directory
netstat: /proc/net/raw6: No such file or directory
Active UNIX domain sockets (only servers)
Proto RefCnt Flags       Type       State         I-Node PID/Program name    Path
netstat: /proc/net/unix: No such file or directory
root@ubuntu:/# 

 

 

新建挂载点和net namespace

root@ubuntu:~/docker/container# unshare -m -n /bin/bash
root@ubuntu:~/docker/container# ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
root@ubuntu:~/docker/container# ls
config.json  rootfs
root@ubuntu:~/docker/container# cd rootfs/
root@ubuntu:~/docker/container/rootfs# ls
bin  boot  client  dev  docker-entrypoint.d  docker-entrypoint.sh  etc  home  lib  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  unixsock  usr  var
root@ubuntu:~/docker/container/rootfs# ./client 
connect: No such file or directory
root@ubuntu:~/docker/container/rootfs# 

 

原因是没有用绝对路径,改成/var/run/server.sock 

root@ubuntu:~/docker/container/rootfs# cp ../../unix-domain-socket-example/bin/client ./
root@ubuntu:~/docker/container/rootfs# ls
bin boot client dev docker-entrypoint.d docker-entrypoint.sh etc home lib media mnt opt proc root run sbin srv sys tmp unixsock usr var
root@ubuntu:~/docker/container/rootfs# ./client
sent iccExchangeAPDU
receive 15 transmit good!
^C
root@ubuntu:~/docker/container/rootfs# unshare --user --mount --ipc --pid --net --uts -r --fork --propagation private bash
root@ubuntu:~/docker/container/rootfs# ./client
sent iccExchangeAPDU
receive 15 transmit good!

 

 root@ubuntu:~/docker/container/rootfs# unshare --user --mount --ipc --pid --net --uts -r --fork --propagation private bash
root@ubuntu:~/docker/container/rootfs# ./client 
sent iccExchangeAPDU
receive 15 transmit good!
^C
root@ubuntu:~/docker/container/rootfs# ./client  &
[1] 12
root@ubuntu:~/docker/container/rootfs# sent iccExchangeAPDU
receive 15 transmit good!

root@ubuntu:~/docker/container/rootfs# ps -elf | grep client0 S root     19962 19365  0  80   0 -  1096 pipe_w 17:23 pts/4    00:00:00 grep --color=auto client
root@ubuntu:~/docker/container/rootfs# chroot . /bin/bash
root@ubuntu:/# ls
bin  boot  client  dev  docker-entrypoint.d  docker-entrypoint.sh  etc  home  lib  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  unixsock  usr  var
root@ubuntu:/# ps -elf | grep client
root@ubuntu:/# mount -t proc /proc
mount: /proc: can't find in /etc/fstab.
root@ubuntu:/# mount -t proc proc /proc
root@ubuntu:/# ps -elf | grep client
   12 root      0:00 ./client
   22 root      0:00 grep client
root@ubuntu:/# kill -9  12
root@ubuntu:/# ps -elf | grep client

 

 

server运行在sandbox

 

 sanbox

root@ubuntu:~/docker/container/rootfs# unshare --user --mount --ipc --pid --net --uts -r --fork --propagation private bash
root@ubuntu:~/docker/container/rootfs# mount -t proc proc /proc
root@ubuntu:~/docker/container/rootfs# ps -elf 
F S UID        PID  PPID  C PRI  NI ADDR SZ WCHAN  STIME TTY          TIME CMD
4 S root         1     0  0  80   0 -  1400 wait   17:35 pts/4    00:00:00 bash
0 R root        12     1  0  80   0 -  1741 -      17:36 pts/4    00:00:00 ps -elf
root@ubuntu:~/docker/container/rootfs# ls
bin  boot  client  dev  docker-entrypoint.d  docker-entrypoint.sh  etc  home  lib  media  mnt  opt  proc  root  run  sbin  server  srv  sys  tmp  unixsock  usr  var
root@ubuntu:~/docker/container/rootfs# ./server &
[1] 14
root@ubuntu:~/docker/container/rootfs# chroot . /bin/bash

 

client 发送

root@ubuntu:~/docker/unix-domain-socket-example/bin# ./client 
sent iccExchangeAPDU
receive 15 transmit good!

 

 ****************************************sandbox

https://github.com/denehs/unix-domain-socket-example

 

 

 

root@ubuntu:/# ps -elf | grep server
   11 root      0:00 ./server
   31 root      0:00 ./server
   34 root      0:00 grep server
root@ubuntu:/# ls /
bin  boot  client  dev  docker-entrypoint.d  docker-entrypoint.sh  etc  home  lib  media  mnt  opt  proc  root  run  sbin  server  srv  sys  tmp  unixsock  usr  var
root@ubuntu:/# ls /var/run/
lock/  mount/ utmp   
root@ubuntu:/# ls /var/run/
lock  mount  utmp
root@ubuntu:/# netstat -pan | grep server
Active Internet connections (servers and established)
Active UNIX domain sockets (servers and established)
unix  2      [ ]         DGRAM                    74752739 31/server           /var/run/server.sock
root@ubuntu:/# ls -al var/run/server.sock
ls: cannot access 'var/run/server.sock': No such file or directory
root@ubuntu:/# 

 

 

 

 

已经执行chroot了,client再发送一次

 

 

 

从sandbox退出后又有了,但是无法kill

 

root@ubuntu:~/docker/container/rootfs# ls -al  /proc/22442/ns/
total 0
dr-x--x--x 2 root root 0 Nov 20 17:48 .
dr-xr-xr-x 9 root root 0 Nov 20 17:44 ..
lrwxrwxrwx 1 root root 0 Nov 20 17:48 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 root root 0 Nov 20 17:48 ipc -> 'ipc:[4026534439]'
lrwxrwxrwx 1 root root 0 Nov 20 17:48 mnt -> 'mnt:[4026534437]'
lrwxrwxrwx 1 root root 0 Nov 20 17:48 net -> 'net:[4026534442]'
lrwxrwxrwx 1 root root 0 Nov 20 17:48 pid -> 'pid:[4026534440]'
lrwxrwxrwx 1 root root 0 Nov 20 17:48 pid_for_children -> 'pid:[4026534440]'
lrwxrwxrwx 1 root root 0 Nov 20 17:48 user -> 'user:[4026534436]'
lrwxrwxrwx 1 root root 0 Nov 20 17:48 uts -> 'uts:[4026534438]'
root@ubuntu:~/docker/container/rootfs# 

 

 

进入  nsenter -t 22442 -p  然后kill

oot@ubuntu:~/docker/container/rootfs# mount -t proc proc /proc
root@ubuntu:~/docker/container/rootfs# ps -elf 
F S UID        PID  PPID  C PRI  NI ADDR SZ WCHAN  STIME TTY          TIME CMD
4 S root         1     0  0  80   0 -  1400 wait   17:30 pts/4    00:00:00 bash
0 S root        11     1  0  80   0 -   450 skb_wa 17:30 pts/4    00:00:00 ./server
4 S root        56     1  0  80   0 -  1100 wait   17:50 pts/4    00:00:00 nsenter -t 22442 -p
0 S root        57    56  0  80   0 -  1662 wait   17:50 pts/4    00:00:00 -bash
0 R root        79    57  0  80   0 -  1741 -      17:51 pts/4    00:00:00 ps -elf
root@ubuntu:~/docker/container/rootfs# kill -9 11
root@ubuntu:~/docker/container/rootfs# ps -elf 
F S UID        PID  PPID  C PRI  NI ADDR SZ WCHAN  STIME TTY          TIME CMD
4 S root         1     0  0  80   0 -  1400 wait   17:30 pts/4    00:00:00 bash
4 S root        56     1  0  80   0 -  1100 wait   17:50 pts/4    00:00:00 nsenter -t 22442 -p
0 S root        57    56  0  80   0 -  1662 wait   17:50 pts/4    00:00:00 -bash
0 R root        80    57  0  80   0 -  1741 -      17:51 pts/4    00:00:00 ps -elf
root@ubuntu:~/docker/container/rootfs# exit
logout
[1]+  Killed                  ./server
root@ubuntu:~/docker/container/rootfs# ps -elf | grep './server'
0 S root        82     1  0  80   0 -  1096 pipe_w 17:52 pts/4    00:00:00 grep --color=auto ./server
root@ubuntu:~/docker/container/rootfs# 

 

 

 

*************** 先chroot,然后运行server

 

 

root@ubuntu:~/docker/unix-domain-socket-example/bin# ./client 
connect: Connection refused
root@ubuntu:~/docker/unix-domain-socket-example/bin# ./client 
connect: Connection refused
root@ubuntu:~/docker/unix-domain-socket-example/bin# ls -al /var/run/server.sock
srwxr-xr-x 1 root root 0 Nov 20 17:36 /var/run/server.sock
root@ubuntu:~/docker/unix-domain-socket-example/bin# 

 

posted on 2020-11-20 16:32  tycoon3  阅读(496)  评论(0编辑  收藏  举报

导航