nDPI流量协议分析

1. 介绍

nDPI是一个从OpenDPI发展而来的DPI库,现在由ntop组织负责维护。

为了给你提供一个跨平台DPI的体验,nDPI除了支持Unix平台,还支持Windows(和Mac)。为了使nDPI更加适合应用于流量监控,我们将会持续进行优化,比如一旦发现存在对网络流量监控非必须的、却拖慢了DPI引擎的功能时,可以执行关闭。

不管使用了哪个端口,nDPI都可以探测到实际的应用层协议。这意味着既可以探测运行在非标准端口上的协议(e.g探测运行在非80端口上的http流量),又可以探测运行在一个标准端口上的其他协议(e.g探测运行在80端口上的Skype流量)。这是因为现在端口跟协议关联的概念已经被打破。

在过去的几个月里,我们已经为nDPI增加了以下多个功能:

一个名为ndpiReader的增强型demo

可以被编译进kernel成为一个模块,使其更加高效

从各方面提升了识别速度,目前nDPI在这方面已经远远超过了前代的OpenDPI

新增了大量的协议支持(目前为止已经支持超过180种协议),覆盖范围从商业类协议(如SAP和Citrix)到桌面协议(如Dropbox和Spotify)

可以定义基于端口(端口范围)的协议探测,丰富了传统的仅仅基于端口的探测手段

为了使nDPI支持探测加密连接,我们增加一个用于SSL的解码器(同时支持客户端和服务端),用以找出那些使用了加密证书的协议。这使我们可以识别那些以前无法探测到的协议,比如Citrix和AppleiCloud等

通过基于额外的一些字符串匹配方式,我们可以支持识别一些常见的应用子协议

2. 代码下载

在你搭建ntop和nProbe的过程中nDPI就会自动被下载。也可以作为一个独立的DPI库来使用,源代码可以通过gitclone https://github.com/ntop/nDPI.git下载。

或者:https://github.com/ntop/nDPI/archive/2.4.tar.gz


3. nDPI库安装

其他

安装方式跟平台以及发行版相关,这里列举了一些:

Ubuntu/Debian #apt-get install build-essential

#apt-get install git autoconf automake autogen libpcap-dev libtool

Fedora/CentOS #yum groupinstall "Development tools"

#yum install git autoconf automake autogen libpcap-devel libtool

MacOSX(using http://brew.sh) # brew install autoconf automake libtool git

FreeBSD #pkg install autoconf automake libtool gmake git

依赖环境:

libpcap
autotools
libtool
gawk
gcc
build-essential

安装:

cd nDPI
./autogen.sh
./configure
make
cd example
./ndpiReader --help

Version2.0版本在工程目录下执行make时,默认就编译了example目录下的ndpiReader

4. ndpiReader的命令行选项

以下列出了该demo程序的有效选项以及对应的简单解释

$./ndpiReader -h

ndpiReader-i  [-f ][-s ][-m]

[-p][-l  [-q][-d][-h][-t][-v ]

[-n] [-w ] [-j ]

Usage:

-i                   |指定一个需要被识别的pcap文件/文件列表,或者需要被嗅探的

                                                 |设备接口/接口列表(文件列表或接口列表使用","作为分隔符)

-f                            |指定一条BPF规则的过滤字串

-s                             |最大的嗅探时间(显然只在嗅探接口时生效)

-m                            | pcap文件分段解析超时时间(显然只在解析pcap文件时生效)

-p.protos                          |指定一个自定义的协议识别配置文件(eg.protos.txt)

-l                           |指定循环执行嗅探的次数(仅用于测试)

-n                       |指定线程数量,缺省跟设备接口数量对应

                                                 |如果传入的是pcap文件时固定使用单线程

-j                               |指定一个输出包内容的json文件

-g                                |指定线程-CPU亲和关系映射表

-d                                              |禁止协议猜测功能

-q                                              |安静模式,意味着不打印信息

-t                                               |解析GTP隧道协议

-r                                               |打印 nDPI版本和git版本

-w                                  |指定测试信息的输出文件

-h                                              | help信息

-v<1|2|3>                                  |按级别进一步打印包的详细信息,分为1、2、3级


5. 协议文件

通过基于字符串的匹配方式,nDPI可以支持识别应用层的子协议。这是因为存在很多像AppleiCloud/iMessage,WhatsApp等新出现的子协议,以及其他使用http(s)的协议,这些协议可以通过解码主机SSL证书或http头中的"Host"字段而被识别。因此我们决定嵌入一个有效字符串匹配库到nDPI中,这个库基于AC自动机算法来匹配成百上千的有效子串(i.e运行在商业硬件上的nDPI可以处理超过10Gbit的流量)

通过使用一个协议文件,你可以在运行时设置自定义的子协议,这个协议文件的格式如下:


# Subprotocols

# Format:

# host:"",host:"",.....@

host:"googlesyndication.com"@Google

host:"venere.com"@Venere

host:"kataweb.it",host:"repubblica.it"@Repubblica

host:"ntop"@ntop

你还可以配置基于IP的子协议,格式如下:


# IP based Subprotocols

# Format:

# ip:,ip:,.....@

ip:213.75.170.11@CustomProtocol


你还可以配置基于端口的子协议,格式如下:

# Format:

# :,:,.....@

tcp:81,tcp:8181@HTTP

udp:5061-5062@SIP

tcp:860,udp:860,tcp:3260,udp:3260@iSCSI

tcp:3000@ntop

只需要在运行ndpiReader时加上使用“-p”选项,就可以测试你自定义的配置协议了。当然你也可以通过在你的程序中调用nDPI的APIndpi_load_protocols_file()来测试你的配置。

6 .示例

这节中我们将展示一些demo程序ndpiReader的使用范例。

6.1现场捕获模式

下面这个例子展示了ndpiReader的现场捕获模式,其中“-i”选项用来指定需要进行嗅探的设备接口,“-s”选项指定了嗅探的时间。

$sudo ./ndpiReader -i eth0 -s 20

-----------------------------------------------------------

*NOTE: This is demo app to show *some* nDPI features.

*In this demo we have implemented only some basic features

*just to show you what you can do with the library. Feel

*free to extend it and send us the patches for inclusion

------------------------------------------------------------

UsingnDPI (2.0.0-838-6607c33) [1 thread(s)]

Capturinglive traffic from device eth0...

Capturingtraffic up to 5 seconds

Runningthread 0...

nDPIMemory statistics:

nDPIMemory (once): 93.13 KB

FlowMemory (per flow): 1.25 KB

ActualMemory: 1.49 MB

PeakMemory: 1.49 MB

Trafficstatistics:

Ethernetbytes: 80367 (includes ethernet CRC/IFC/trailer)

Discardedbytes: 1200

IPpackets: 236 of 256 packets total

IPbytes: 74703 (avg pkt size 291 bytes)

Uniqueflows: 165

TCPPackets: 0

UDPPackets: 230

VLANPackets: 4

MPLSPackets: 0

PPPoEPackets: 0

FragmentedPackets: 0

MaxPacket size: 328

PacketLen < 64: 28

PacketLen 64-128: 9

PacketLen 128-256: 6

PacketLen 256-1024: 193

PacketLen 1024-1500: 0

PacketLen > 1500: 0

nDPIthroughput: 47.22 pps / 125.62 Kb/sec

Analysisbegin: 01/Jan/1970 08:00:00

Analysisend: 01/Jan/1970 08:00:00

Trafficthroughput: 47.22 pps / 125.62 Kb/sec

Trafficduration: 4.998 sec

Guessedflow protos: 1

Detectedprotocols:

Unknown packets: 194 bytes: 69976 flows: 143

NetBIOS packets: 19 bytes: 2116 flows: 8

SSDP packets: 2 bytes: 416 flows: 2

IGMP packets: 2 bytes: 120 flows: 2

ICMPV6 packets: 4 bytes: 344 flows: 1

DHCPV6 packets: 3 bytes: 455 flows: 3

LLMNR packets: 10 bytes: 760 flows: 5

Cloudflare packets: 2 bytes: 516 flows: 1

Protocolstatistics:

Acceptable 4727 bytes

Unrated 69976 bytes


6.2文件捕获模式

最简单的创建一个pcap文件的方法是使用tcpdump命令,就像下面这个例子一项:

$sudo tcpdump -i eth0 -w /var/tmp/capture.pcap -v

tcpdump:listening on eth0, link-type EN10MB (Ethernet), capture size 262144bytes

^C248packets captured

252packets received by filter

0packets dropped by kernel

一旦pcap文件被创建,你就可以像下面这样运行ndpiReader:

nDPI流量协议分析_第1张图片

$sudo ./ndpiReader -i /var/tmp/capture.pcap

-----------------------------------------------------------

*NOTE: This is demo app to show *some* nDPI features.

*In this demo we have implemented only some basic features

*just to show you what you can do with the library. Feel

*free to extend it and send us the patches for inclusion

------------------------------------------------------------

UsingnDPI (2.0.0-838-6607c33) [1 thread(s)]

Capturinglive traffic from device eth0...

Capturingtraffic up to 5 seconds

Runningthread 0...

nDPIMemory statistics:

nDPIMemory (once): 93.13 KB

FlowMemory (per flow): 1.25 KB

ActualMemory: 1.49 MB

PeakMemory: 1.49 MB

Trafficstatistics:

Ethernetbytes: 80650 (includes ethernet CRC/IFC/trailer)

Discardedbytes: 1020

IPpackets: 231 of 248 packets total

IPbytes: 75106 (avg pkt size 302 bytes)

Uniqueflows: 164

TCPPackets: 2

UDPPackets: 227

VLANPackets: 1

MPLSPackets: 0

PPPoEPackets: 0

FragmentedPackets: 0

MaxPacket size: 328

PacketLen < 64: 19

PacketLen 64-128: 6

PacketLen 128-256: 13

PacketLen 256-1024: 193

PacketLen 1024-1500: 0

PacketLen > 1500: 0

nDPIthroughput: 155.03 K pps / 412.96 Mb/sec

Analysisbegin: 14/Dec/2017 15:37:39

Analysisend: 14/Dec/2017 15:37:44

Trafficthroughput: 49.59 pps / 135.25 Kb/sec

Trafficduration: 4.659 sec

Guessedflow protos: 0

Detectedprotocols:

Unknown packets: 200 bytes: 71136 flows: 146

MDNS packets: 6 bytes: 1197 flows: 3

NetBIOS packets: 6 bytes: 552 flows: 3

SSDP packets: 3 bytes: 624 flows: 2

ICMPV6 packets: 1 bytes: 86 flows: 1

DHCPV6 packets: 5 bytes: 761 flows: 5

LLMNR packets: 10 bytes: 750 flows: 4

Protocolstatistics:

Acceptable 3970 bytes

Unrated 71136 bytes

6.3协议文件

为了阐述清楚协议文件的作用,我们现在就来讲解如何识别ntop.org的流量。

可以像下面这样编辑protos.txt.

$echo 'host:"ntop.org"@nTop' > protos.txt

修改完协议文件之后,你就可以像下面这样运行ndpiReader:

$sudo ./ndpiReader -i eth0 -s 30 -p ./protos.txt


7.API nDPI

这节中高亮的就是nDPI的API。

这节中将ndpiReader作为一个基本范例来展示如何初始化nDPI库。首先需要一个编译完成的库以及一个合适的Makefile(i.e就像ndpiReader的Makefile那样)

为了在你的程序中使用nDPI的API,你除了要include自己的头文件外,还需要添加类似下面这一行:

#include


库可以按照下面的顺序执行初始化:

[1].创建并初始化一个nDPI核心库探测模块

structndpi_detection_module_struct * module =ndpi_init_detection_module();


备注:本API格式在Version2.0版本中较之前版本差异很大。

这个探测模块中维护了所有支持的协议。

本API只是注册了所有支持的协议,但并未使能其中任何一个协议


[2].ndpiReader接下来通过一些宏使能了探测模块中的所有协议(显然你可以根据自己的需求来决定使能哪些协议)

NDPI_BITMASK_SET_ALL(all);

ndpi_set_protocol_detection_bitmask2(

structndpi_detection_module_struct *ndpi_struct,

constNDPI_PROTOCOL_BITMASK * dbm);

参数含义如下:

@ndpi_struct指向当前操作的探测模块

@dbm调用者实际通过该集合来控制实际需要应用的协议,只有该字段中被置1的对应协议,其协议分析器才真正允许被加载

备注:本API的作用就是使能一个已经初始化的nDPI核心库探测模块中的协议

[3].为了导入已经存在的协议文件,你还必须调用下面的API

ndpi_load_protocols_file(structndpi_detection_module_struct *ndpi_mod, char* path);

参数含义如下:

@ndpi_mod指向当前操作的探测模块

@path协议文件的路径


[4].一旦从你的pcap文件或设备接口上捕获到了数据流,就可以调用下面的API来进行分析

ndpi_protocolndpi_detection_process_packet(

structndpi_detection_module_struct *ndpi_struct,

structndpi_flow_struct *flow,

constunsigned char *packet,

constunsigned short packetlen,

constu_int64_t current_tick_l,

structndpi_id_struct *src,

structndpi_id_struct *dst)

参数含义如下:

@ndpi_struct指向传入包所属的探测模块

@ndpi_flow指向传入包所属的数据流

@packet指向传入包的IP头

@packetlen IP包的长度

@current_tick_l收到该IP包的时间(ms)

@src指向源用户状态机

@dst指向目的用户状态机

备注:本API是ndpi核心库处理收到包的入口,通过分析传入的IP包,完成数据流的识别,最后返回是别结果.

如果想了解更深入的信息,我们建议你阅读下面这些文件:

nDPI/example/pcapReader.c,

nDPI/src/include/ndpi_structs.h,

nDPI/src/include/ndpi_public_functions.h

nDPI/src/ndpi_main.c.

具体的协议解析器文件都被放在nDPI/src/protocols文件夹中。                  

你可能感兴趣的:(安全工具)