郭靖宗,薛有為,申志軍
(1.河南水利與環境職業學院,河南 鄭州 450008;2.內蒙古農業大學 計算機與信息工程學院,內蒙古 呼和浩特 010000)
互聯網發展離不開網絡安全,隨著互聯網迅速發展,網絡覆蓋范圍已經全球化,中國互聯網絡信息中心表示,2020年中國網民規模為9.89億,較2020年3月提升5.9個百分點,移動通信速度也邁入了5G時代,網絡入侵的頻率也越來越頻繁,入侵的手段也越來越復雜。根據第45次《中國互聯網絡發展狀況統計報告》顯示,截至2019年12月[1],國家計算機網絡應急技術處理協調中心接收到網絡安全事件報告107 801件。隨著各個行業對于Internet需求的加大,對于各種網絡攻擊的入侵檢測技術的需求也在進一步的提高。
智能化入侵檢測的研究離不開數據集和分類模型。筆者基于最新的數據集CSE-CIC-IDS進行數據預處理,劃分訓練集和測試集,以之為基礎通過XGBoost模型進行分類測試并進行綜合對比分析。
入侵檢測數據集的研究可以追溯到20世紀90年代[2],麻省理工學院林肯實驗室模擬美國空軍局域網環境而建立的網絡流量測試數據集,此數據集建立時加入了4種異常類型,在1999年由來自哥倫比亞大學的Sal Stolfo教授和來自北卡羅來納州立大學的Wenke Lee[3]教授采用數據挖掘等技術,對KDD' 98數據集進行數據預處理和特征分析,生成了數據集KDD' 99。此數據集和它之后的改進版NSL-KDD數據集在入侵檢測模型的訓練時經常作為基準數據集使用。
近年來,隨著網絡攻擊類型增加,KDD' 99數據集已不能有效地反映現代的網絡流量特點和低占空間攻擊,因此2015年由新南威爾士大學(UNSW)在澳大利亞網絡安全中心(ACCS)的網絡實驗室中使用IXIA工具創建了UNSW-NB15數據集[4]。實驗的攻擊數據是從CVE網站受到的攻擊數據中獲取。該數據集使用Tcpdump抓取了100G數據。UNSW-NB15數據集具有9類攻擊:24 246個模糊測試攻擊(Fuzzers),2 677個分析攻擊(Analysis),2 329個后門攻擊(Backdoors),16 353個拒絕服務攻擊(DoS),44 525個漏洞攻擊(Exploits),215 481個通用攻擊(Generic),13 987個偵察攻擊(Reconnaissance),1 511個代碼攻擊(Shellcode)和174個蠕蟲攻擊(Worms),正常數據約220萬條,共計254萬條數據,沒有進一步劃分攻擊類型。數據集包括原始流量包(pacp)和特征流量CSV文件,CSV文件被劃分為訓練集和測試集,文件共有49個特征。訓練集有17萬條數據,測試集有8萬條數據[5]。
UNSW-NB15數據集的缺點是攻擊類型沒有進行二級劃分,捕獲時間較短,流量分布可能會與真實流量分布存在偏差,訓練得到的模型可能不理想。因此,加拿大通信安全機構(Communications Security Establishment/CSE)和網絡安全研究院(Canadian Institute for Cybersecurity/CIC)于2018年合并公布了入侵檢測數據集CSE-CIC-IDS 2018[6,7]。該數據集獲取的網絡拓撲結構是由AWS搭建的拓撲結構。劃分為5個子網。分別代表企業的5個部門,和服務器機房。除IT部門以外的部門,都安裝了不同的Windows系統。對于IT部門的計算機安裝了Ubuntu,對于服務器機房安裝了不同的Windows服務器。該數據集一共模擬了七大類攻擊,14種攻擊數據,涉及了7種網絡協議:HTTP、HTTPS、POP3、SMTP、IMAP、FTP和SSH。該數據集包含了原始流量包、主機日志記錄和特征標簽流文件。
CSE-CIC-IDS2018數據集獲取時間相對于UNSW-NB15數據集時間較長,在現代流量中最符合真實流量分布情況。實驗模擬環境較新,具有現代網絡協議和攻擊類型的數據集。
機器學習在入侵檢測中就是通過對比訓練好的模型之間的偏離度來區分是否異常。該模型是根據數據之間的關系來描述的,若模型S是基于監督學習的異常檢測模型,則S=(M,D)。M是正常網絡行為的模型,D是M允許的偏差。機器學習模型一般是由訓練模塊和檢測模塊構成。訓練模塊訓練好模型M,然后根據M和D來對新的網絡事件進行預測,如果超過D的范圍,則該數據被標記為異常流量。
分類問題一直都是研究人員所探索的問題,如何使用機器學習高效而準確的判斷數據之間的相關性,并且根據某些已知的特征來區分輸入的樣本是屬于哪一種已知的類別,其本質是通過對特征進行模型計算得到一個對未分類數據的預測模型。機器學習發展至今,產生了許多經典的分類算法,比如邏輯回歸、樸素貝葉斯、決策樹、K最鄰近和支持向量機等算法。
筆者以邏輯回歸為例說明傳統機器學習算法的工作原理。
邏輯回歸的思路是把線性回歸改為二分類。邏輯回歸模型定義為如(1)和(2)所示概率分布的模型:

(1)

(2)
其中:x∈Rn是輸入(特征空間)
Y∈{0,1是輸出(標記)}
w∈Rn為模型參數——權值向量(weight)
b∈R為模型參數——偏執(bias)
為了簡潔,將b擴充到w,然后x后邊加入全1的列得到:
w·x+b?w·x
(3)
(4)
因此邏輯回歸模型的對數幾率函數為公式(5):
(5)
上式意味著輸出Y=1的對數幾率是輸出x的線性函數,即邏輯回歸模型。
在數據預處理過程的時候,由于特征流量文件內存過大,計算機內存經常溢出,會使得后續的數據預處理和模型訓練效率降低,所以在數據合并之前,需要對10個CSV文件提取10%的數據集作為子集。由于每個文件中,都包含不同的攻擊類型,所以,需要對每個文件進行隨機提取,確保特征的分布穩定。代碼如下:
import pandas as pd
data = pd.read_csv(`XXX.csv')
sample = data.sample(frac=0.1, random_state=5, axis=0)#Frac=0.1代表抽取其中10%的數據
sample.to_csv(`XXX.csv',encoding=`utf_8_sig')
文件合并之前,需要統一格式,對于列數不同的文件,首先對比其中特征的區別。發現文件中多余的兩列對于模型的訓練沒有意義,然后將多余的列進行刪除,與其他8個文件的表頭進行統一。刪除指定列的代碼如下:
df.drop([`typeMedium'],axis=1,inplace=True)
隨著大數據的出現,需要處理的數據源越來越多,數據分析任務多半涉及將多個數據源數據進行合并。數據集成是指將多個數據源中的數據結合、進行一致存放的數據存儲,這些源可能包括多個數據庫或數據文件。在數據集成的過程中,會遇到一些問題,本文實驗中遇到了數據值的沖突和處理,并且對沖突進行去重處理。接下來,需要將10個文件進行集成處理,然后進行表頭去重。代碼如下:
def marge(csv_list, outputfile):
for inputfile in csv_list:
f = open(inputfile, `r', encoding="utf-8")
data = pd.read_csv(f)
data.to_csv(outputfile, mode=`a', index=False)
#去重保留一個表頭
def distinct(file):
df = pd.read_csv(file, header=None)
datalist = df.drop_duplicates()
datalist.to_csv(`result_new.csv', index=False, header=False)
數據清洗是通過將缺失值刪除或者填補,糾正數據的不一致來達到清洗的目的。簡單來說,就是把數據里面哪些缺胳膊腿的數據、有問題的數據給處理掉。總的來講,數據清洗是一項繁重的任務,需要根據數據的準確性、完整性、一致性、時效性、可信性和解釋性來考察數據,從而得到標準的、干凈的、連續的數據。
數據集存在空值或者Infinity時,文件無法正常運行,需要對空值進行處理。處理方法有兩種:刪除空值和Infinity所在行,或者使用取均值進行填充。但是對于本文的上億條數據,取均值意義不大。所以本文采用刪除空值和Infinity行。首先需要判斷數據集中是否存在空值,然后進行刪除。代碼操作如下:
df_n.dropna(axis=1, how=`any', inplace=True)
數據有一列是日期,需要轉換為時間戳。如圖1(a)所示,文件中第三列包含一列是日期,在做模型訓練的時候,此格式無法進行讀取,所以需要將其轉化成時間戳格式。轉換以后的結果如圖1(b)的Timestamp列所示。
代碼如下所示:
data = pd.read_csv(`XXX.csv')
data[`Timestamp']=data[`Timestamp'].apply(lambda x:time.mktime(time.strptime(x,`%d/%m/%Y %H:%M:%S')))
data.to_csv(`XXXX.csv', sep=`,', header=True,index=False)

(a)處理前的時間樣例

(b)處理過后的時間樣例圖1 時間樣例
最后數據集需要進行歸一化處理,歸一化有兩種形式:①把數據變為0~1之間的數;②把有量綱表達式變為無量綱表達式。主要是為了使得數據處理方便快捷。歸一化是數據預處理中的一步操作,歸一化的作用是縮小統一樣本的分布。如果不進行歸一化,數據的取值范圍往往會非常大。在訓練模型的時候,數值范圍分布差異過大會使模型產生過擬合現象。因此歸一化操作可以使得模型訓練的效果更好,提升模型性能。
筆者使用的是Max-Min標準化,該方法將某個變量的觀察值減去該變量的最小值,然后除以該變最大值與最小值的差,其標準化的數值落到[0,1]區間,max和min分別為最大樣本值和最小樣本值。
代碼部分如下:
def data_norm(df,*cols):
df_n = df.copy()
for col in cols:
ma = df_n[col].max()
mi = df_n[col].min()
df_n[col] = (df_n[col] - mi) / (ma - mi)
return(df_n)
數據集處理完之后需要進行訓練集和測試集的劃分,劃分的時候,要保證兩部分互不相交,保持數據分布一致,訓練集數據占到總數的2/3到4/5比較合理,為了保證數據集的隨機性,將數據集進行隨機打亂,多次劃分結果取平均值。部分代碼如下:
test = test_data.sample(int(test_data.shape[0]*0.2))
train = test_data.iloc[list(set(test_data.index.values)-set(test_data20.index.values)),]
XGBoost是在Gradient Boosting算法[8]基礎上加以改進,模型和參數本身指定了給定輸入和如何預測,但是沒有告訴如何去尋找一個比較好的參數,這個時候就需要目標函數登場了。一般地如式(11)目標函數包含兩項:第一項損失函數,它表示模型擬合數據的程度;另一項是正則化項(懲罰項),它使得模型更加簡單,避免過擬合。
Obj(θ)=L(θ)+Ω(θ)
(6)
XGBoost的構建目標函數為(7),左邊是損失函數,右邊是正則化項,(8)是正則化項的展開式。
(7)
(8)
下文中式(9)—式(15)介紹了如何構造目標函數,對于給定xi個樣本,都需要求一個f(x)的得分,當有k個樣本時,第0個樹的預測值為0,第1棵樹的預測值為f1(xi),并且等于第0棵樹預測值與第1棵樹預測值相加。第二棵樹的預測值為f2(xi),是第1棵、第2棵與第三課樹的預測值的和。以此類推,第k棵樹的預測值就是k-1棵樹與k棵樹的和。然后將得出的第k棵樹的結果帶入函數當中得出式(13),其中式(14)在預測第k棵樹的時候,前k-1棵樹的預測值已知,所以是常量,最終得出最小化目標函數。
(9)
(10)
(11)
(12)
(13)
(14)
(15)
XGBoost實驗開始,對數據集大小對訓練集評分和測試集評分做了比較,由圖2可知隨著訓練集樣本的增加,訓練集得分會降低,而測試集得分會上升,但是隨著訓練集的上升,會導致模型的過擬合,使得模型訓練的效率大大下降。
在訓練的時候偶爾會出現過擬合。雖然模型可以準確地擬合訓練數據,但是無法高效的預測除訓練集以外的數據。如果此時使用測試集進行測試,測試集中的部分信息已經在訓練集出現,因此可能會過擬合,因此需要從訓練數據中取部分當作驗證集,但不參與訓練。因此,本文實驗還在XGBoost模型上做了K折交叉驗證(KFlod),K折交叉驗證會將數據集劃分為k個分組,成為折疊(fold)。使用該方法,對sample_influence、ntrees_estimators 、gamasolve、max_depthsolve這幾個參數進行了K折交叉驗證,并且繪制了分析圖像,對它們參數的變化對結果影響進行了可視化分析。
XGBoost模型在訓練之前,會對數據集的特征進行重要性的劃分,因為效率是模型最重要的因素之一[9]。如果一次性讀取所有特征,會導致復雜度提高,所以要精簡特征。

圖2 訓練集個數影響
模型的參數對于算法的評分起著至關重要的作用,訓練模型之前需要對模型的參數有一定的了解。XGBoost把參數分成了3類:Booster參數、通用參數和學習目標參數,表1舉例說明了部分參數,其中在模型調參的時候,參數的學習率往往是被調試的參數。

表1 XGBoost參數說明
由圖3可以看出隨著生成的最大樹的數目增加,模型的得分也會越來越高,但是n_estimators數量太大,會導致模型訓練時間增加。所以n_estimators的值不能選最高點。圖4可以看出不同的gamma參數得分,gamma參數從0一直下降,從3開始上升。所以還是將gamma參數設置成默認參數0的效果最好。模型對學習率進行了實驗。

圖3 不同n_estimators的得分

圖4 不同數量gamma參數得分
由表2可以看出當學習率從0.02升至0.06時,各項得分都達到了最高,當學習率為0.08時,指標沒有明顯提升,所以為了避免網絡不能收斂,最終將學習率設定為0.06。

表2 XGBoost結果
筆者使用了CSE-CIC-IDS 2018數據集進行了邏輯回歸等算法結果分析,然后與XGboost模型進行比較,表3是經典分類算法的評估表,其中KNN的得分綜合最高,但是訓練速度非常緩慢,可能導致過擬合。

表3 經典算法得分表
通過對XGBoost模型參數的交叉驗證,得出不同參數對應準確率的曲線圖,實驗結果分析表明基于XGBoost模型的入侵檢測模型能夠較好地完成分類任務。
筆者對最新的CSE-CIC-IDS入侵檢測數據集進行數據預處理,創建了訓練集和測試集,在此基礎上基于XGBoost設計并開發了入侵檢測模型。本模型可以對攻擊和未被攻擊數據進行區分。但是無法區分攻擊數據的攻擊類型。后續希望可以解決多分類問題。