官方网站:
https://github.com/ntop/nDPIhttps://www.ntop.org/support/documentation/documentation/https://www.ntop.org/products/deep-packet-inspection/ndpi/https://github.com/ntop/nDPI/blob/dev/doc/nDPI_QuickStartGuide.pdfnDPI 从 OpenDPI 发展而来,是一款 C 语言开发的开源 DPI 实现,nDPI 不仅支持多达 185 种流量的识别,比如 QQ、Apple iCloud、Tor 等,还能避免因随机端口导致的误判。
nDPI 要求调用它的高层应用需要提前处理好报文的第二层,由 nDPI 处理第三层和以上的数据,如果用户使用 nDPI 作为底层,那么就有必要进行先协议切分,三层和以上的数据才能由 nDPI 处理。
nDPI 适合作为一些用于检测流量并判断流量属于何种应用的高层应用程序的基础,具有较好的移植性,现在有针对 Linux、Windows、Mac 和 BSD 类型系统的支持,硬件架构上支持 x86,MIPS 和 ARM。
nDPI 实现了两层架构:核心库用来处理数据报文,抽取基本信息;解析器用插件实现,用于解析报文检测协议类别。nDPI 一旦识别出报文协议就立即返回结果。nDPI 支持对加密流量的解析。nDPI 实现了线程安全。nDPI 实现了优化匹配的方式:nDPI 根据端口尝试直接用一些有可能识别成功的协议解析器进行解析,如果猜错了,则按注册顺序用其他解析器解析。比如一个使用 22 端口的流,则尝试先用 ssh 解析器解析。nDPI 支持提取数据流的元数据。nDPI 可以利用已经识别的 URL 来判断应用的功能:像那些会连接到固定服务器的应用,比如 QQ 等,这样一来对流的识别效率会有一定程度的提高。针对某些互联网应用,比如 Dropbox,由于应用会连接到具体的服务器上,比如 *.dropbox.com,通过解析 HTTP 头抽取 Host 字段,如果这个字段的内容和预先设置的 URL 匹配,就可以初步判断为流属于 Dropbox。但是这里有个问题,怎样才知道哪些包重要,哪些不重要,不然让高层应用怎么抓?
流使用不同的承载协议还有某些软件在开始传输数据之前会进行协商或者其他的处理,这些都是可以作为参照的流量特征。参考 libprotoident,它用来进行识别的包都是双向流的前面的包,一般而言,用双向流整个周期(流的开始到结束)前面的包来进行识别成功率会更高。
影响 DPI 引擎的性能的因素主要是支持的协议数量和流的元数据的抽取,因为在识别流程中,nDPI 先根据端口或者 URL 猜可能的协议种类并用对应的解析器尝试解析,如果猜不对就按照解析器的注册顺序解析直到有一个解析成功;另外对于某些流有很多特征元数据的话,抽取特征也是个很耗时的工作。
nDPI 的设计中,每个解析器都会包含一个默认的协议和端口。比如一个 TCP 流使用 80 端口的话,nDPI 就会尝试猜应用层协议,并尝试使用 HTTP 解析器解析,如果正好猜对,就能让整个解析过程变得更快,如果猜错,比如 HTTP 流不用 80 端口,才会交给其他解析器处理。
nDPI 针对加密流量一般是两种方法:
通过 URL 识别应用类别:不过默认情况下这个仅对互联网应用有效,常见的互联网应用都会连接到其官方服务器,提前注册了这些服务器的 URL,如果加密流量与这些 URL 有关,就判断流属于与那些 URL 相关的应用。
发现自签名的 SSL 证书:如果是 VPN 应用,通常使用了自签名的证书而且保持长时间连接,而非像 HTTPS 一样只发送少量数据。这部分的流识别只能靠行为识别。
nDPI 支持在运行时自定义协议解析器。使用的时候,需要按照一定的格式写配置文件,这些配置文件主要起到保存特征的作用,比如定义一个基于 TCP,使用 81 端口的流为 HTTP,那么 nDPI 就会从流中提取出某些有用的元数据,通过 Aho-Corasick 算法进行快速匹配,如果匹配成功,就可以认为这个流使用了 HTTP。
完成后,键入 ndpiReader 就可以看到帮助信息。尝试使用 ndpiReader 抓 eth0 的包持续 30 秒:
cd nDPI/example ./ndpiReader --help ndpiReader -i eth0 -s 30