此篇方法是第一个将端到端的方法应用到加密流量分类领域,使用数据集ISCX-VPN-NonVPN-2016数据集进行研究。
依据ISO/OSI层的不同,加密技术可以分为
应用层加密:应用程序在应用层实现自己的协议以实现数据的安全传输(如BitTorrent或Skype),在一些论文中也称为常规加密。
表示层加密
网络层加密:如IPSec加密协议
不同的拆分粒度会导致不同的流量单位。主流的研究分为包级(packet)、流级(flow)、会话级(session)
原始流量(raw traffic)可以定义为|P|个包的集合
P = { p 1 , . . . p ∣ P ∣ } P=\{p^1,...p^{|P|}\} P={p1,...p∣P∣}
其中,
p i = ( x i , b i , t i ) , i = 1 , 2 , . . . , ∣ P ∣ p^i=(x^i,b^i,t^i),i=1,2,...,|P| pi=(xi,bi,ti),i=1,2,...,∣P∣
流级:一组原始流量P可以划分为多个子集,子集中的所有数据包按照时间排列,每一个子集就称为一个流(flow)
f = ( x , b , d , t ) = { p 1 = ( x 1 , b 1 , t 1 ) , p 2 = ( x 2 , b 2 , t 2 ) , . . . , p n = ( x n , b n , t n ) } , t 1 < . . . < t n f=(x,b,d,t)=\{p^1=(x^1,b^1,t^1),p^2=(x^2,b^2,t^2),...,p^n=(x^n,b^n,t^n)\}, t^1<...
会话级:一个会话可以定义为双向流,即流的五元组中的源IP/源port与目的IP/目的port可以互换(session)
ISCX-VPN-NonVPN-2016包括7种常规加密流量和7种协议封装流量
数据集结构如下:
ISCX数据集的流特征有14类标签,但原始流量没有标签,因此我们根据数据集中pcap文件的论文描述对其进行标签。而一些文件,如Facebook_video.pcap可以被标记为“浏览器”或“流媒体”,所有与“浏览器”和“ -浏览器”相关的文件都有这个问题。决定不给这些文件贴上标签。
最后,标记的ISCX数据集有12类,包括6类常规加密流量和6类协议封装流量。
使用论文团队开发的工具USTC-TL2016进行数据预处理
ALL表示使用了所有层的包层选择
L7表示仅仅使用了OSI模型的第七层(应用层)的包层选择
采用小批量随机梯度下降(SGD)。采用10倍交叉验证技术,保证了CNN模型的泛化能力。
利用训练好的CNN模型进行测试
输入:取流或者会话的前n个字节作为模型输入,n取784(28*28)
使用1D-CNN的理由:CNN主要应用于计算机视觉领域,如图像分类。CNN适用于以下类型的数据:
多数组形式的数据;
具有强局部相关性的数据;
特征可以出现在任何地方的数据;
对象不受平移和扭曲影响的数据。
具体来说,1D-CNN适合于诸如顺序数据或语言之类的数据。2D-CNN适用于图像或音频声谱图等数据。3D-CNN适用于视频或体积图像等数据。网络流量本质上是顺序数据。它是一种按层次结构组织的一维字节流。字节、分组、会话和整个流量的结构与自然语言处理领域中的字符、单词、句子和整篇文章的结构非常相似。近年来,CNN在NLP中的成功应用均采用1D-CNN,如情感分析、文本分类。本文在这些研究的启发下,使用一维cnn执行加密流量分类任务,并将其性能与二维cnn进行比较。
论文给出的源码是基于tensorflow实现的,这里用torch写了一个CNN做了一下exp4,也就是上图的红色箭头的结果。如下,基本差不多
class OneCNNC(nn.Module):
def __init__(self,label_num):
super(OneCNNC,self).__init__()
self.layer_1 = nn.Sequential(
# 输入784*1
nn.Conv2d(1,32,(1,25),1,padding='same'),
nn.ReLU(),
# 输出262*32
nn.MaxPool2d((1, 3), 3, padding=(0,1)),
)
self.layer_2 = nn.Sequential(
# 输入262*32
nn.Conv2d(32,64,(1,25),1,padding='same'),
nn.ReLU(),
# 输入262*64
nn.MaxPool2d((1, 3), 3, padding=(0,1))
)
self.fc1=nn.Sequential(
# 输入88*64
nn.Flatten(),
nn.Linear(88*64,1024),
# 这里自己加了两个dropout层
nn.Dropout(p=0.5),
nn.Linear(1024,label_num),
nn.Dropout(p=0.3)
)
def forward(self,x):
# print("x.shape:",x.shape)
x=self.layer_1(x)
# print("x.shape:",x.shape)
x=self.layer_2(x)
# print("x.shape:",x.shape)
x=self.fc1(x)
# print("x.shape:",x.shape)
return x