zoukankan      html  css  js  c++  java
  • 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# 
  • 相关阅读:
    odoo14系列笔记-基本进销存(二)
    odoo14系列笔记-基本进销存(一)
    PVE另一种方法使用中科大的镜像服务器 NGINX反向代理
    git 国内加速
    VirtualBox开启套娃模式-打开嵌套 VT-x/AMD-V 功能
    K8S集群安装(基于DEIBAN,proxmox)
    JS语法 ES6、ES7、ES8、ES9、ES10、ES11、ES12新特性
    8个非常实用的Vue自定义指令
    require和import的区别
    js异步加载之defer、async、type=module
  • 原文地址:https://www.cnblogs.com/dream397/p/14011621.html
Copyright © 2011-2022 走看看