スケーラブルLGPLv3のオープンディープパケットインスペクションライブラリ
ディレクトリ
nDPI -クイックスタートガイド
オープンソーススケーラブルLGPLv3のディープパケットインスペクションライブラリ
1は、nDPIは、導入
ソースダウンロードし、1.1を
2、nDPIライブラリ
2.1、コンパイラnDPIソース
サンプルndpiReaderソースのコンパイル、2.2を
、ndpiReaderコマンドラインオプション2.3を
2.4プロトコルファイル
3、例えば
3.1リアルタイムキャプチャモード
3.2、PCAPキャプチャモード
3.3プロトコルファイル
4、API nDPI
5は、nDPIは、カスタム・プロトコル開発
5.1導入
新しいプロトコルの作成、5.2
、5.3をnDPIに同意を追加します
1、nDPIはじめに
nDPIは現在、NTOPによって維持、DPIライブラリのOpenDPIをベースにしています。
クロスプラットフォームを体験するためにあなたにDPIを与えるために、我々は、Unix / Linuxをサポートしていないだけでなく、Windowsがサポートしています。だけでなく、私たちは、nDPIを修正する交通監視アプリケーションに、より適切なものにすることによって持っていること、不要な監視ネットワークトラフィックのためにこれらの機能を無効にすることによって、私たちは、この機能を実現するため、また、スピードDPIエンジンを加速されています。
nDPIは、アプリケーション層プロトコル、およびどのように関係なく使用するポートの検出を可能にします。これは、非標準ポートモニタ既知のプロトコル(例えば、ポートのポート80に加えて、HTTPプロトコルを検出する)またはその逆(例えば、Skypeのトラフィック検知ポート80)が可能になっていることを意味します。「ポート=アプリケーション」の今日の概念にはもはや適用されないためです。
過去数ヶ月で、私たちも含めて、いくつかの新機能を追加しました:
- 応用例ndpiReaderスピード/サポート機能およびパッケージが強化されました。(たとえば、あなたが今、GTPトンネルのトラフィックを分析することができます)
- あなたは、効率的なカーネルベースのモジュールを開発するためにそれを使用できるようにNDPIは、Linuxカーネルにコンパイルすることができます。
- 多面スピードを強化し、nDPI彼の前任者よりも速くなりました(以前のバージョンに)。
- SAPおよびCitrixおよび他のそのような「ビジネス」の合意を含む契約の数を(これまでのところ、我々は、約200の契約をサポート)、追加、それはDropboxのとSpotifyは「デスクトップ」プロトコルを持っています。
- 来て、あなたがポート検出の検出に基づいて古典的な補足的な合意を使用することができるために、ポート(およびポート範囲)に基づくプロトコル検出を定義することができ。
- nDPIサポートは暗号化されたリンクを可能にするために、我々は、SSL(サーバとクライアントが含まれます)の証明書は、デコーダに追加しました。したがって、我々は合意を明確にする暗号化証明書の使用を理解することができます。これはまた、CitrixのオンラインおよびAppleのiCloud他の一般的な合意を検出することができないとして私たちが識別できるようになります。
- サブプロトコル・サポートを使用して、一致する文字列に基づきます。
1.1、ソースをダウンロード
あなたはNTOPとnProbe nDPIを構築するときに自動的にダウンロードされます。もちろん、何もスタンドアロンDPIライブラリとしてそれを使用停止することはできません。あなたは始めることができますhttps://github.com/ntop/nDPIをソースコードをダウンロードしてください。
2、nDPIライブラリー
2.1、コンパイラソースコードnDPI
非常にシンプルであるライブラリを使用して起動NDPI。このライブラリをコンパイルするには、次のような特定の前提条件を満たしている必要があります。
GUN autotools/libtool
gawk
gcc
これを実現するために、あなたはそれらをインストールするには、次のコマンドを使用する必要があります。
あなたは上記のインストールが完了したら、ソースコードnDPIをコンパイルするには、次のコマンドを使用することができます。
cd <nDPI source code directory>
./autogen.sh
./configure
make
2.2、コンパイラのソースコードの例ndpiReader
開始ndpiReaderも非常に簡単です。それをコンパイルするには、次のコマンドを使用する必要があります。
cd <nDPI source code directory>/example
make
2.3、ndpiReaderコマンドラインオプション
このアプリケーション例では、パッケージと支持体のndpiReader速度/機能解析に使用することができます。特に、ndpiReaderは、コマンドラインオプションの数を指定することができます。
ここでは簡単な概要コマンドのオプションであり、各オプションを使用することができます。
-i <file.pcap |device>
このコマンドは、データ・パケットを読み取るために、またはリアルタイムキャプチャ用デバイスを指定するのpcapファイルを指定するために使用されます。そして、だけ彼らの二つのうちの一つ。
-f <BPF filter>
選択された流量をフィルタリングするBPFフィルタを指定します。NDPIのみ(指定されている場合)、フィルタに一致する受信パケットが可能となります。
-s <duration>
定义了捕获持续时间,以秒为单位,仅用于实时流量捕获。
-p <file.protos>
指定了一个协议文件(例如protos.txt)来扩展对子协议和基于端口协议检测的支持。尤其需要小心的是,协议一旦被定义到protos文件中就会覆盖之前的已经存在的协议。
-l <num loops>
检测循环数(仅用与测试)
-d
这个标志会禁用nDPI协议猜测,仅使用DPI。
-t
打印ndpiReader帮助
-v <1|2>
使用这个标志时,ndpiReader会生成详细的输出,这个输出能被用于调试其性能。数字1是显示带有“未知协议”数据包的最低等级,而2级会显示地更加详细,两者只能指定其一。
2.4、协议文件
nDPI能够通过基于字符串的匹配支持子协议。这是由于许多新的子协议比如Apple iCloud/iMessage,WhatsApp和许多其他的使用HTTP(s)的协议能够通过解码SSL证书主机或者HTTP“Host:”被检测到。因此我们决定将一个基于流行的Aho-Corasick 算法的高效字符匹配库嵌入到nDPI中,用于数十万子字符的高效匹配(即在普通硬件上能足够快地支持10Gb的流量)。
你可以在运行时通过使用一个用以下格式的协议文件来指定子协议:
除此之外,你也能使用以下格式来指定一个基于端口的检测:
你可以使用ndpiReader这个应用(使用 –p 选项)来测试你的自定义配置。或者你可以使用ndpi_load_protocls_file() nDPI API调用来增强你自己的应用。
3、示例
在这一节我们会展示一些ndpiReader的使用范例。
3.1、实时捕获模式
下面这个例子将会展示ndpiReader的实时捕获模式。使用参数-i指定接口设备,参数-s 指定实时捕获持续时间。
3.2、pcap 捕获模式
创建一个pcap文件最简单的方法就是通过使用tcpdump命令,就像下面这个例子:
一旦pcap文件被创建,你就能启动ndpiReader,使用参数-I :
3.3、协议文件
为了阐明协议文件的特性,我们现在将解释怎样让你识别来自ntop.org的流。
我们可以通过编辑protos.txt文件来实现它:
ntop$ echo 'host:"ntop.org"@nTop'> protos.txt
一旦这个协议文件已经被修改,你可以启动ndpiReader,使用参数 –p:
4、API nDPI
在这一节中nDPI API是重点。
示例ndpiReader现在有一个基础的例子用来展示如何初始化这个库。需要一个已经编译好的库和一个合适配置的Makefile(即示例Makefile)。
想要在你的应用中开始使用nDPI的API,除了你自己的包含外,必须也添加下面这个包含文件:
#include"dpi_main.h"
这个库可以像下面这样初始化:
1、声明协议位掩码,初始化检测模块:
NDPI_PROTOCOL_BITMASK all;
ndpi_struct = ndpi_init_detection_module(detection_ticks_resolution,malloc_wrapper,
free_wrapper,debug_printf);
这个函数允许你初始化检测模块。字段有如下含义:
U_int32_t ticks_per_second
每秒时间戳分辨率(比如1000每毫秒分辨率)。
void*(*_ndpi_malloc)(unsigned long size);
指向一个内存分配器的函数指针。
void*(*_ndpi_free)(void*prt);
指向一个调试输出函数的函数指针,在生产环境下置空(NULL)
2、通过适当的宏并将他们设置到检测模块中来启用所有协议(需要注意的是,如果你愿意你也可以启用这些协议的子集)。
// enable all protocols
NDPI_BITMASK_SET_ALL(all);
ndpi_set_protocol_detection_bitmask2(ndpi_struct, &all);
这个函数能让你设置已经定义到检测模块中的协议位掩码。
3、为了加载一个存在的协议文件,你必须使用如下函数:
dpi_load_protocols_file(ndpi_struct, _protoFilePath);
4、每当从你的pcap文件或者入口设备中捕获到流时,它们可以通过使用以下函数分析:
protocol = (const u_int32_t)ndpi_detection_process_packet(
ndpi_struct,ndpi_flow,iph ? (uint8_t *)iph : (uint8_t *)if,
ipsize,
time,
src,
dst);
这些字段有以下的含义:
struct ndpi_detection_module_struct*ndpi_struct;
检测模块。
struct ndpi_flow_struct*flow;
指向连接状态机的流空指针。
const unsigned char*packet;
这个packet作为一个无符号的字符指针,长度为packetlen。这个指针必须指向第三层(IP报头)。
const unsigned short packetlen;
packetlen包的长度。
const U_int32_t current_tickt;
数据包的当前时间戳。
struct ndpi_id_struct*src;
指向源订阅状态机的空指针。
struct ndpi_id_struct*dst;
指向目的订阅状态机的空指针。
5、一旦流被分析后,有必要通过下面的函数来摧毁检测模块。
ndpi_exit_detection_module(ndpi_struct, free_wrapper);
这些字段有以下含义:
struct ndpi_detection_module_struct*ndpi_struct;
需要被消除的检测模块。
void*(*_ndpi_free)(void*prt);
指向一个内存释放函数的函数指针。
如需进一步的信息,我们建议可以阅读以下文件:
nDPI/example/ndpiReader.c,
nDPI/src/include/ndpi_structs.h,
nDPI/src/include/ndpi_public_functions.h
nDPI/src/ndpi_main.c
协议解析器文件被包含在nDPI/src/protocols 目录下。
5、开发nDPI自定义协
在这一节中,我们将展示将你的协议包含在nDPI中的方法。
5.1、介绍
各nDPIプロトコルエントリは、それがnDPIにより実行時に使用される機能として実現されるであろう。nDPIこの点で例として使用することができ、いくつかのプロトコルがあります。あなたが知っておく必要があるということですnDPI協定を開発する場合、以下の、我々は、主要な概念のいくつかをリストアップしました。
5.2、新しいプロトコルを作成します
各プロトコルは、以下に対応する定義ファイルのヘッダーを持っている必要があります。
<nDPI source code directory>/src/include/ndpi_protocols_osdpi.h
例えば:
#define NDPI_PROTOCOL_MY_PROTOCOL 171
NDPI_PROTOCOL_MY_PROTOCOLは、本契約の名前で、171は、本契約のIDで、一意である必要があります。
あなたは、プロトコルを定義した後、次のような新しいプロトコルのソースファイルを作成する必要があります
<nDPI source code directory>/src/lib/protocols/my_protocol.c
これは、次のものが含まれます。
#include "ndpi_utils.h"
#ifdef NDPI_PROTOCOL_MY_PROTOCOLS
.....
#endif
内部に、など、エントリ関数を定義します:
void ndpi_search_my_protocol(
struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow)
{
struct ndpi_packet_struct *packet = &flow->packet;
NDPI_LOG(NDPI_PROTOCOL_MY_PROTOCOL, ndpi_struct,NDPI_LOG_DEBUG, "my protocol detection...\n");
/* skip marked packets by checking if the detection protocol stack */
if (packet->detected_protocol_stack[0] != NDPI_PROTOCOL_MY_PROTOCOL) {
ndpi_check_my_protocol(ndpi_struct, flow);
}
}
そして次備え、コア機能を検出するパケットストリームを処理するために:
static void ndpi_check_my_protocol(struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow)
{
struct ndpi_packet_struct *packet = &flow->packet;
u_int32_t payload_len = packet->payload_packet_len;
.....
.....
if("Found Protocol") {
NDPI_LOG(NDPI_PROTOCOL_MY_PROTOCOL, ndpi_struct,
NDPI_LOG_DEBUG, "Found my protocol.\n");
ndpi_int_my_protocol_add_connection(ndpi_struct, flow);
return;
}
/*Exclude Protocol*/
NDPI_LOG(NDPI_PROTOCOL_MY_PROTOCOL, ndpi_struct, NDPI_LOG_DEBUG,
"exclude my protocol.\n");
NDPI_ADD_PROTOCOL_TO_BITMASK(
flow->excluded_protocol_bitmask,
NDPI_PROTOCOL_MY_PROTOCOL);
}
}
など、特定の機能が正しいプロトコル識別情報を報告するために使用されもあります。
static void ndpi_int_my_protocol_add_connection(
struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow,
u_int8_t due_to_correlation)
{
ndpi_int_add_connection(ndpi_struct, flow,
NDPI_PROTOCOL_MY_PROTOCOL,
/*Choose the type of your protocol*/
NDPI_CORRELATED_PROTOCOL or NDPI_REAL_PROTOCOL);
}
5.3 nDPIに同意を追加
契約書が作成されたら、次のヘッダーファイル内のエントリ関数を宣言する必要があります。
<nDPI source code directory>/src/include/ndpi_protocols.h
これは、次のものが含まれます。
/* my protocol entry */
void ndpi_search_my_protocol(
struct ndpi_detection_module_struct *ndpi_struct,
struct ndpi_flow_struct *flow);
各契約はNDPI_SELECTION_BITMASK関連付けられている必要があります。完全なリストについてはNDPI_SELECTION_BITMASKは、ファイルに含まれています:
<nDPI source code directory>/src/include/ndpi_define.h
あなたのプロトコルのための特定のビットマスクを選択したら、ファイルを編集して、存在nDPI新たな合意を通知しなければなりません。
<nDPI source code directory>/src/lib/ndpi_main.c
あなたは、以下の機能への同意を追加する必要があります。
void ndpi_set_protocol_detection_bitmask2(
struct ndpi_detection_module_struct *ndpi_struct,
const NDPI_PROTOCOL_BITMASK * dbm)
.....
.....
.....
#ifdef NDPI_PROTOCOL_MY_PROTOCOL
ndpi_set_bitmask_protocol_detection(ndpi_struct,detection_bitmask,a,
NDPI_PROTOCOL_MY_PROTOCOL,
ndpi_search_my_protocol,
NDPI_SELECTION_BITMASK_MY_PROTOCOL,
SAVE_DETECTION_BITMASK_AS_UNKNOW,
ADD_TO_DETECTION_BITMASK);
/* Update callback_buffer index */
a++;
#endif
.....
.....
.....
ndpi_struct->callback_buffer_size = a;
NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG,
"callback_buffer_size is %u\n", ndpi_struct->callback_buffer_size);