如何捕获GRE或VXLAN封装的内部网络流量?
针对封装流量的tcpdump过滤方案
当流量被GRE/VXLAN这类协议封装时,普通src/dst过滤器仅匹配外层IP,无法识别内层封装的真实IP。以下是几种准确可靠的解决方法:
1. 基于协议嵌套的多层过滤(推荐)
tcpdump支持按协议层级逐层过滤,直接匹配内层封装的IP,无需手动计算字节偏移,适配性更强。
针对GRE桥接封装场景(如你提供的报文结构)
你的流量是外层IP+GRE,内层封装了完整的以太网帧和IP头,可使用以下命令:
- 捕获内层源IP为10.75.2.11的流量:
tcpdump -i eth0 'gre and ether proto ip and ip src 10.75.2.11' - 捕获内层目的IP为10.75.2.160的流量:
tcpdump -i eth0 'gre and ether proto ip and ip dst 10.75.2.160'
该命令先匹配外层GRE协议,再解析内层以太网帧中的IP协议,最终定位到真实的源/目的IP,完全避免固定偏移的准确性问题。
针对VXLAN封装场景
VXLAN默认用UDP 4789端口封装,可类似过滤:
tcpdump -i eth0 'udp port 4789 and ether proto ip and ip src x.x.x.x'
2. 利用BPF扩展语法(高版本tcpdump支持)
若你的tcpdump/libpcap版本足够新(通常2.4.0+),支持更直观的协议字段引用,直接指定内层IP:
tcpdump -i eth0 'ip proto gre and ip[gre:ip_src] = 10.75.2.11'
或匹配目的IP:
tcpdump -i eth0 'ip proto gre and ip[gre:ip_dst] = 10.75.2.160'
这种写法可读性更强,无需转换十六进制,底层会自动处理协议偏移。
3. 十六进制匹配内层IP(兼容旧版本)
如果上述方法因版本限制无法使用,可手动将IP转换为十六进制,结合协议过滤:
- 10.75.2.11 转换为十六进制是
0x0a4b020b - 10.75.2.160 转换为十六进制是
0x0a4b02a0
针对你的GRE桥接场景,内层IP源地址的偏移需结合报文结构计算:外层IP头(20字节) + GRE头(4字节) + 内层以太网帧头(14字节) + 内层IP头源地址偏移(20字节) = 58字节,所以命令为:
tcpdump -i eth0 'gre and ip[58:4] = 0x0a4b020b'
注意:此方法依赖固定字节偏移,若GRE头包含可选字段(长度变化)则会失效,仅作为旧环境的备选方案。
内容的提问来源于stack exchange,提问作者Linksman
相关产品推荐
相关产品推荐

