TCP 连接排故:使用 BPF BCC工具包进行网络跟踪

2024-05-24 08:12

本文主要是介绍TCP 连接排故:使用 BPF BCC工具包进行网络跟踪,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

写在前面


  • 博文内容为 BCC 进行网络跟踪常见工具介绍
  • tcpconnect:主动的 TCP 连接跟踪
  • tcpaccept:被动的 TCP 连接跟踪
  • tcpretrans:重传的 TCP 连接跟踪
  • tcptracer:已建立的 TCP 连接跟踪
  • tcpconnlat:测量出站 TCP 连接的延迟
  • tcpdrop:被内核丢弃的 TCP 数据包跟踪
  • tcplife: TCP 会话追踪
  • tcpstates: TCP 状态更改跟踪
  • tcpsubnet:统计发送到特定子网的 TCP 流量
  • tcptop: IP 端口的网络吞吐量跟踪
  • solisten: 本机 IPv4 和 IPv6 侦听跟踪
  • softirqs:软中断的服务时间统计
  • netqtop:统计网卡上数据包大小和计数
  • 理解不足小伙伴帮忙指正 😃,生活加油

不必太纠结于当下,也不必太忧虑未来,当你经历过一些事情的时候,眼前的风景已经和从前不一样了。——村上春树


认识之前,简单回忆一下,TCP 三次握手,四次挥手

三次握手

客户端                       服务器
SYN-SENT  ------ SYN(seq=x) ----><---- SYN+ACK(seq=y, ack=x+1) ---- SYN_RECV
ESTABLISHED  ---- ACK(ack=y+1, seq=x+1) ---->
  • 第一次握手:客户端发送一个SYN包(SYN=1,seq=x)到服务器,请求建立连接。客户端进入SYN_SENT状态。
  • 第二次握手:服务器收到 SYN 包,必须确认客户端的 SYN,发送 ACK(ACK=1,ack=x+1),同时自己也发送一个SYN包(SYN=1,seq=y)。服务器进入SYN_RECV状态。
  • 第三次握手: 客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ACK=1,ack=y+1,seq=x+1)
    客户端和服务器进入ESTABLISHED状态,连接建立完成。

四次挥手

客户端                       服务器
FIN_WAIT1  ------ FIN(seq=u) ----><---- ACK(ack=u+1) ---- CLOSE_WAIT<---- FIN(seq=w) ----
TIME_WAIT  ---- ACK(ack=w+1) ----->(等待2MSL后关闭连接)(服务器也关闭连接)
  • 第一次挥手:客户端发送一个FIN包(FIN=1,seq=u)给服务器端,请求关闭连接。客户端进入FIN_WAIT1状态。
  • 第二次挥手:服务器端收到FIN包后发送一个ACK包(ACK=1,ack=u+1)给客户端,表示已经收到客户端的关闭连接请求。服务器端进入CLOSE_WAIT状态。
  • 第三次挥手: 服务器端关闭连接,发送一个FIN包(FIN=1,seq=w)给客户端。服务器端进入 LAST_ACK 状态。
  • 第四次挥手: 客户端收到FIN包后发送一个ACK包(ACK=1,ack=w+1)给服务器端,表示已经收到服务器端的关闭连接请求。客户端进入TIME_WAIT状态,等待2MSL时间后关闭连接。服务器端收到 ACK 包后关闭连接。

tcpconnect:主动的 TCP 连接跟踪

tcpconnect(8)会在每次主动的TCP连接(从当前机器发起的)建立(例如,通过connect()调用)时,打印一行信息,包含源地址、目的地址。在输出中应该寻找不寻常的连接请求,它们可能会暴露出软件配置的低效,也可能暴露入侵行为

┌──[root@vms100.liruilongs.github.io]-[~]
└─$tcpconnect #/usr/share/bcc/tools/tcpaccept
Tracing connect ... Hit Ctrl-C to end
PID     COMM         IP SADDR            DADDR            DPORT
103502  curl         4  192.168.26.100   192.168.26.100   8000
103509  curl         4  192.168.26.100   192.168.26.100   8780
103512  mysql        4  192.168.26.100   192.168.26.100   3306
3053    haproxy      4  192.168.26.100   192.168.26.100   3306
3053    haproxy      4  192.168.26.100   192.168.26.102   4569
3053    haproxy      4  192.168.26.100   192.168.26.100   3306
103550  curl         4  192.168.26.100   192.168.26.100   5000
3053    haproxy      4  192.168.26.100   192.168.26.100   3306
3053    haproxy      4  192.168.26.100   192.168.26.100   4569
103572  mysql        4  192.168.26.100   192.168.26.100   3306
3053    haproxy      4  192.168.26.100   192.168.26.102   5000
3053    haproxy      4  192.168.26.100   192.168.26.102   8775
3053    haproxy      4  192.168.26.100   192.168.26.102   8000
................................
3053    haproxy      4  192.168.26.100   192.168.26.100   3306
3053    haproxy      4  192.168.26.100   192.168.26.102   35357
3053    haproxy      4  192.168.26.100   192.168.26.101   80

这个工具的开销应该可以忽略不计,因为它只跟踪执行连接connect.内核函数。它不是跟踪每个包然后过滤。

t选项打印一个时间戳列:

# ./tcpconnect -t
TIME(s)  PID    COMM         IP SADDR            DADDR            DPORT
31.871   2482   local_agent  4  10.103.219.236   10.251.148.38    7001
31.874   2482   local_agent  4  10.103.219.236   10.101.3.132     7001

d选项跟踪 DNS 响应,并尝试将每个连接与之前发出的 DNS 查询关联起来。如果找到与该 IP 匹配的 DNS 响应,则将打印该响应。如果未找到匹配项,则在此列中打印"No DNS Query"

# ./tcpconnect -d
PID    COMM         IP SADDR            DADDR            DPORT QUERY
1543   amazon-ssm-a 4  10.66.75.54      176.32.119.67    443   ec2messages.us-west-1.amazonaws.com
1479   telnet       4  127.0.0.1        127.0.0.1        23    localhost
1469   curl         4  10.201.219.236   54.245.105.25    80    www.domain.com (123.342ms)
1469   curl         4  10.201.219.236   54.67.101.145    80    No DNS Query
1991   telnet       6  ::1              ::1              23    localhost
2015   ssh          6  fe80::2000:bff:fe82:3ac fe80::2000:bff:fe82:3ac 22    anotherhost.org

127.0.0.1的查询和::1自动与 localhost 相关联。如果收到DNS响应和跟踪连接调用之间的时间超过100毫秒,该工具将在查询名称之后打印时间差

L选项打印 LPORT 列: 目标端口

# ./tcpconnect -L
PID    COMM         IP SADDR            LPORT  DADDR            DPORT
3706   nc           4  192.168.122.205  57266  192.168.122.150  5000
3722   ssh          4  192.168.122.205  50966  192.168.122.150  22
3779   ssh          6  fe80::1          52328  fe80::2          22

显示 UID 和 PID

# ./tcpconnect -Uu 1000
UID   PID    COMM         IP SADDR            DADDR            DPORT
1000  31338  telnet       6  ::1              ::1              23
1000  31338  telnet       4  127.0.0.1        127.0.0.1        23

其他的一些操作 Demo

examples:./tcpconnect           # trace all TCP connect()s./tcpconnect -t        # include timestamps./tcpconnect -d        # include DNS queries associated with connects./tcpconnect -p 181    # only trace PID 181./tcpconnect -P 80     # only trace port 80./tcpconnect -P 80,81  # only trace port 80 and 81./tcpconnect -4        # only trace IPv4 family./tcpconnect -6        # only trace IPv6 family./tcpconnect -U        # include UID./tcpconnect -u 1000   # only trace UID 1000./tcpconnect -c        # count connects per src ip and dest ip/port./tcpconnect -L        # include LPORT while printing outputs./tcpconnect --cgroupmap mappath  # only trace cgroups in this BPF map./tcpconnect --mntnsmap mappath   # only trace mount namespaces in the map

tcpaccept:被动的 TCP 连接跟踪

tepaccept(8)是 tcpconnect(8)工具的搭档。每当有被动的TCP连接建立(接受的一方)时(通 tcpaccept()),就会打印一行信息,同样包含源地址和目的地址。

tcpconnect 工具使用 eBPF 特性来跟踪出去的 TCP 连接尝试。该工具的输出还包括失败的连,同样 tcpconnect 工具是轻量级的,因为它跟踪内核的 connect() 函数,而不是捕获和过滤数据包。

内核在 TCP 3 次握手中接收 ACK 数据包后,内核会将来自 SYN 队列的连接移到 accept 队列,直到连接的状态变为 ESTABLISHED。因此,只有成功的 TCP 连接才能在此队列中看到。

可以使用 tcpaccept 进行常规故障排除,来显示服务器已接受的新连接

┌──[root@vms100.liruilongs.github.io]-[~]
└─$tcpaccept #/usr/share/bcc/tools/tcpconnect
PID     COMM         IP RADDR            RPORT LADDR            LPORT
3193    xinetd       6  ::ffff:192.168.26.100 55384 ::ffff:192.168.26.100 4569
6621    mariadbd     4  192.168.26.100   42682 192.168.26.100   3306
3193    xinetd       6  ::ffff:192.168.26.102 56114 ::ffff:192.168.26.100 4569
6621    mariadbd     4  192.168.26.100   42696 192.168.26.100   3306
3636    httpd        4  192.168.26.100   38142 192.168.26.100   80
3193    xinetd       6  ::ffff:192.168.26.101 47122 ::ffff:192.168.26.100 4569
6621    mariadbd     4  192.168.26.100   42700 192.168.26.100   3306
3994    httpd        4  192.168.26.100   57924 192.168.26.100   8004
3053    haproxy      4  192.168.26.101   51722 192.168.26.99    3306
6621    mariadbd     4  192.168.26.100   42702 192.168.26.100   3306
.......................................
6621    mariadbd     4  192.168.26.100   52492 192.168.26.100   3306
^C┌──[root@vms100.liruilongs.github.io]-[~]
└─$

每次内核处理一个出去的连接时,tcpconnect 都会显示连接的详情。其他的一些选项

examples:./tcpaccept           # trace all TCP accept()s./tcpaccept -t        # include timestamps./tcpaccept -P 80,81  # only trace port 80 and 81./tcpaccept -p 181    # only trace PID 181./tcpaccept --cgroupmap mappath  # only trace cgroups in this BPF map./tcpaccept --mntnsmap mappath   # only trace mount namespaces in the map./tcpaccept -4        # trace IPv4 family only./tcpaccept -6        # trace IPv6 family only

tcpretrans:重传的 TCP 连接跟踪

每次TCP重传数据包时tcpretrans(8)会打印一行记录,包含源地址和目的地址,以及当时该 TCP 连接所处的内核状态。TCP 重传会导致延迟和吞吐量方面的问题。

如果重传发生在 TCPESTABLISHED状态下,会进一步寻找外部网络可能存在的问题。如果重传发在SYNSENT状态下,这可能是 CPU 饱和的一个征兆,也可能是内核丢包引发的。

tcpretrans 工具显示有关 TCP 重新传输的详细信息,如本地和远程的 IP 地址和端口号,以及重新传输时 TCP 的状态。

该工具使用 eBPF 功能,因此开销非常低。每次内核调用 TCP 重新传输函数时,tcpretrans 都会显示连接的详情。

┌──[root@vms100.liruilongs.github.io]-[~]
└─$tcpretrans #/usr/share/bcc/tools/tcpretrans
Tracing retransmits ... Hit Ctrl-C to end
TIME     PID     IP LADDR:LPORT          T> RADDR:RPORT          STATE
12:35:36 107232  4  192.168.26.100:39122 R> 192.168.26.100:3306  FIN_WAIT1
12:35:36 0       4  192.168.26.99:3306   R> 192.168.26.101:57360 ESTABLISHED
12:35:55 0       4  192.168.26.99:48370  R> 192.168.26.99:3306   FIN_WAIT1
12:36:07 11139   4  192.168.26.100:43004 R> 192.168.26.100:3306  FIN_WAIT1
12:36:07 11139   4  192.168.26.99:45960  R> 192.168.26.99:3306   FIN_WAIT1
12:36:07 11139   4  192.168.26.99:45950  R> 192.168.26.99:3306   FIN_WAIT1
12:36:07 3053    4  192.168.26.99:46030  R> 192.168.26.99:3306   FIN_WAIT1
12:36:07 27      4  192.168.26.99:46014  R> 192.168.26.99:3306   FIN_WAIT1
^C┌──[root@vms100.liruilongs.github.io]-[~]
└─$
  • ESTABLISHED 状态表示连接已经建立,并且数据可以在两个方向上进行传输。
  • FIN_WAIT1 表明本地端已经收到来自远程端的 FIN 分片,但本地应用还未完全关闭连接,因此本地端等待应用层的关闭指示。如果这种状态持续很长时间,那么可能存在应用程序关闭不当或网络问题导致远程端未能及时收到 ACK 分片。

重传通常是网络健康状况不佳的标志,这个工具对他们的调查很有用。与使用tcpdump不同,该工具的开销非常低,因为它只跟踪重传函数

# ./tcpretrans -l
TIME     PID    IP LADDR:LPORT          T> RADDR:RPORT          STATE
01:55:45 0      4  10.153.223.157:22    R> 69.53.245.40:51601   ESTABLISHED
01:55:46 0      4  10.153.223.157:22    R> 69.53.245.40:51601   ESTABLISHED
01:55:46 0      4  10.153.223.157:22    R> 69.53.245.40:51601   ESTABLISHED
01:55:53 0      4  10.153.223.157:22    L> 69.53.245.40:46444   ESTABLISHED
01:56:06 0      4  10.153.223.157:22    R> 69.53.245.40:46444   ESTABLISHED

T 列 中的“L”这些都是尝试:内核可能发送了一个TLP,但在某些情况下它可能最终没有被发送。

  • L>: 表示数据包是从本地地址(LADDR)发送到远程地址(RADDR)的。
  • R>: 表示数据包是从远程地址(RADDR)发送到本地地址(LADDR)的。

要快速发现重传流,可以使用-c标志。它将计算每个流中发生的重传次数。

# ./tcpretrans.py -c
Tracing retransmits ... Hit Ctrl-C to end
^C
LADDR:LPORT              RADDR:RPORT             RETRANSMITS
192.168.10.50:60366  <-> 172.217.21.194:443         700
192.168.10.50:666    <-> 172.213.11.195:443         345
192.168.10.50:366    <-> 172.212.22.194:443         211

其他的一些操作

optional arguments:-h, --help       show this help message and exit-s, --sequence   display TCP sequence numbers-l, --lossprobe  include tail loss probe attempts-c, --count      count occurred retransmits per flow-4, --ipv4       trace IPv4 family only-6, --ipv6       trace IPv6 family onlyexamples:./tcpretrans           # trace TCP retransmits./tcpretrans -l        # include TLP attempts./tcpretrans -4        # trace IPv4 family only./tcpretrans -6        # trace IPv6 family only

tcptracer:已建立的 TCP 连接跟踪

tcptracer 工具追踪内核中与 TCP 连接建立(如通过 connect()或 accept()系统调用)和关闭(显式关闭或进程死亡时)相关的函数。同样该工具使用 eBPF 功能,因此开销非常低。

┌──[root@vms100.liruilongs.github.io]-[~]
└─$tcptracer   #/usr/share/bcc/tools/tcptracer
Tracing TCP established connections. Ctrl-C to end.
T  PID    COMM             IP SADDR            DADDR            SPORT  DPORT
C  28943  telnet           4  192.168.1.2      192.168.1.1      59306  23
C  28818  curl             6  [::1]            [::1]            55758  80
X  28943  telnet           4  192.168.1.2      192.168.1.1      59306  23
A  28817  nc               6  [::1]            [::1]            80     55758
X  28818  curl             6  [::1]            [::1]            55758  80
X  28817  nc               6  [::1]            [::1]            80     55758
A  28978  nc               4  10.202.210.1     10.202.109.12    8080   59160
X  28978  nc               4  10.202.210.1     10.202.109.12    8080   59160

关于事件类型的解释:

  • C 表示连接(Connect):这通常表示一个 TCP 连接请求已经发送或接收。
  • X 表示关闭(Close):这表示 TCP 连接已经关闭,可能是由于正常关闭(如通过 FIN/ACK 握手)或由于某种错误导致的异常关闭。
  • A 表示接受(Accept):这通常表示服务器已经接受了一个来自客户端的连接请求,并创建了一个新的连接。然而,

每当内核连接、接受或关闭连接时,tcptracer 都会显示连接的详情。

通过可以基于 Cgroup 来进行过滤,同时提供接基于 网络命名空间的过滤

[root@liruilongs ~]# /usr/share/bcc/tools/tcptracer -h
usage: tcptracer [-h] [-t] [-p PID] [-N NETNS] [--cgroupmap CGROUPMAP] [--mntnsmap MNTNSMAP] [-4 | -6] [-v]Trace TCP connectionsoptional arguments:-h, --help            show this help message and exit-t, --timestamp       include timestamp on output-p PID, --pid PID     trace this PID only-N NETNS, --netns NETNStrace this Network Namespace only--cgroupmap CGROUPMAPtrace cgroups in this BPF map only--mntnsmap MNTNSMAP   trace mount namespaces in this BPF map only-4, --ipv4            trace IPv4 family only-6, --ipv6            trace IPv6 family only-v, --verbose         include Network Namespace in the output
[root@liruilongs ~]#

tcpconnlat:测量出站 TCP 连接的延迟

TCP 连接延迟是建立连接所需的时间。这通常涉及内核 TCP/IP 处理和网络往返时间,而不是应用程序运行时。

tcpconnlat 工具使用 eBPF 特性来测量发送 SYN 数据包和接收响应数据包之间的时间。

LAT(ms) 列为延迟时间

┌──[root@liruilongs.github.io]-[~]
└─$tcpconnlat #/usr/share/bcc/tools/tcpconnlat
PID     COMM         IP SADDR            DADDR            DPORT LAT(ms)
1701    barad_agent  4  10.0.16.15       169.254.0.4      80    9.68
1701    barad_agent  4  10.0.16.15       169.254.0.4      80    8.20
1701    barad_agent  4  10.0.16.15       169.254.0.4      80    9.29
1701    barad_agent  4  10.0.16.15       169.254.0.4      80    7.52
1701    barad_agent  4  10.0.16.15       169.254.0.4      80    7.68
^C┌──[root@liruilongs.github.io]-[~]
└─$

也可以根据延迟时间,pid 来进行过滤,其他的 Demo

examples:./tcpconnlat           # trace all TCP connect()s./tcpconnlat 1         # trace connection latency slower than 1 ms./tcpconnlat 0.1       # trace connection latency slower than 100 us./tcpconnlat -t        # include timestamps./tcpconnlat -p 181    # only trace PID 181./tcpconnlat -L        # include LPORT while printing outputs./tcpconnlat -4        # trace IPv4 family only./tcpconnlat -6        # trace IPv6 family only

tcpdrop:被内核丢弃的 TCP 数据包跟踪

tcpdrop 工具使管理员能够显示内核所丢弃的 TCP 数据包和段的详情.tcpdrop 工具使用 eBPF 特性,而不是捕获和过滤资源密集型的数据包,来直接从内核检索信息。

┌──[root@liruilongs.github.io]-[~]
└─$$tcpdrop   #/usr/share/bcc/tools/tcpdrop
TIME     PID    IP SADDR:SPORT       > DADDR:DPORT   STATE (FLAGS)
13:28:39 32253  4  192.0.2.85:51616  > 192.0.2.1:22  CLOSE_WAIT (FIN|ACK)b'tcp_drop+0x1'b'tcp_data_queue+0x2b9'...13:28:39 1      4  192.0.2.85:51616  > 192.0.2.1:22   CLOSE (ACK)b'tcp_drop+0x1'b'tcp_rcv_state_process+0xe2'...

每次内核丢弃 TCP 数据包和段时,tcpdrop 都会显示连接的详情,包括导致软件包丢弃的内核堆栈追踪

STATE (FLAGS):TCP 连接的状态和相关的 TCP 标志:

  • CLOSE_WAIT (FIN|ACK)

CLOSE_WAIT状态通常意味着本地应用程序已经接收了关闭连接的 FIN 包,但还没有发送它自己的 FIN 包来关闭连接。如果连接长时间处于 CLOSE_WAIT 状态,可能是因为应用程序有 bug 或者没有正确处理关闭的连接。
FIN|ACK 标志表示这个数据包是一个带有 FIN 和 ACK 标志的 TCP 段。这通常是在关闭连接的过程中发送的。

  • CLOSE (ACK)

CLOSE状态表示连接正在关闭,但还没有完全关闭。这通常是正常的,因为 TCP 关闭是一个四次握手的协议,需要双方交换多个数据包来确保连接被正确关闭。ACK标志表示这个数据包是一个TCP确认包,用于确认之前接收到的数据包。

examples:./tcpdrop           # trace kernel TCP drops./tcpdrop -4        # trace IPv4 family only./tcpdrop -6        # trace IPv6 family only

tcplife: TCP 会话追踪

tcplife 工具使用 eBPF 跟踪打开和关闭的 TCP 会话,并打印一行输出来总结每一个会话。管理员可以使用 tcplife 来识别连接和传输的流量数

可以显示到端口 22 (SSH)的连接来检索以下信息:

  • 本地进程 ID(PID)
  • 本地进程名称
  • 本地 IP 地址和端口号
  • 远程 IP 地址和端口号
  • 接收和传输的流量的数量(以 KB 为单位)。
  • 连接处于活跃状态的时间(毫秒)
┌──[root@liruilongs.github.io]-[~]
└─$/usr/share/bcc/tools/tcplife -L 22
PID   COMM    LADDR      LPORT RADDR       RPORT TX_KB  RX_KB      MS
19392 sshd    192.0.2.1  22    192.0.2.17  43892    53     52 6681.95
19431 sshd    192.0.2.1  22    192.0.2.245 43902    81 249381 7585.09
19487 sshd    192.0.2.1  22    192.0.2.121 43970  6998     7 16740.35

列宽调整

# ./tcplife -w
PID   COMM             IP LADDR                      LPORT RADDR                      RPORT  TX_KB  RX_KB MS
26315 recordProgramSt  4  127.0.0.1                  44188 127.0.0.1                  28527      0      0 0.21
3277  redis-server     4  127.0.0.1                  28527 127.0.0.1                  44188      0      0 0.26
26320 ssh              6  fe80::8a3:9dff:fed5:6b19   22440 fe80::8a3:9dff:fed5:6b19   22         1      1 457.52
26321 sshd             6  fe80::8a3:9dff:fed5:6b19   22    fe80::8a3:9dff:fed5:6b19   22440      1      1 458.69
26341 recordProgramSt  4  127.0.0.1                  44192 127.0.0.1                  28527      0      0 0.27
3277  redis-server     4  127.0.0.1                  28527 127.0.0.1                  44192      0      0 0.32

其他的 Demo

examples:./tcplife           # trace all TCP connect()s./tcplife -t        # include time column (HH:MM:SS)./tcplife -w        # wider columns (fit IPv6)./tcplife -stT      # csv output, with times & timestamps./tcplife -p 181    # only trace PID 181./tcplife -L 80     # only trace local port 80./tcplife -L 80,81  # only trace local ports 80 and 81./tcplife -D 80     # only trace remote port 80./tcplife -4        # only trace IPv4 family./tcplife -6        # only trace IPv6 family

tcpstates:显示 TCP 状态更改信息

在 TCP 会话中,TCP 状态会改变。tcpstates 工具使用 eBPF 功能跟踪这些状态变化,并打印包括每个状态持续时间的详细信息。例如,使用 tcpstates 来确定连接是否在初始化状态中花费了太多时间。

如果多个连接同时改变了其状态,使用第一列中的套接字地址(SKADDR)来确定哪些条目属于同一个连接

┌──[root@liruilongs.github.io]-[~]
└─$tcpstates  #/usr/share/bcc/tools/tcpstates
SKADDR           C-PID C-COMM     LADDR           LPORT RADDR           RPORT OLDSTATE    -> NEWSTATE    MS
ffff9fd7e8192000 22384 curl       100.66.100.185  0     52.33.159.26    80    CLOSE       -> SYN_SENT    0.000
ffff9fd7e8192000 0     swapper/5  100.66.100.185  63446 52.33.159.26    80    SYN_SENT    -> ESTABLISHED 1.373
ffff9fd7e8192000 22384 curl       100.66.100.185  63446 52.33.159.26    80    ESTABLISHED -> FIN_WAIT1   176.042
ffff9fd7e8192000 0     swapper/5  100.66.100.185  63446 52.33.159.26    80    FIN_WAIT1   -> FIN_WAIT2   0.536
ffff9fd7e8192000 0     swapper/5  100.66.100.185  63446 52.33.159.26    80    FIN_WAIT2   -> CLOSE       0.006
^C

每次连接改变其状态时,tcpstates 都会显示一个新行,其中包含更新的连接详情。

OLDSTATE    -> NEWSTATE    MS
CLOSE       -> SYN_SENT    0.000
SYN_SENT    -> ESTABLISHED 1.373
ESTABLISHED -> FIN_WAIT1   176.042
FIN_WAIT1   -> FIN_WAIT2   0.536
FIN_WAIT2   -> CLOSE       0.006

其他的一些 Demo

examples:./tcpstates           # trace all TCP state changes./tcpstates -t        # include timestamp column./tcpstates -T        # include time column (HH:MM:SS)./tcpstates -w        # wider columns (fit IPv6)./tcpstates -stT      # csv output, with times & timestamps./tcpstates -Y        # log events to the systemd journal./tcpstates -L 80     # only trace local port 80./tcpstates -L 80,81  # only trace local ports 80 and 81./tcpstates -D 80     # only trace remote port 80./tcpstates -4        # trace IPv4 family only./tcpstates -6        # trace IPv6 family only

tcpsubnet:统计发送到特定子网的 TCP 流量

tcpsubnet 工具汇总并合计了本地主机发往子网的 IPv4 TCP 流量,并按固定间隔显示输出。该工具使用 eBPF 功能来收集并总结数据,以减少开销。

默认情况下,tcpsubnet 为以下子网汇总流量:

  • 127.0.0.1/32
  • 10.0.0.0/8
  • 172.16.0.0/12
  • 192.0.2.0/24/16
  • 0.0.0.0/0

最后一个子网(0.0.0.0/0)是一个全包括选项。tcpsubnet 工具计算与这个全包括条目中前四个不同的子网的所有流量。按照以下流程计算 192.0.2.0/24198.51.100.0/24 子网的流量。到其他子网的流量将在 0.0.0.0/0 全包括子网条目中跟踪。

开始监控发送到 192.0.2.0/24、198.51.100.0/24 以及其他子网的流量数,需注意 0.0.0.0/0 要放到最后面

┌──[root@liruilongs.github.io]-[~]
└─$/usr/share/bcc/tools/tcpsubnet 192.0.2.0/24,198.51.100.0/24,0.0.0.0/0
Tracing... Output every 1 secs. Hit Ctrl-C to end
[02/21/20 10:04:50]
192.0.2.0/24           856
198.51.100.0/24       7467
[02/21/20 10:04:51]
192.0.2.0/24          1200
198.51.100.0/24       8763
0.0.0.0/0              673
...

以字节为单位显示指定子网每秒一次的流量。其他的输出格式

# tcpsubnet -J -fK 192.130.253.110/27,0.0.0.0/0
{"date": "03/05/18", "entries": {"0.0.0.0/0": 2}, "time": "22:46:27"}
{"date": "03/05/18", "entries": {}, "time": "22:46:28"}
{"date": "03/05/18", "entries": {}, "time": "22:46:29"}
{"date": "03/05/18", "entries": {}, "time": "22:46:30"}
{"date": "03/05/18", "entries": {"192.30.253.110/27": 0}, "time": "22:46:31"}
{"date": "03/05/18", "entries": {"192.30.253.110/27": 1}, "time": "22:46:32"}
{"date": "03/05/18", "entries": {"192.30.253.110/27": 18}, "time": "22:46:32"}

其他的 Example

examples:./tcpsubnet                 # Trace TCP sent to the default subnets:# 127.0.0.1/32,10.0.0.0/8,172.16.0.0/12,# 192.168.0.0/16,0.0.0.0/0./tcpsubnet -f K            # Trace TCP sent to the default subnets# aggregated in KBytes../tcpsubnet 10.80.0.0/24    # Trace TCP sent to 10.80.0.0/24 only./tcpsubnet -J              # Format the output in JSON.

tcptop:跟踪 IP 端口的网络吞吐量

tcptop 工具以 KB 为单位显示主机发送并接收的 TCP 流量。这个报告会自动刷新并只包含活跃的 TCP 连接。该工具使用 eBPF 功能,因此开销非常低。

┌──[root@liruilongs.github.io]-[~]
└─$/usr/share/bcc/tools/tcptop
13:46:29 loadavg: 0.10 0.03 0.01 1/215 3875PID    COMM         LADDR           RADDR              RX_KB   TX_KB
3853   3853         192.0.2.1:22    192.0.2.165:41838  32     102626
1285   sshd         192.0.2.1:22    192.0.2.45:39240   0           0
...

对于没有捕获到进程名的连接,会使用 PID 代替进程,说明他的生命周期很短

命令的输出只包括活跃的 TCP 连接。如果本地或者远程系统关闭了连接,则该连接在输出中不再可见。

不清除屏幕打印

[root@liruilongs ~]# /usr/share/bcc/tools/tcptop -C
Tracing... Output every 1 secs. Hit Ctrl-C to end15:52:52 loadavg: 0.03 0.07 0.02 1/708 3057186PID     COMM         LADDR                 RADDR                  RX_KB  TX_KB
1701    b'barad_agen 10.0.16.15:51796      169.254.0.4:80             0      0
362732  b'tat_agent' 10.0.16.15:52488      169.254.0.138:8186         0      015:52:53 loadavg: 0.03 0.07 0.02 5/708 3057187PID     COMM         LADDR                 RADDR                  RX_KB  TX_KB
362732  b'tat_agent' 10.0.16.15:52488      169.254.0.138:8186         0      015:52:54 loadavg: 0.03 0.07 0.02 4/710 3057191PID     COMM         LADDR                 RADDR                  RX_KB  TX_KB
362732  b'tat_agent' 10.0.16.15:52488      169.254.0.138:8186         0      015:52:55 loadavg: 0.03 0.07 0.02 4/709 3057196PID     COMM         LADDR                 RADDR                  RX_KB  TX_KB
1701    b'barad_agen 10.0.16.15:59568      169.254.0.4:80             0      0
362732  b'tat_agent' 10.0.16.15:52488      169.254.0.138:8186         0      0
^C
15:52:56 loadavg: 0.03 0.07 0.02 3/708 3057199PID     COMM         LADDR                 RADDR                  RX_KB  TX_KB
362732  b'tat_agent' 10.0.16.15:52488      169.254.0.138:8186         0      0
[root@liruilongs ~]#

其他的 Example

examples:./tcptop           # trace TCP send/recv by host./tcptop -C        # don't clear the screen./tcptop -p 181    # only trace PID 181./tcptop --cgroupmap ./mappath  # only trace cgroups in this BPF map./tcptop --mntnsmap mappath   # only trace mount namespaces in the map./tcptop -4        # trace IPv4 family only./tcptop -6        # trace IPv6 family only

solisten:追踪 IPv4 和 IPv6 侦听尝试

solisten 工具追踪所有 IPv4 和 IPv6 侦听尝试。它跟踪监听尝试,包括最终失败或者不接受连接的监听程序。当程序要侦听 TCP 连接时,程序会追踪内核调用的功能。

┌──[root@liruilongs.github.io]-[~]
└─$/usr/share/bcc/tools/solisten
PID    COMM           PROTO         BACKLOG     PORT     ADDR
3643   nc             TCPv4         1           4242     0.0.0.0
3659   nc             TCPv6         1           4242     2001:db8:1::1
4221   redis-server   TCPv6         128         6379     ::
4221   redis-server   TCPv4         128         6379     0.0.0.0

PID:进程ID,表示哪个进程正在使用该套接字。
COMM:与该套接字关联的进程名。
PROTO:套接字使用的协议,这里是 TCPv4(IPv4 上的 TCP)或 TCPv6(IPv6 上的 TCP)。
BACKLOG:套接字监听队列的长度。当客户端尝试连接到服务器时,如果服务器忙于处理其他连接,那么客户端的连接请求将被放入这个队列中等待。
PORT:套接字正在监听的端口号。
ADDR:套接字绑定的地址。0.0.0.0 表示该套接字正在监听所有可用的 IPv4 地址,而 :: 表示它正在监听所有可用的 IPv6 地址。对于 2001:db8:1::1,这是一个具体的 IPv6 地址。

其他的 Example

Examples:./solisten.py              # Stream socket listen./solisten.py -p 1234      # Stream socket listen for specified PID only./solisten.py --netns 4242 # " for the specified network namespace ID only./solisten.py --show-netns # Show network ns ID (useful for containers)

softirqs:软中断的服务时间统计

softirqs 工具总结了服务软中断(soft IRQ)所花费的时间,并将这个时间显示为总计或直方图分布。这个工具使用 irq:softirq_enterirq:softirq_exit 内核追踪点,是一个稳定的追踪机制。

┌──[root@liruilongs.github.io]-[~]
└─$/usr/share/bcc/tools/softirqs
Tracing soft irq event time... Hit Ctrl-C to end.
^C
SOFTIRQ          TOTAL_usecs
tasklet                  166
block                   9152
net_rx                 12829
rcu                    53140
sched                 182360
timer                 306256

netqtop:统计网卡上数据包大小和计数

netqtop 工具显示有关特定网络接口的每个网络队列上收到的(RX)和传输的(TX)数据包属性的统计信息。统计包括:

  • 每秒字节数(BPS)
  • 每秒数据包数(PPS)
  • 平均数据包大小
  • 数据包总数

要生成这些统计数据,netqtop 跟踪执行传输数据包 net_dev_start_xmit 和接收数据包 netif_receive_skb 的事件的内核功能。

┌──[root@liruilongs.github.io]-[~]
└─$/usr/share/bcc/tools/netqtop -n enp1s0 -i 2
Fri Jan 31 18:08:55 2023
TXQueueID	avg_size   [0, 64)	[64, 512)  [512, 2K)  [2K, 16K)  [16K, 64K)0      	0      	0      	0      	0      	0      	0Total  	0      	0      	0      	0      	0      	0RXQueueID	avg_size   [0, 64)	[64, 512)  [512, 2K)  [2K, 16K)  [16K, 64K)0      	38.0   	1      	0      	0      	0      	0Total  	38.0   	1      	0      	0      	0      	0
-----------------------------------------------------------------------------
Fri Jan 31 18:08:57 2023
TXQueueID	avg_size   [0, 64)	[64, 512)  [512, 2K)  [2K, 16K)  [16K, 64K)0      	0      	0      	0      	0      	0      	0Total  	0      	0      	0      	0      	0      	0RXQueueID	avg_size   [0, 64)	[64, 512)  [512, 2K)  [2K, 16K)  [16K, 64K)0      	38.0   	1      	0      	0      	0      	0Total  	38.0   	1      	0      	0      	0      	0

显示 2 秒时间间隔的字节大小范围内的数据包数:如果平均队列大小(avg_size)持续较高,这可能表示网络接口正在遭受拥塞或延迟。

博文部分内容参考

© 文中涉及参考链接内容版权归原作者所有,如有侵权请告知 😃


BCC工具包 帮助文档

https://docs.redhat.com/zh_hans/documentation/red_hat_enterprise_linux/9/html/configuring_and_managing_networking/network-tracing-using-the-bpf-compiler-collection_configuring-and-managing-networking


© 2018-2024 liruilonger@gmail.com, All rights reserved. 保持署名-非商用-相同方式共享(CC BY-NC-SA 4.0)

这篇关于TCP 连接排故:使用 BPF BCC工具包进行网络跟踪的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/997856

相关文章

W外链微信推广短连接怎么做?

制作微信推广链接的难点分析 一、内容创作难度 制作微信推广链接时,首先需要创作有吸引力的内容。这不仅要求内容本身有趣、有价值,还要能够激起人们的分享欲望。对于许多企业和个人来说,尤其是那些缺乏创意和写作能力的人来说,这是制作微信推广链接的一大难点。 二、精准定位难度 微信用户群体庞大,不同用户的需求和兴趣各异。因此,制作推广链接时需要精准定位目标受众,以便更有效地吸引他们点击并分享链接

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]