zoukankan      html  css  js  c++  java
  • docker容器抓包 一介凡人

    当docker容器的网络模式不是--net=host(如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主

    机的IP和端口)时,容器和宿主机的网络互相独立,而容器一般也不会有安装tcpdump。因此,无法直接抓取容器内的包。

    一、docker 获取容器的相关信息

    1、查看docker容器的网络类型

    docker inspect --format='{{json .NetworkSettings.Networks}}' pgadmin
    {"bridge":{"IPAMConfig":null,"Links":null,"Aliases":null,"NetworkID":"f64b74cb9fa4ba72d6c041e6ccebfeaf4de028b8d665fbd353bcd489b3c092cf","EndpointID":"2fe58fec718f546b752e45e3dcca6099bb365d3b628df37b7589d6c59c785681","Gateway":"172.17.0.1","IPAddress":"172.17.0.3","IPPrefixLen":16,"IPv6Gateway":"","GlobalIPv6Address":"","GlobalIPv6PrefixLen":0,"MacAddress":"02:42:ac:11:00:03","DriverOpts":null}}
    

    2、获取容器的pid

    docker inspect --format "{{.State.Pid}}" container_id/name 获取PID

    二、tcpdump和nsenter抓包

    1、在docker容器内安装tcpdump工具来直接抓包

    • 获取docker id

      docker ps | grep xxx
    • copy tcpdump安装包和依赖包到容器内

      docker cp libpcap0-0.9.8-50.10.1.x86_64.rpm container_id:/tmp/
      docker cp tcpdump-3.9.8-1.21.x86_64.rpm container_id:/tmp/
    • 进入容器 安装tcpdump后进行抓包

      docker exec -it -u root container_id bash
      rpm -ivh *.rpm

    也可直接使用这个tcpdump文件(已编译好 免安装 可直接使用)

    docker cp /file/to/path/tcpdump container_id:/tmp/
    sh /tmp/tcpdump -i any -s 0 host x.x.x.x
    

    2、使用宿主机上的tcpdump工具对容器进程抓包

    如果宿主机上已安装了tcpdump抓包工具,那我们就可以通过宿主机上的nsenter工具来对docker容器进行抓包。

    nsenter 包含在绝大部分 Linux 发行版预置的 util-linux 工具包中。

    使用它可以进入指定进程的关联命名空间。包括文件命名空间(mount namespace)、主机名命名空间(UTS namespace)、IPC 命名空间(IPC namespace)、网络命名空间

    (network namespace)、进程命名空间(pid namespace)和用户命名空间(user namespace)。

    what is nsenter 

    It is a small tool allowing to enter into namespaces. Technically, it can enter existing namespaces, or spawn a process into a new set of namespaces. "What are those namespaces you're blabbering about?" We are talking about container namespaces.
    nsenter can do many useful things, but the main reason why I'm so excited about it is because it lets you enter into a Docker container.
    

    参数

    nsenter --help
    
    用法:
     nsenter [options] <program> [<argument>...]
    
    Run a program with namespaces of other processes.
    
    选项:
     -t, --target <pid>     要获取名字空间的目标进程
     -m, --mount[=<file>]   enter mount namespace
     -u, --uts[=<file>]     enter UTS namespace (hostname etc)
     -i, --ipc[=<file>]     enter System V IPC namespace
     -n, --net[=<file>]     enter network namespace
     -p, --pid[=<file>]     enter pid namespace
     -U, --user[=<file>]    enter user namespace
     -S, --setuid <uid>     set uid in entered namespace
     -G, --setgid <gid>     set gid in entered namespace
         --preserve-credentials do not touch uids or gids
     -r, --root[=<dir>]     set the root directory
     -w, --wd[=<dir>]       set the working directory
     -F, --no-fork          执行 <程序> 前不 fork
     -Z, --follow-context   set SELinux context according to --target PID
    
     -h, --help     显示此帮助并退出
     -V, --version  输出版本信息并退出
    
    更多信息请参阅 nsenter(1)。
    

    如何使用nsenter来抓包

    • 获取容器进程id,即PID

      docker ps | grep xxx 获取容器id/name
      
      docker inspect --format "{{.State.Pid}}" container_id/name 获取PID
    • 使用nsenter切换网络命名空间

      nsenter -n -t container_id/name
      
      可在切换前后执行ifconfig来对比变化

    现在就已进入容器的网络命名空间,就可以使用宿主机上的tcpdump来对容器进行抓包了

    三、通过iflink找到网卡对应关系

    1. 在宿主机上执行命令ip link

    ip link
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    2: ens33: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master bond0 state UP mode DEFAULT group default qlen 1000
        link/ether 00:0c:29:c3:35:79 brd ff:ff:ff:ff:ff:ff
    3: ens37: <BROADCAST,MULTICAST,SLAVE,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master bond0 state UP mode DEFAULT group default qlen 1000
        link/ether 00:0c:29:c3:35:79 brd ff:ff:ff:ff:ff:ff
    4: bond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
        link/ether 00:0c:29:c3:35:79 brd ff:ff:ff:ff:ff:ff
    5: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default
        link/ether 02:42:f7:6d:1c:51 brd ff:ff:ff:ff:ff:ff
    7: veth5092b87@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default
        link/ether 32:79:aa:d3:7f:2c brd ff:ff:ff:ff:ff:ff link-netnsid 0
    9: veth34be698@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default
        link/ether ae:d6:54:b3:50:93 brd ff:ff:ff:ff:ff:ff link-netnsid 1
    

    2、在容器内查看iflink文件

    docker exec -it pgadmin  sh
    
    /pgadmin4 $ cat /sys/class/net/eth0/iflink
    9
    
    或者通过ethtool来查看
    在容器中执行:ethtool -S eth0
    root@336043b07211:/# ethtool -S eth0
     NIC statistics: peer_ifindex: 9
    

    这样就可以确定:
    pgadmin这个容器在物理机上对应的veth pair是veth34be698@if8

    (9对应宿主机9:)

    容器外查看 ps  -ef  查看端口

    ps -ef | grep 5080
    root 2053 1356 0 17:05 ? 00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 5080 -container-ip 172.17.0.3 -container-port 80
    root 2059 1356 0 17:05 ? 00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip :: -host-port 5080 -container-ip 172.17.0.3 -container-port 80
    root 2348 1913 0 17:24 pts/1 00:00:00 grep --color=auto 5080

    容器内通过netstat  -r  查看连接情况

    /pgadmin4 $ netstat –r
    Active Internet connections (w/o servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State
    tcp        0      0 5b7f4fff015b:32830      192.168.40.132:postgresql ESTABLISHED
    tcp        0      0 5b7f4fff015b:32834      192.168.40.132:postgresql ESTABLISHED
    tcp        0      0 5b7f4fff015b:32838      192.168.40.132:postgresql ESTABLISHED
    tcp        0      0 5b7f4fff015b:32842      192.168.40.132:postgresql ESTABLISHED
    tcp        0      0 5b7f4fff015b:http       ::ffff:192.168.40.200:6165 TIME_WAIT
    tcp        0      0 5b7f4fff015b:http       ::ffff:192.168.40.200:6461 ESTABLISHED
    Active UNIX domain sockets (w/o servers)
    Proto RefCnt Flags       Type       State         I-Node Path

    tcpdump -i any

    tcpdump -i any
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
    22:01:27.432382 IP 192.168.40.200.10859 > root.http: Flags [P.], seq 2426513533:2426514255, ack 2732166892, win 4106, length 722: HTTP: GET /dashboard/dashboard_stats/1/16384?chart_names=session_stats,tps_stats,ti_stats,to_stats,bio_stats HTTP/1.1
    22:01:27.433384 IP root.49538 > public1.114dns.com.domain: 16551+ PTR? 3.0.17.172.in-addr.arpa. (41)
    22:01:27.444500 IP root.32834 > 192.168.40.132.postgres: Flags [P.], seq 1629397589:1629399809, ack 3287353308, win 1424, options [nop,nop,TS val 17857857 ecr 17856872], length 2220
    22:01:27.444595 IP 192.168.40.132.postgres > root.32834: Flags [.], ack 2220, win 1432, options [nop,nop,TS val 17857857 ecr 17857857], length 0
    22:01:27.457255 IP 192.168.40.132.postgres > root.32834: Flags [P.], seq 1:394, ack 2220, win 1432, options [nop,nop,TS val 17857870 ecr 17857857], length 393
    22:01:27.457263 IP root.32834 > 192.168.40.132.postgres: Flags [.], ack 394, win 1424, options [nop,nop,TS val 17857870 ecr 17857870], length 0
    22:01:27.458350 IP public1.114dns.com.domain > root.49538: 16551 NXDomain 0/1/0 (118)
    22:01:27.458360 IP root.http > 192.168.40.200.10859: Flags [P.], seq 1:419, ack 722, win 1432, length 418: HTTP: HTTP/1.1 200 OK
    22:01:27.458485 IP root.http > 192.168.40.200.10859: Flags [P.], seq 419:673, ack 722, win 1432, length 254: HTTP
    22:01:27.458568 IP 192.168.40.200.10859 > root.http: Flags [.], ack 673, win 4103, length 0
    22:01:27.459127 IP root.33689 > public1.114dns.com.domain: 20618+ PTR? 200.40.168.192.in-addr.arpa. (45)
    22:01:27.487509 IP public1.114dns.com.domain > root.33689: 20618 NXDomain* 0/1/0 (80)
    22:01:27.487691 IP root.46946 > public1.114dns.com.domain: 55017+ PTR? 114.114.114.114.in-addr.arpa. (46)
    22:01:27.514467 IP public1.114dns.com.domain > root.46946: 55017 1/0/0 PTR public1.114dns.com. (78)
    22:01:27.514595 IP root.49870 > public1.114dns.com.domain: 5779+ PTR? 132.40.168.192.in-addr.arpa. (45)
    22:01:27.551436 IP public1.114dns.com.domain > root.49870: 5779 NXDomain 0/1/0 (122)
    22:01:28.442007 IP 192.168.40.200.10859 > root.http: Flags [P.], seq 722:1444, ack 673, win 4103, length 722: HTTP: GET /dashboard/dashboard_stats/1/16384?chart_names=session_stats,tps_stats,ti_stats,to_stats,bio_stats HTTP/1.1
    

    tcpdump  -i  docker0  -vvv   -w   ip.txt

    将抓包结果放到文本中

  • 相关阅读:
    C++(封装一)
    数据结构之链式栈(二)
    C++(函数重载二)
    不计算阶乘获得结果末尾0的个数
    附加产品
    刘子闻讲的高精度【太强了】
    字符串相关函数
    回文素数
    蛇形填数
    筛法模版
  • 原文地址:https://www.cnblogs.com/zjz20/p/15750774.html
Copyright © 2011-2022 走看看