想象一座大型快递分拣中心:成千上万的包裹在传送带上飞奔,从一个分拣口滑向另一个分拣口。如果某个包裹丢了、迟了、或者被送错了地方,负责人往往一头雾水——它到底经过了哪条传送带?在哪个节点卡住了?这时如果传送带旁装上一圈摄像头,把每个流经的包裹都拍下来,事后就能逐帧回放,真相便会水落石出。 tcpdump 和 ngrep 就是网络世界的“传送带摄像头”。tcpdump 像一架架在网卡旁的摄像机,忠实记录每一个进出网卡的数据包——也就是“电子包裹”;ngrep 则像一台能透视包裹内部单据的扫描仪,直接查看应用层内容。配合 Wireshark 这个“视频分析室”,网络工程师就能像侦探一样,从一条条记录里找出故障的蛛丝马迹。这篇文章,就是教你装好、用好这套“监控回放系统”。

岗位关联

学会抓包,相当于拥有网络排障的“现场监控回放”能力。无论是排查连接超时、定位协议错误,还是做安全审计,tcpdump/ngrep 都能把抽象的网络问题变成看得见、查得清的硬证据。这是网络工程师、SRE 和 DevOps 的基础功。

目录
  1. 可视化演示
  2. 抓包基础
  3. 过滤表达式
  4. 保存回放
  5. ngrep抓应用
  6. 高级技巧
  7. 协议定位
  8. 排查实战
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示Wireshark抓包过程与协议层级解析,交互切换流量捕获视图与协议 dissect 视图。

本节配有交互动效(进入视口后自动加载,约 3KB)。

网络流量捕获 多协议数据包(TCP/HTTP/DNS/TLS/ARP)在网络接口流动,虚线为捕获点 经过捕获点(CAP)的数据包被记录,右侧列表显示包序号、协议与长度 未捕获的包以低透明度显示,捕获的包高亮并记录到抓包列表 Wireshark通过网卡混杂模式捕获所有经过的网络流量进行协议分析

抓包基础

快递中心要在传送带旁装摄像头,首先要选对机位——对着哪条传送带、拍哪个区域,决定了你能看到什么。tcpdump 也一样,第一步是选对网卡。服务器通常有好几张网卡(eth0、eth1……),数据包从哪张网卡进出,你就得把“摄像头”架在哪张上。如果机位选错,摄像头对着空墙,什么也录不到。

数据包是网络上的“电子包裹”,每个包裹都自带一张“电子快递单”。这张单子上有五个关键信息:源 IP(寄件人地址)、源端口(寄件人的门牌号)、目的 IP(收件人地址)、目的端口(收件人的门牌号)、协议类型(包裹走的运输方式,是 TCP 的可靠汽车还是 UDP 的快递飞机)。这五个字段合在一起,称为五元组,是后面所有过滤和分析的基石。

tcpdump 的基本用法并不复杂:tcpdump -i eth0 指定在 eth0 网卡上抓包;tcpdump -c 100 让它在抓到 100 个包后自动停止;因为要读取原始套接字,所以几乎总是需要 root 权限。另外要注意,默认情况下 tcpdump 不抓回环接口 lo 上的包,如果要排查本机到本机的服务,要用 -i lo 主动指定。

把摄像头架对位置、认得懂快递单,抓包的第一步就算迈出去了。机位选错,后面一切分析都无从谈起——这正是 tcpdump 中 -i 参数的意义所在。

packet=(ipsrc, portsrc, ipdst, portdst, proto)\mathrm{packet} = (ip_{src},\ port_{src},\ ip_{dst},\ port_{dst},\ proto)
这个“公式”说:一个数据包可以用五个字段唯一描述,就像一张快递单上的五个关键栏位。
  1. 五元组整体定义数据包的五要素组合,唯一标识一段通信,相当于快递单的完整信息栏。
    (ipsrc, portsrc, ipdst, portdst, proto)(ip_{src},\ port_{src},\ ip_{dst},\ port_{dst},\ proto)
  2. ip_src 源 IP发出数据的机器地址,相当于寄件人所在的城市。
    ipsrcip_{src}
  3. port_src 源端口发起通信的应用程序临时门牌号,通常是浏览器随机开的高位端口。
    portsrcport_{src}
  4. ip_dst 目的 IP接收数据的机器地址,相当于收件人所在的城市。
    ipdstip_{dst}
  5. port_dst 目的端口接收方服务的固定门牌号,如 80 是 HTTP、443 是 HTTPS。
    portdstport_{dst}
  6. proto 传输层协议包裹选择的运输方式,TCP 保证送达,UDP 追求速度。
    protoproto

过滤表达式

传送带上的包裹太多,如果每个都录,事后回放能看花眼。于是你给摄像头加了筛选器:只录寄往上海的,或者只录从北京来的。tcpdump 的过滤表达式就是这个筛选器,它决定哪些包裹值得进入你的视野。

最常用的过滤维度有三个。按主机过滤,host 192.168.1.1 表示只看与这台机器相关的包;按端口过滤,port 80 表示只看源或目的端口是 80 的包;按协议过滤,tcp、udp、icmp 分别锁定对应协议。光是这三个维度,已经能帮你在海量流量中缩小包围圈。

真正强大的地方在于组合。用 and(与)、or(或)、not(非)可以把条件串起来,比如 host 10.0.0.1 and port 80,意思是“只看这台机器上 80 端口的流量”。这就像告诉摄像头:只录寄往或来自指定地址、且走指定门牌号的包裹。组合条件让排障从“大海捞针”变成“精准定位”。

筛选器用得好,抓包效率翻倍。面对高峰期每秒上万的数据包,一个精准的过滤表达式,能让你从一片噪音中直接看到想找的那一个包裹——这就是排障的“先手优势”。

pass(p)  ⟺  (p.ipsrc=h∨p.ipdst=h)∧(p.port=80)\mathrm{pass}(p) \iff (p.ip_{src}=h \lor p.ip_{dst}=h) \land (p.port=80)
过滤表达式的本质是一个布尔判断:数据包 p 只有同时满足主机条件(源或目的 IP 等于 h)和端口条件(端口为 80)才被放行。
  1. 判定通过函数定义 pass(p) 表示数据包 p 是否被抓包条件选中。
    p↦pass(p)p \mapsto \mathrm{pass}(p)
  2. 主机条件源 IP 或目的 IP 等于目标主机 h,相当于寄件人或收件人是目标地址才关注。
    p.ipsrc=h∨p.ipdst=hp.ip_{src}=h \lor p.ip_{dst}=h
  3. 端口条件源端口或目的端口等于 80,相当于收寄件“门牌号”必须是 HTTP 服务。
    p.port=80p.port=80
  4. 逻辑与组合两个条件用“与”连接,需要同时满足,即交集筛选。
    (A)∧(B)(A) \land (B)

保存回放

摄像头是实时的,错过就没了。为了事后能慢慢看,快递中心会把录像存成文件。tcpdump 也自带“录像机”:用 -w 参数把抓到的包写入 pcap 文件,用 -r 参数随时读回来看。pcap 是抓包数据的标准保存格式,Wireshark、ngrep 等工具都能读。

写入文件很简单:tcpdump -i eth0 -w capture.pcap。抓包结束后按 Ctrl+C 停止,所有包就被保存在文件里了。要注意的是,-w 保存的是原始二进制包,不能用 cat 直接看,必须用 -r 读回:tcpdump -r capture.pcap。读回之后,之前的过滤表达式同样可以再用,相当于在录像里继续筛选。

把 pcap 文件拖进 Wireshark,等于把监控录像搬进了分析室。Wireshark 会把每个包解码成可读的协议字段,还能画 TCP 时序图、统计会话、追踪 HTTP 流。生产环境不方便慢慢研究时,抓一份 pcap 带回本地分析,是网络排障的经典姿势。

有了录像和回放,故障就不再是“转瞬即逝的灵异事件”。哪怕当时没看清,只要 pcap 在手,就能像侦探反复看监控一样,把每一个可疑的瞬间放大、放慢、逐帧研究。

pcap={p1,p2,…,pn}\mathrm{pcap}=\{p_1,p_2,\dots,p_n\}
pcap 文件本质就是一个按时间顺序排列的数据包集合,像一卷连续帧的监控录像带。
  1. pcap 文件是集合抓包文件在逻辑上等价于一个有序的数据包序列。
    F={p1,p2,…,pn}\mathcal{F}=\{p_1,p_2,\dots,p_n\}
  2. 写入操作 -w把实时抓到的包逐个写入文件,相当于录像键。
    write(pi)→F\mathrm{write}(p_i) \to \mathcal{F}
  3. 读取操作 -r从文件按顺序读回数据包,相当于回放键。
    F→read(pi)\mathcal{F} \to \mathrm{read}(p_i)

ngrep抓应用

tcpdump 的镜头是“远观”——它看到的是包裹外表和快递单。可有些时候,你真正关心的是包裹里面装了什么。比如排查一个 API 请求,你想确认请求体里到底有没有带上正确的参数。这时候就需要 ngrep:一台能“透视”包裹内部单据的扫描仪。

ngrep 的全称是 network grep,它把 grep 的文本匹配能力搬到了网络上。最经典的用法是抓 HTTP 请求:ngrep -q 'GET|POST' 'host 10.0.0.1',意思是“只看发往 10.0.0.1 的请求中,应用层内容匹配 GET 或 POST 的数据包”。它会直接把匹配到的内容打印在终端上,实时可见。

ngrep 的匹配基于正则表达式,灵活度很高。想找登录接口,就匹配 'user|passwd';想看某个响应码,就匹配 'HTTP/1.1 500'。它和 tcpdump 的分工很清晰:tcpdump 负责看你关心的包,ngrep 负责看包里的内容是否包含你关心的信息——一个是交通监控,一个是安检扫描。

tcpdump 告诉你“包裹从哪里来到哪里去”,ngrep 告诉你“包裹里装了什么”。两者配合,网络问题往往在几分钟内就能从“现象”推进到“根因”。下次排查接口联调问题时,别忘了这台透视扫描仪。

match(data, regex)  ⟺  ∃s∈segments(data): regex(s)\mathrm{match}(data,\ regex) \iff \exists s \in \mathrm{segments}(data):\ \mathrm{regex}(s)
ngrep 的匹配逻辑是:把应用层数据分段,只要任意一个片段命中了正则表达式,这个包就算匹配成功。
  1. 数据分片把应用层负载切分成可独立匹配的文本片段。
    segments(data)={s1,s2,…,sk}\mathrm{segments}(data)=\{s_1,s_2,\dots,s_k\}
  2. 正则匹配片段用正则表达式对每个片段执行匹配,判断是否包含目标模式。
    regex(si)\mathrm{regex}(s_i)
  3. 存在性判定只要存在至少一个片段匹配成功,整体结果即为真。
    ∃si∈S: regex(si)\exists s_i \in S:\ \mathrm{regex}(s_i)

高级技巧

摄像头用久了,你会发现它还能更聪明:比如只录特定颜色的包裹。tcpdump 的 BPF(Berkeley Packet Filter)语法,就是这样一种“智能识别”能力。它允许你直接读取包里的二进制字段做判断,精度远超 host/port 这些常规关键字。

最经典的 BPF 例子是过滤 TCP 握手包。TCP 头的第 13 个字节存放八个标志位,其中第 2 位(数值 2)是 SYN 标志。表达式 tcp[13] & 2 != 0 的意思是:读取 TCP 头第 13 个字节,和 2 做按位与,结果不为 0 就说明这个包带 SYN 标志。这就是抓三次握手的精确姿势。

另一个实战话题是 TLS 解密。HTTPS 流量是加密的,直接看只能看到乱码。但如果你能拿到会话密钥,就能“透视”密文。方法是在客户端设置环境变量 SSLKEYLOGFILE=/path/keys.log,让浏览器或 curl 把会话密钥导出到文件,再在 Wireshark 里指定这个密钥文件,就能解开加密内容。此外,抓包有性能开销,生产环境务必用 -c 限制数量、用过滤表达式缩小范围,别让“监控”本身拖垮业务。

高级技巧的本质,是让你从“看包裹”进化到“看懂包裹内部结构”。BPF 让你精准筛选,TLS 解密让你穿透加密外壳。掌握这些,你的抓包能力就从“会用工具”升级为“精通协议”。

tcp[13]&0x02≠0\mathrm{tcp}[13] \mathbin{\&} \mathrm{0x02} \neq 0
BPF 表达式的本质是“位运算过滤器”:对 TCP 头的标志位字节做按位与,判断某个特定标志是否为 1。
  1. 读取偏移字节tcp[13] 表示取 TCP 头第 13 个字节,该字节的二进制位正好对应各标志位。
    tcp[13]\mathrm{tcp}[13]
  2. 按位与掩码0x02 的二进制是 00000010,与操作后只保留第 2 位(SYN 位)。
    tcp[13]&0x02\mathrm{tcp}[13] \mathbin{\&} \mathrm{0x02}
  3. 非零判定结果不为 0 说明 SYN 位确实是 1,即该包是握手发起包。
    tcp[13]&0x02≠0\mathrm{tcp}[13] \mathbin{\&} \mathrm{0x02} \neq 0

协议定位

快递单有不同的联次:发件联、中转联、签收联。网络协议也有自己的一套“单据体系”。学会在抓包结果里快速认出这些单据,是排障的核心功夫。最常见的三套单据:TCP 三次握手的连接单据、DNS 查询的名字解析单据、HTTP 请求响应的应用单据。

TCP 三次握手是每次连接的开场白。客户端先发一个 SYN 包(我想连你),服务端回 SYN-ACK(好的,我准备好了),客户端再回 ACK(收到,开始通信)。三次握手缺任何一步,连接都建立不起来。抓到包后,一眼看出缺少哪个标志位,问题方向就有了。

DNS 查询负责把域名解析成 IP,相当于快递中心的地址簿查询。抓包里看到 A? example.com 就是查询记录,看到应答里没有 IP 或返回 NXDomain,就是域名解析失败。HTTP 字段则更贴近应用:请求行、状态码、Header 里的 Content-Type、Cookie,都直接反映业务状态。还有一个常客是 ICMP——ping 命令用的就是它,type 和 code 字段能告诉你网络不可达还是超时。

认识这些“单据”,就像老快递员熟记各种面单的格式。抓包里每一条记录都在无声地讲述网络发生了什么,而协议定位能力,就是你能听懂这些讲述的耳朵。

SYN→ SYN ⁣− ⁣ACK ACK\mathrm{SYN} \xrightarrow{\ \mathrm{SYN\!-\!ACK}\ } \mathrm{ACK}
三次握手可视为一条状态转移链:客户端发起 SYN,服务端用 SYN-ACK 应答,客户端再用 ACK 确认,连接随即建立。
  1. SYN 发起连接客户端发出标志位 SYN=1 的包,主动要求建立连接。
    SYN\mathrm{SYN}
  2. SYN-ACK 应答服务端同意后,同时置 SYN 和 ACK 两个标志,表示“收到了,并回应”。
    SYN ⁣− ⁣ACK\mathrm{SYN\!-\!ACK}
  3. ACK 最终确认客户端再回一个纯 ACK 包,连接建立,数据传输开始。
    ACK\mathrm{ACK}

排查实战

掌握了摄像头、筛选器、录像机和解码能力,最后一步是实战破案。网络故障的经典场景,用抓包都能找到硬证据。记住一个原则:别猜,去抓。

排查“连接超时”时,先抓包看 SYN 有没有发出去。如果本机连 SYN 都没发,问题在应用没调 connect 或路由不通;如果发了 SYN 却收不到 SYN-ACK,问题在网络中间(被防火墙丢包或对端没监听在对应 IP);如果收到了 SYN-ACK 但 ACK 发不过去,则可能是对端的半连接队列满了。排查“端口不通”时,最关键的信号是 RST 包——对方收到 SYN 后直接回 RST,说明端口根本没有服务监听,或者被防火墙主动拒绝。

“响应缓慢”则需要算时间。抓到请求包和响应包后,看它们之间的时间戳差,减去服务器端的处理时延,剩下的就是网络往返时间 RTT。RTT 突然飙高,通常指向链路拥塞、无线信号差或跨地域专线问题。安全审计则是另一个方向:用 tcpdump 抓异常外联,用 ngrep 匹配可疑关键字,能快速发现木马回连、暴力扫描等恶意行为。

破案靠的是证据链,不是猜测。一套完整抓包流程下来,连接有没有建立、请求有没有到达、响应有多快、数据有没有被篡改,全都清清楚楚。这就是 tcpdump 和 ngrep 给网络工程师的底气:故障发生时,你不是在黑暗中摸索,而是站在监控室里俯瞰全局。

RTT=tack−tsend\mathrm{RTT} = t_{\mathrm{ack}} - t_{\mathrm{send}}
RTT(往返时延)等于确认包到达时刻减去请求包发出时刻,反映数据在这条链路上走一个来回要花多长时间。
  1. 记录发送时间在抓包里找到请求包,记录它的时间戳。
    tsendt_{\mathrm{send}}
  2. 记录确认时间找到对应的响应包或 ACK 包,记录它的时间戳。
    tackt_{\mathrm{ack}}
  3. 相减得到 RTT两个时间戳相减,就是一次往返时延,用来量化链路快慢。
    RTT=tack−tsend\mathrm{RTT}=t_{\mathrm{ack}}-t_{\mathrm{send}}

AI 应用场景

微服务调用超时定位

阶段:故障定位与根因分析

解决的问题:微服务架构下几十个服务互相调用,一个请求链路涉及五六个服务,任何一个环节慢了都会导致超时。传统方式靠猜和日志翻找,效率低且定位不准。用 tcpdump 在关键节点抓包,可精确锁定“哪一跳”出了问题。

具体案例:某订单服务调用支付服务超时,SRE 在支付服务所在节点执行 tcpdump -i eth0 host 订单服务IP and port 8443 -w pay.pcap,抓完用 Wireshark 看 TCP 流,发现 SYN 发出后等了 3 秒才收到 SYN-ACK,说明问题在网络链路而非应用,进一步定位到跨可用区专线拥塞。

安全审计中的异常外联分析

阶段:安全监控与威胁检测

解决的问题:服务器被植入木马后,通常会主动外联到陌生的 C2 服务器。传统防御只看告警难以确认行为。抓包可以还原真实的通信内容与节奏,为安全决策提供证据。

具体案例:安全工程师在可疑服务器上用 tcpdump -i eth0 'dst port 53 or dst port 443' -c 1000 抓取外联流量,再用 ngrep -q 'shell|cmd|token' 对应用层做关键字匹配,最终定位到一个每隔 5 分钟上报一次的加密通道,确认并隔离了失陷主机。

第三方 API 联调协议核对

阶段:联调测试与协议验证

解决的问题:对接第三方 API 时,经常出现“我发了请求对方说没收到”或“响应格式对不上文档”的问题。靠双方来回截图效率极低。直接在本地抓包,就能客观看到请求报文到底长什么样。

具体案例:后端开发在调用第三方支付接口时,用 ngrep -q 'POST' 'host api.第三方.com' 实时查看请求体,发现 Content-Type 被框架设成了 application/x-www-form-urlencoded,而对方要求 application/json,一行抓包证据直接终结了两天的争论。

Python 演示

python73 行
"""模拟 tcpdump 抓包与 BPF 过滤流程的演示脚本"""import random  class Packet:    """模拟一个数据包: 五元组 + TCP 标志位"""     def __init__(self, src_ip, src_port, dst_ip, dst_port, proto, syn=False, ack=False):        self.src_ip = src_ip        self.src_port = src_port        self.dst_ip = dst_ip        self.dst_port = dst_port        self.proto = proto        self.syn_flag = syn        self.ack_flag = ack     def summary(self):        flags = ""        if self.syn_flag:            flags += "S"        if self.ack_flag:            flags += "A"        return f"{self.src_ip}:{self.src_port} -> {self.dst_ip}:{self.dst_port} {self.proto}[{flags}]"  def bpf_filter(pkt, host=None, port=None, syn_only=False):    """模拟 BPF 过滤: host X and port Y and tcp-syn"""    if host and pkt.src_ip != host and pkt.dst_ip != host:        return False    if port and pkt.src_port != port and pkt.dst_port != port:        return False    if syn_only and not pkt.syn_flag:        return False    return True  def capture(packets, limit=5, **kwargs):    """模拟 tcpdump -c limit 抓包并按条件过滤"""    seen = []    for pkt in packets:        if bpf_filter(pkt, **kwargs):            seen.append(pkt)            if len(seen) >= limit:                break    return seen  def main():    traffic = [        Packet("10.0.0.1", 12345, "8.8.8.8", 443, "TCP", syn=True),        Packet("10.0.0.2", 54321, "10.0.0.1", 80, "TCP", syn=True),        Packet("10.0.0.1", 12346, "8.8.8.8", 443, "TCP", ack=True),        Packet("10.0.0.3", 40000, "10.0.0.1", 22, "TCP", syn=True),        Packet("10.0.0.1", 50000, "10.0.0.2", 80, "TCP", ack=True),        Packet("10.0.0.2", 54322, "10.0.0.1", 80, "TCP", ack=True),    ]    print("== 全部流量 ==")    for pkt in traffic:        print(" ", pkt.summary())     print("\n== 过滤 host 10.0.0.1 and port 80 ==")    result = capture(traffic, host="10.0.0.1", port=80)    for pkt in result:        print(" ", pkt.summary())     print("\n== 过滤 tcp-syn 握手包 ==")    handshakes = capture(traffic, syn_only=True)    for pkt in handshakes:        print(" ", pkt.summary())  if __name__ == "__main__":    main()
目的:用 Python 模拟 tcpdump 的抓包与 BPF 过滤流程,演示如何按主机、端口、SYN 标志筛选数据包,帮助理解真实抓包工具的过滤原理。
  1. class Packet:模拟一个数据包,相当于给包裹做好一张电子快递单。
  2. def bpf_filter(...)模拟 BPF 过滤表达式,逐条判断五元组与标志位是否匹配。
  3. if host and pkt.src_ip != host and pkt.dst_ip != host:等价于表达式 host X,源和目的都不是该地址就跳过。
  4. def capture(...)模拟 tcpdump -c limit,抓到足够数量的包就自动停止。
  5. handshakes = capture(traffic, syn_only=True)等价于 BPF 里的 tcp[13] & 2 != 0,只保留 SYN 标志的握手包。

常见误区

误区以为 tcpdump 抓到什么都能直接看到内容,包括 HTTPS 网站里的账号密码,就像监控能拍到快递单一样。

正解HTTP 协议确实是明文传输,一抓一个准;但 HTTPS 走 TLS 加密,抓到的只有密文。没有会话密钥,看到的只是一堆乱码,如同隔着快递箱看不到里面的东西。想解密,需要在客户端设置 SSLKEYLOGFILE 导出会话密钥,再在 Wireshark 里导入才能看到明文。

为何常见:很多人把 HTTP 明文抓包的经验直接套到 HTTPS 上,忽略了加密层这道“密封箱”。

误区以为把网卡设成混杂模式(promiscuous mode)后,tcpdump 就能看到整个局域网里所有人的通信。

正解现代交换机按 MAC 地址把帧转发到对应端口,不会广播给所有端口。只有在老式集线器、无线监听模式或开启交换机端口镜像(SPAN)的拓扑下,才能看到其他主机流量。混杂模式只是让网卡“不忽略”,能不能收到数据取决于物理链路。

为何常见:老式集线器时代确实抓到一片全有,把二十年前的旧经验带到了今天交换机组网的现实里。

误区觉得 tcpdump 的过滤表达式跟搜索框一样,随便写点什么都能过滤,写错了也会有输出。

正解tcpdump 的过滤表达式遵循 BPF 语法,非法表达式会直接报错退出。而且关键字含义严格,比如 http 不是合法的协议关键字,要用 tcp port 80;or、and 的优先级也容易踩坑。表达式写不好,要么错过关键包,要么被海量无关流量淹没。

为何常见:把 tcpdump 当成黑盒工具,没意识到它底层是一台完整的“包筛选机器”,输入条件必须符合机器的语言。

误区认为抓包只是“看看而已”,挂在服务器上不影响任何业务。

正解高流量场景下,tcpdump 会把每个数据包从内核复制到用户态,CPU 和磁盘开销相当可观,生产环境长时间抓包可能直接把磁盘写满。正确做法是尽量用过滤表达式前置缩小范围,用 -c 限制数量,或用 -s 0 适当截断包长。监控系统不能反过来拖垮被监控的系统。

为何常见:本地小流量测试时完全感觉不到开销,上了生产环境才在流量高峰时踩坑。

误区ngrep 能匹配内容、像 grep 一样直观,所以“更高级”,日常用它就够了,tcpdump 可以丢一边。

正解两者定位完全不同。tcpdump 工作在网络层,擅长记录五元组、标志位、会话流程,还能保存 pcap、离线分析;ngrep 面向应用层内容匹配,适合找特定字符串。排障时通常先用 tcpdump 整体抓、再用 ngrep 深入看内容,是配合关系而非替代关系。

为何常见:名字里带 “grep“ 容易让人觉得它更现代、更强大,但它其实是”网络内容扫描仪”,不是网络摄像机。

面试题

Q1. tcpdump 中 -i eth0 参数的作用是什么?

单选题 · easy

  • A.保存文件为 eth0.pcap
  • B.在 eth0 网卡上抓包← 正确答案
  • C.抓包数量限制为 eth0
  • D.过滤源端口为 80

答案:B。-i 全称 interface,用于指定在哪张网卡上抓包。就像装摄像头要先选机位,选错网卡就什么都录不到。A 是 -w 的用法,C 是 -c 的用法,D 是 port 80 的用法。

Q2. 要读取之前保存的 pcap 抓包文件,应该使用哪个参数?

单选题 · easy

  • A.-w 写入文件
  • B.-r 读取文件← 正确答案
  • C.-i 指定网卡
  • D.-c 限制数量

答案:B。-r 是 read 的缩写,负责把 pcap 文件读回来分析,相当于监控录像的回放键。-w 是写入录像,-i 是选机位,-c 是控制录多久就停。回放与录制是一对成对操作。

Q3. 过滤表达式 port 80 的含义是?

单选题 · easy

  • A.源端口或目的端口为 80← 正确答案
  • B.仅当源端口为 80
  • C.仅当目的端口为 80
  • D.表示 HTTP 协议流量

答案:A。在 tcpdump 中,port 80 会同时匹配源端口或目的端口为 80 的包,等价于 src port 80 or dst port 80。这相当于只要包裹的寄件人或收件人是 80 号门牌就记录。B、C 都是更精确的子集,D 不准确,因为端口不等于协议。

Q4. 以下哪个不是 tcpdump 的合法过滤关键字?

单选题 · mid

  • A.目标主机过滤
  • B.源端口过滤
  • C.协议 http 过滤← 正确答案
  • D.数据包长度过滤

答案:C。tcpdump 的协议关键字是 tcp、udp、icmp 等,http 不是合法关键字,要用 tcp port 80 来过滤 HTTP 流量。A 对应 host,B 对应 src port,D 对应 less/greater。写错关键字会让 BPF 解析直接报错退出。

Q5. ngrep 与 tcpdump 的核心区别是什么?

单选题 · mid

  • A.ngrep 只能抓 HTTP 包
  • B.ngrep 匹配应用层内容← 正确答案
  • C.tcpdump 无法保存文件
  • D.ngrep 不需要 root 权限

答案:B。ngrep 的杀手锏是应用层文本匹配,像网络版 grep,能在 payload 里找关键字;tcpdump 更像网络层摄像机,记录五元组和标志位。ngrep 也能抓非 HTTP 协议,A 错;tcpdump 可以用 -w 保存 pcap,C 错;抓包通常仍需要 root,D 错。

Q6. 排查“端口不通”,tcpdump 发现对方回了一个 RST 包,最可能的原因是?

单选题 · mid

  • A.端口未监听或防火墙拒绝← 正确答案
  • B.网络链路完全断开
  • C.DNS 解析失败
  • D.数据包被加密无法识别

答案:A。RST 是 TCP 的“拒绝”信号。对方收到 SYN 后直接回 RST,通常说明对应端口没有服务监听,或被防火墙主动丢弃并重置。完全断网时根本收不到任何包,B 错;DNS 解析是更早的环节,C 错;加密不影响 TCP 层标志位,D 错。

Q7. BPF 表达式 tcp[13] & 2 != 0 过滤的是哪类数据包?

单选题 · hard

  • A.带 ACK 标志的包
  • B.带 SYN 标志的包← 正确答案
  • C.带 FIN 标志的包
  • D.端口号为 2 的包

答案:B。TCP 头第 13 个字节是标志位字节,0x02 对应 SYN 位。按位与操作后结果非 0,说明 SYN 位为 1,即握手发起包。ACK 位是 0x10,FIN 位是 0x01,D 错在把位移当端口。这条表达式是抓三次握手最经典的 BPF 写法。

Q8. 关于 TLS 解密,下列说法正确的有?

多选题 · mid

  • A.开启 SSLKEYLOGFILE 可导出密钥← 正确答案
  • B.私钥无法解密所有会话← 正确答案
  • C.没有密钥只能看到密文← 正确答案
  • D.TLS 1.3 可无条件解密

答案:ABC。SSLKEYLOGFILE 是浏览器和 curl 支持的会话密钥导出机制,A 对;服务器私钥主要用于 TLS 握手阶段,无法解密采用前向保密的会话,B 对;没有密钥时抓包只能看到 TLS 记录层的密文,C 对;TLS 1.3 全面启用前向保密,没有密钥同样解不开,D 错。

Q9. 关于混杂模式,正确的说法有哪些?

多选题 · mid

  • A.可接收流经网卡的所有包← 正确答案
  • B.需要网卡驱动支持← 正确答案
  • C.只能抓本机发出的包
  • D.交换机未镜像时可能漏包← 正确答案

答案:ABD。混杂模式让网卡接收所有流经的帧,A 对;它依赖网卡驱动支持,B 对;非混杂模式才只收发给本机的包,混杂模式不止抓本机发出的包,C 错;在交换网络中未做端口镜像时,即使混杂模式也收不到其他主机的流量,D 对。

Q10. 用 tcpdump 排查“连接超时”时,应该关注哪些信息?

多选题 · extreme

  • A.SYN 包有没有发出去← 正确答案
  • B.是否收到 SYN-ACK← 正确答案
  • C.HTTP 响应头字段
  • D.握手包到达的时间间隔← 正确答案

答案:ABD。连接超时要先确认 SYN 能否发出,A 对;SYN 发出后迟迟收不到 SYN-ACK,说明问题在网络链路或对端未响应,B 对;连接还没建立,谈 HTTP 响应头为时尚早,C 错;对比握手包之间的时间间隔可以计算 RTT,判断是链路慢还是对端处理慢,D 对。这题考察的是抓包排障的完整思路。