这里所说的网络流量处理,包括常说的 IDS ,IPS ,NTA, NDR ,XDR ,DPI ,网络行为审计,防火墙之类需要在数据包层面对流量进行判断审计之类的操作。如果只需要简单的处理比如流量统计,那只需要++就行了。如果要做更准确深入的分析判断,就得需要对这些数据解码。从 IP TCP 一直到应用层如 SMTP 。要针对 SMTP 的协议内容作出判断分析审计,就需要解析 SMTP 协议。
IDS ,IPS 等流量处理引擎各有不同的侧重点,所以对协议解析的要求也各不相同,但大概来说,完整,准确,详细地提取出协议中的字段,比如邮件的标题,收件人,发件人是更好的。解析提取的实现方式也各有各的办法,但解析部分的实现方式会受到流量处理模型的影响。这里把协议解析的实现建立在通常的处理模型之上。所以先简单描述一下这个处理模型。可能有其他处理模型,那这里讨论的协议解析方式有可能不适用。通常,流量处理模型分为以下几个部分,每抓到一个数据包,就会逐个功能调用一遍,也就是数据包会逐次经过每个模块,每个模块被数据包触发。
从系统中获取到数据包。性能之类这里不关心。这里只关心获取到的数据包是网络层的,它是零散的单个的 ip 包,它不会为协议解析提供什么方便,除非你只基于单个包解析。这部分虽然实现了从无到有的数据包获取,解决了根本关键问题。但它只提供了一个简单的视角:一个个的数据包,随机的,混乱的,毫无顺序的,甚至是被破坏了的和错误的数据包。
这个解码仅限于 TCP/IP 的头解码,还没到我们要说的应用层协议解析。因为上一个抓包功能提供的数据包仅仅是原始数据,也就是一个 buff ,并没有结构信息。为此,需要解析 TCP/IP 。至少得知道源目的 IP 端口五元祖等信息。
有了数据包的 TCP/IP 信息,流表把单个的数据包按照链接进行分类,属于同一链接的数据包都关联到同一个链接节点上。这个节点上可以保存本链接的相关信息。比如每条链接有多少个数据包。流表就是一个可以用五元祖来确定唯一节点的 hash 表。每随机到来一个包,就根据这个包的 IP 端口五元祖来找到对应的 hash 节点,这个节点上会记录着此链接相关的数据,比如数据包统计。总不能把 A 链接的数据包算到 B 链接的头上,如果这样,那 A B 链接所在的手机会有流量统计错误,不止协议解析会出错,连钱就会出错。数据包经过流表的处理后,就具备了链接这个视角。
协议识别可以判断一条链接是什么协议。是邮件还是网页还是。这个功能内部很复杂,但它对外输出很简单:就是在一条链接上打一个标签。因为有了流表的支持,它不需要在每个数据包上标记协议类型,它只需要在流表的链接节点上标记即可。协议解析也依赖这个标记,只有标记了是 SMTP ,才能开始按照 SMTP 协议来解析。否则无从下手。不过实际情况协议解析和协议识别可能并非完全的先后关系,协议识别也可能依赖协议解析之后的内容进行判断。比如:识别出是 HTTP 协议,进入 HTTP 解析,提取出 HTTP 头的 URI 字段。URI 字段内容再次进入协议识别模块,进一步判断出这条链接是基于 HTTP 协议的聊天应用。不过这里先不关注这些内容,我们只关注协议解析过程。
现在,已经得到了协议解析所需要的基本条件。这条链接可以进入协议解析模块开始解析了。如果是 SMTP 协议,就在这条流上按照 SMTP 协议规范解析。如果是 POP 协议,就按照 POP 协议规范解析...
1
fuzzsh 20 天前 via Android
项目不错,star 支持下。
看介绍这个会承担转发数据包?现在大多高性能都是用 dpdk |
![]() |
2
nilai 19 天前
不错, 不过现在的加密流量都太多, 大部分都是 https 了
|
![]() |
3
chunhuitrue OP @fuzzsh 只解码,不转发。
|
![]() |
4
chunhuitrue OP |
![]() |
5
arthasliu 19 天前
你是不是要找:wireshark
|
![]() |
6
licolicoli 19 天前
正好在做类似的东西,Go 里面有个库叫 [gopacket]( https://github.com/gopacket/gopacket) ,感兴趣可以去看看。
另外,Rust 好像还没有积极维护的底层网络库,libpnet 没什么人维护,剩下的其实都是 pcap 的绑定。之前用 Go 写一个二层协议的客户端就被折腾的要死,后来还是决定用 C 做了。 |
![]() |
7
777777 19 天前
看标题我以为你训练出了一个协议解析的 AI 模型,正在考虑这个方向
|
![]() |
8
bingfengfeifei 19 天前
最近遇到一个流量解析方面的问题。不知道你这个项目有考虑到这种情况不
主要是 FTP 协议的解析,由于 FTP 的数据通道是与控制通道分开的,且端口动态,没有任何协议特征。 所以进行 FTP-Data 协议的识别时,需要依赖 FTP 的控制通道。 所以协议解析时,首先解析到 FTP 协议,看到被动模式或者主动模式的命令字时,可以用缓存记录这个关系,然后等待后续的 FTP-Data 协议进来时,可以根据缓存的 IP 端口对识别 FTP-Data 协议或者文件还原等等。 这样是理想状况下,但是 BUG 来了。 FTP 和 FTP-Data 是两条会话,所以两者在 TCP 层面并没有什么关联性,如果存在多线程队列处理时,网卡在哈希的时候,可能哈希到不同的处理线程。这样就可能让 FTP-Data 的会话有可能在 FTP 协议处理前处理,然而就导致 FTP-Data 无法识别。 还可能出现乱序,导致 FTP-Data 的会话先过来,同样也会导致无法识别到。 这样 FTP 旁路分析时,经常就会出现 FTP-Data 数据协议无法识别对的情况。 |
![]() |
9
chunhuitrue OP @licolicoli 这个是流重组+应用层协议解析,和 go 那个不一样。另外,这个也不负责抓包相关。
|
![]() |
10
chunhuitrue OP @bingfengfeifei 这是流量处理引擎框架的问题。不是流重组协议解码库的问题。你可以不用五元组 hash ,用 ip hash 。这样同样的 ip 都去同一个线程。不会这样会导致流量分配不平衡。ftp 的情况并没有特别好的办法。
|
![]() |
11
chunhuitrue OP 原来这里发帖要减分。为了省积分,我一起把链接发这里好了:
网络流量处理中的协议解析二:流重组 https://chunhuitrue.github.io/posts/net-protocol-parse-reassemb/ 网络流量处理中的协议解析三:解析 https://chunhuitrue.github.io/posts/net-protocol-parse-parse/ 网络流量处理中的协议解析四:状态机 https://chunhuitrue.github.io/posts/net-protocol-parse-sm/ 网络流量处理中的协议解析五:async/await https://chunhuitrue.github.io/posts/net-protocol-parse-async-await/ 网络流量处理中的协议解析六: 执行器 https://chunhuitrue.github.io/posts/net-protocol-parse-executer/ 网络流量处理中的协议解析七: Protolens https://chunhuitrue.github.io/posts/net-protocol-parse-protolens/ |
![]() |
12
chunhuitrue OP @777777 啥时候发出来能 @我一下么?看看怎么作的。
|
![]() |
13
bingfengfeifei 16 天前
@chunhuitrue #10 确实,我们现在是用的 IP Hash 收包,如果有单一 IP 流的话,会存在单 CPU 核处理的情况。
|
![]() |
14
chunhuitrue OP https://github.com/chunhuitrue/protolens
添加了 DNS 协议解码模块。 |