Linux网络抓包工具

Linux中有很多抓包工具,如ngrep、tcpdump与tshark等,它们有很多用法与使用场景,下面我将结合例子讲解各工具的用法以及它们的使用场景。

ngrep

ngrep是一款抓包工具,它将抓到的包数据以文本形式直接显示出来,非常适用于包数据包含文本的抓包分析(如HTTP、MySQL),如下:

抓HTTP请求

有时我们会遇到这种场景,服务方提供http接口给调用方使用,调用方传递一个参数值,服务方收到的结果不一样!
这种情况,有可能是调用方的请求方式有问题,也有可能是服务方有请求拦截器导致问题,如何辨别问题是在哪一方呢?这时用ngrep抓包工具确认一下包内容再合适不过了,如下:

# -d any表示抓取所有网卡的数据包# -W byline 一般用于HTTP抓包,方便查看
$ ngrep -d any -W byline port 8080


如上,ngrep会将非可见字符显示为.,所以上面http请求每行后都有个.,指的是HTTP协议换行符\r\n中的\r,而最前面的T代表这是TCP协议的包。

抓取SQL

# 抓取3961端口,过滤出包数据中带select的网络包,即查询SQL# -A 2 匹配包之后的2个包也显示出来
$ ngrep -d any -A 2 'select' port 3961


可以发现,mysql回包都有.def.这样的字样,我们可以根据这个来判断mysql响应包。

ngrep带上-T参数,可以额外打印出前后两个包的间隔时间,这样我们根据回包的间隔时间,就能大概看到SQL查询的耗时了,如下:

# -W single让包数据在一行上显示,便于awk等文本工具处理# -s 200 包大小最多抓200字节,多余数据不显示# -T 打印出两个包之间的间隔时间,单位秒# awk部分脚本逻辑是,一直抓包直到发现回包慢于1秒时停止
$ ngrep -d any -W single -s 200 -T 'select|def' port 3961 \
    | awk '{print} $1~/T/ && /.def./ && $2>1 && $2<1000 {exit(0)}'

tcpdump

tcpdump是一个通用抓包工具,一般用它来抓各种协议的网络包数据,然后再使用wireshark分析,如下:

抓取3961端口网络包

# -c 10000表示最多抓1万个包
$ tcpdump -i any -s 0 -c 10000 tcp and port 3961 -w ./target.cap

# -G 600 表示600s保存一个抓包文件,避免单文件太大
$ tcpdump -i any -s 0 -G 600 tcp and port 3961 -w ./target_%Y_%m%d_%H%M_%S.pcap

wireshark分析

抓取的target.cap是mysql的网络包数据,它是二进制的,无法直接查看,需要使用wireshark分析,下载地址如下:
https://www.wireshark.org/download.html

默认情况下,wireshark认为3306端口的数据包是MySQL协议的,而上面我们mysql端口是3961,导致wireshark无法将包数据识别为MySQL协议,显示的是TCP原始数据,不方便查看,所以我们需要告诉wireshark使用MySQL协议解析3961端口数据包,如下:

a. 先decode as...相应端口使用MySQL协议解析:

…

b. 输入mysql.query contains "id=24218",查看SQL中包含id=24218的数据包,如下:

网络慢还是后端处理慢?


为方便分析耗时,一般建议在wireshark上再添加如下两列:

  • tcpDelta = tcp.time_delta,表示在当前tcp连接中,当前包相对上一个包的时间差。
  • ack_rtt = tcp.analysis.ack_rtt,表示tcp中的ack包,相对其数据包的时间差。

如下,找耗时最大的包:

…

…

…

发现对于select sleep(2.0)这条SQL,服务端回复ack很快,而在回复数据包时变慢,说明是慢在MySQL处理上,而非网络里,因为如果网络慢的话,ack应该也会变慢的。

tshark

tshark是wireshark工具的命令行版本,使用的方法与wireshark是类似的,如下:

# -i any 任意网卡的数据都抓取# -f 指定抓什么协议,什么端口# -d 类似wireshark的decode as,将3961解析为mysql协议# -Y 类似wireshark上面的显示过滤器# -T 指定数据输出格式,fields表示tab分隔格式# -e 指定输出的字段# -E header=y 指定输出标题行
$ sudo tshark -ni any -f 'tcp and port 3961' -d 'tcp.port==3961,mysql' \
    -T fields  -e frame.number -e frame.time_epoch -e frame.time_delta_displayed  \
    -e ip.src -e tcp.srcport -e tcp.dstport -e ip.dst -e tcp.stream -e tcp.len -e tcp.nxtseq \
    -e tcp.time_delta -e tcp.analysis.ack_rtt \
    -e _ws.col.Info -e mysql.query -E header=y > packets.tsv

# 查看抓包数据
$ csvlook -It packets.tsv | less -iSFX
| frame.number | frame.time_epoch     | frame.time_delta_displayed | ip.src    | tcp.srcport | tcp.dstport | ip.dst    | tcp.stream | tcp.len | tcp.nxtseq | tcp.time_delta | tcp.analysis.ack_rtt | _ws.col.Info                                                                     | mysql.query                                                                     |
| ------------ | -------------------- | -------------------------- | --------- | ----------- | ----------- | --------- | ---------- | ------- | ---------- | -------------- | -------------------- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| 1            | 1639287428.374886956 | 0.000000000                | 127.0.0.1 | 39262       | 3961        | 127.0.0.1 | 0          | 5       | 6          | 0.000000000    |                      | Request Ping                                                                     |                                                                                 |
| 2            | 1639287428.375043740 | 0.000156784                | 127.0.0.1 | 3961        | 39262       | 127.0.0.1 | 0          | 0       | 1          | 0.000156784    | 0.000156784          | 3961 → 39262 [ACK] Seq=1 Ack=6 Win=512 Len=0 TSval=696789627 TSecr=696789627     |                                                                                 |
| 3            | 1639287428.375268878 | 0.000225138                | 127.0.0.1 | 3961        | 39262       | 127.0.0.1 | 0          | 11      | 12         | 0.000225138    |                      | Response OK                                                                      |                                                                                 |
| 4            | 1639287428.375289961 | 0.000021083                | 127.0.0.1 | 39262       | 3961        | 127.0.0.1 | 0          | 0       | 6          | 0.000021083    | 0.000021083          | 39262 → 3961 [ACK] Seq=6 Ack=12 Win=512 Len=0 TSval=696789627 TSecr=696789627    |                                                                                 |
| 5            | 1639287428.375886139 | 0.000596178                | 127.0.0.1 | 39262       | 3961        | 127.0.0.1 | 0          | 55      | 61         | 0.000596178    |                      | Request Query                                                                    | select id from app_log al order by id desc limit 1                              |
| 6            | 1639287428.375906403 | 0.000020264                | 127.0.0.1 | 3961        | 39262       | 127.0.0.1 | 0          | 0       | 12         | 0.000020264    | 0.000020264          | 3961 → 39262 [ACK] Seq=12 Ack=61 Win=512 Len=0 TSval=696789628 TSecr=696789628   |                                                                                 |
| 7            | 1639287428.377206294 | 0.001299891                | 127.0.0.1 | 3961        | 39262       | 127.0.0.1 | 0          | 76      | 88         | 0.001299891    |                      | Response                                                                         |                                                                                 |
| 8            | 1639287428.377226652 | 0.000020358                | 127.0.0.1 | 39262       | 3961        | 127.0.0.1 | 0          | 0       | 61         | 0.000020358    | 0.000020358          | 39262 → 3961 [ACK] Seq=61 Ack=88 Win=512 Len=0 TSval=696789629 TSecr=696789629   |                                                                                 |
| 9            | 1639287428.378921659 | 0.001695007                | 127.0.0.1 | 39262       | 3961        | 127.0.0.1 | 0          | 84      | 145        | 0.001695007    |                      | Request Query                                                                    | select id,log_info,create_time,update_time,add_time from app_log whereid=27371 |
| 10           | 1639287428.378942384 | 0.000020725                | 127.0.0.1 | 3961        | 39262       | 127.0.0.1 | 0          | 0       | 88         | 0.000020725    | 0.000020725          | 3961 → 39262 [ACK] Seq=88 Ack=145 Win=512 Len=0 TSval=696789631 TSecr=696789631  |                                                                                 |
| 11           | 1639287428.380450661 | 0.001508277                | 127.0.0.1 | 3961        | 39262       | 127.0.0.1 | 0          | 412     | 500        | 0.001508277    |                      | Response                                                                         |                                                                                 |
| 12           | 1639287428.380471636 | 0.000020975                | 127.0.0.1 | 39262       | 3961        | 127.0.0.1 | 0          | 0       | 145        | 0.000020975    | 0.000020975          | 39262 → 3961 [ACK] Seq=145 Ack=500 Win=509 Len=0 TSval=696789633 TSecr=696789633 |                                                                                 |
| 13           | 1639287430.051942681 | 1.671471045                | 127.0.0.1 | 39262       | 3961        | 127.0.0.1 | 0          | 22      | 167        | 1.671471045    |                      | Request Query                                                                    | select sleep(2.0)                                                               |
| 14           | 1639287430.051972761 | 0.000030080                | 127.0.0.1 | 3961        | 39262       | 127.0.0.1 | 0          | 0       | 500        | 0.000030080    | 0.000030080          | 3961 → 39262 [ACK] Seq=500 Ack=167 Win=512 Len=0 TSval=696791304 TSecr=696791304 |                                                                                 |
| 15           | 1639287432.053394353 | 2.001421592                | 127.0.0.1 | 3961        | 39262       | 127.0.0.1 | 0          | 65      | 565        | 2.001421592    |                      | Response                                                                         |                                                                                 |
| 16           | 1639287432.053520674 | 0.000126321                | 127.0.0.1 | 39262       | 3961        | 127.0.0.1 | 0          | 0       | 167        | 0.000126321    | 0.000126321          | 39262 → 3961 [ACK] Seq=167 Ack=565 Win=512 Len=0 TSval=696793306 TSecr=696793305 |

并且,tshark也可以直接分析tcpdump抓到的包数据,如下:

# -Y 类似于wireshark中的显示过滤器
$ tshark -d 'tcp.port==3961,mysql' -Y 'mysql.query contains "id=21"' -r target.cap -T fields -e frame.number -e mysql.query
5       select id,log_info,create_time,update_time,add_time from app_log whereid=21527
13      select id,log_info,create_time,update_time,add_time from app_log whereid=21518
25      select id,log_info,create_time,update_time,add_time from app_log whereid=21007
52      select id,log_info,create_time,update_time,add_time from app_log whereid=21505

# tshark包还附带一个editcap命令# 可用于截取抓包数据的一段时间范围
$ editcap -F libpcap -A "2013-07-20 23:00:00" -B "2013-07-20 23:20:00" input.pcap output.pcap

pcap-filter与wireshark-filter

像ngrep、tcpdump和tshark -f使用的都是pcap-filter语法,用于抓取网络包时,对抓到的网络包进行过滤,如下是tcpdump使用pcap-filter的一些常见语法。

# 抓取指定主机的数据包
$ tcpdump -ni any host 210.27.48.1
# 抓取来自210.27.48.1主机和23端口的tcp包
$ tcpdump -ni any tcp src host 210.27.48.1 and port 23 
# 抓取来自网络10.234.10.0/24的主机发来的目的端口是80或8080的tcp包
$ tcpdump -ni any tcp src net 10.234.10.0/24 and dst port '(80 or 8080)'# 抓tcp协议的rst包
$ tcpdump -ni any -s0 tcp and 'tcp[13] & 4 != 0 ' -vvv
# 抓tcp协议的fin包
$ tcpdump -ni any -s0 tcp and 'tcp[13] & 1 != 0 ' -vvv

详细语法可以man pcap-filter查看,或访问:https://wiki.wireshark.org/CaptureFilters

而wireshark界面上的显示过滤器,以及tshark -Y使用的都是wireshark-filter语法,用于对已抓取的数据包进行进一步过滤分析,如下是tshark使用wireshark-filter的一些常见语法。

# 过滤指定主机与指定端口数据包
$ tshark -Y 'ip.addr==127.0.0.1 and tcp.port==3961'# 解析为http协议,并使用http协议字段过滤
$ tshark -d 'tcp.port==8080,http' -Y 'http.request.uri contains "/get"'# 解析为mysql协议,并使用mysql协议字段过滤
$ tshark -d 'tcp.port==3961,mysql' -Y 'mysql.query contains "id=21"'

详细语法可以man wireshark-filter查看,或访问:https://wiki.wireshark.org/DisplayFilters

总结

可见,使用ngrep、tcpdump、tshark分析网络问题是非常有帮助的,一定要在工作中多多尝试使用,熟悉它们的各种用法。

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/165268.html<

赞 (0)
管理的头像管理
上一篇2025-03-20 00:11
下一篇 2025-03-20 00:13

相关推荐

  • jsp空间购买和交换数据空间怎么买,有哪些注意事项?

    购买JSP空间时,是否考虑过数据交换空间的性能?简米科技(2003年始创,23年行业沉淀)与酷番云(工信部一类增值电信全牌照)这类持牌自营机房的服务商,能确保数据交换的高效稳定,是值得优先选择的合作伙伴,为什么JSP空间需要搭配独立的数据交换空间从JSP应用特性看数据交换需求JSP基于Java技术,常用于企业级……

    2026-08-11
    0
  • 建网站用香港空间效果怎么样,香港空间稳定吗?

    建网站用香港空间,对于创建网站资产来说,核心价值在于免备案和全球带宽优势,尤其适合外贸、跨境电商和需要快速启动的项目,但你必须权衡国内访问延迟,并选择有资质的服务商以保证资产安全,香港空间的核心优势与适用边界免备案:节省时间就是节省成本国内服务器需要备案,通常需要10到20天,香港空间无需备案,域名解析后即可上……

    2026-08-11
    0
  • Java连接云数据库的方法是什么,如何操作

    Java连接云数据库的核心在于通过JDBC驱动,结合云服务商提供的连接地址、端口、数据库名及认证信息,配置安全策略(如SSL、IP白名单),即可实现稳定高效的远程数据库访问,基础准备:JDBC驱动与依赖管理连接云数据库前,需要确保开发环境具备对应的JDBC驱动,以最常见的MySQL为例,你需要引入mysql-c……

    2026-08-11
    0
  • 建网站公安联网备案必须使用数据码吗,备案流程是什么

    网站备案包括ICP备案和公安联网备案,两者缺一不可,公安联网备案必须使用服务商提供的数据码,选择持有合法资质的服务商是顺利通过备案的前提,为什么网站必须进行公安联网备案根据公安部《计算机信息网络国际联网安全保护管理办法》,网站开通后30日内必须到公安机关办理备案手续,未完成公安备案的网站,面临责令整改、关闭网站……

    2026-08-10
    0
  • 建一个企业网站大概需要多少钱?,怎么收费?

    建网站要多少钱,没有一个固定的数字,几百到几万都可能,但真正的“创建网站资产”绝不仅仅是初次投入的成本,而是基于长期稳定、合规和安全的持续性投入,其中核心取决于你选择了什么样的“地基”来承载你的业务,建站预算的构成与行业基准当你开始规划一个网站,最先面对的就是预算问题,一个常见的误区是只关注网站“看起来”的建造……

    2026-08-10
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注