【摘要】本文討論并分析了Netfilter的功能框架、工作原理及數(shù)據(jù)包處理的實(shí)現(xiàn)機(jī)制,設(shè)計(jì)了在Netfilter框架中實(shí)現(xiàn)配電終端報(bào)文預(yù)處理的hook模塊,實(shí)現(xiàn)去除通訊遙控報(bào)文數(shù)字簽名的功能,為配網(wǎng)自動(dòng)化的二次安防提供幫助,同時(shí)為其他通信應(yīng)用中修改tcp包數(shù)據(jù)提供借鑒參考。
【關(guān)鍵詞】Netfilter;hook模塊;mangle函數(shù);報(bào)文處理
引言
配電終端是典型的嵌入式設(shè)備,多基于linux系統(tǒng),是配電自動(dòng)化建設(shè)的重要組成部分。國(guó)家電網(wǎng)公司物資采購(gòu)標(biāo)準(zhǔn)的專用技術(shù)規(guī)范中提出,配電終端應(yīng)配備符合國(guó)調(diào)〔2011〕168號(hào)文件技術(shù)功能要求的非對(duì)稱密鑰技術(shù)單向認(rèn)證模塊,終端側(cè)應(yīng)能夠鑒別配電主站(open3200)的數(shù)字簽名。
配電主站與配電終端建立tcp連接后,以104規(guī)約通信,主站發(fā)往終端的重要104規(guī)約報(bào)文會(huì)單向加密并數(shù)字簽名。本文hook模塊設(shè)計(jì)的報(bào)文預(yù)處理功能正是用于終端側(cè),在通信報(bào)文到達(dá)終端前定位tcp數(shù)據(jù)包中的data區(qū)報(bào)文內(nèi)容,對(duì)報(bào)文進(jìn)行數(shù)字簽名鑒別等預(yù)處理。
1.netfilter處理報(bào)文的流程
1.1 netfilter的框架
Netfilter是Linux 2.4版本引入的一個(gè)子系統(tǒng),它作為一個(gè)通用的、抽象的框架,提供一整套的hook函數(shù)管理機(jī)制,使得諸如數(shù)據(jù)包過濾、網(wǎng)絡(luò)地址轉(zhuǎn)換(NAT)和基于協(xié)議類型的連接跟蹤成為可能[1]。同時(shí)netfilter也支持用戶自定義hook函數(shù)擴(kuò)充以上功能。
Netfilter把數(shù)據(jù)包處理的更流程化,并且實(shí)現(xiàn)了擴(kuò)展過濾策略而不必修改內(nèi)核的功能[2]。該框架為每種網(wǎng)絡(luò)協(xié)議( IPv4、IPv6等)定義了數(shù)據(jù)包處理過程,并定義一些鉤子點(diǎn)(Hook) ,在內(nèi)核中建立了一個(gè)函數(shù)指針鏈表,函數(shù)指針?biāo)傅暮瘮?shù)稱為鉤子函數(shù),其返回值告訴協(xié)議棧如何處理數(shù)據(jù)包[3]。
1.2 報(bào)文處理的實(shí)現(xiàn)原理
Tcp包經(jīng)過netfilter時(shí)的處理流程以及各“鉤點(diǎn)”如圖1所示。
圖1 數(shù)據(jù)包在netfilter中的處理流程
對(duì)于收到的每個(gè)數(shù)據(jù)包,都從“PRE_ROUTING”點(diǎn)進(jìn)來,經(jīng)過路由判決,如果是發(fā)送給本機(jī)的就經(jīng)過“LOCAL_IN”點(diǎn),然后往協(xié)議棧的上層繼續(xù)傳遞;否則,如果該數(shù)據(jù)包的目的地不是本機(jī),那么就經(jīng)過“RORWARD”點(diǎn),由“POST_ROUTING”點(diǎn)將該包轉(zhuǎn)發(fā)出去。對(duì)于上層協(xié)議棧發(fā)送的每個(gè)數(shù)據(jù)包,首先也有一個(gè)路由判決,以確定該包是從哪個(gè)接口出去,然后經(jīng)過“LOCAL_OUT”點(diǎn),最后也是順著“POST_ROUTING”點(diǎn)將該包發(fā)送出去[4]。
2.netfilter下報(bào)文預(yù)處理功能設(shè)計(jì)與實(shí)現(xiàn)
2.1 報(bào)文預(yù)處理的功能設(shè)計(jì)
本文設(shè)計(jì)的報(bào)文預(yù)處理功能是在L inux內(nèi)核Netfilter框架上開發(fā)的一個(gè)內(nèi)核模塊,具有tcp包勾取、識(shí)別、數(shù)據(jù)修改(加密或加數(shù)字簽名)等基本功能,通過動(dòng)態(tài)加載到
Linux內(nèi)核中實(shí)現(xiàn)預(yù)處理功能。本文用到的鉤子點(diǎn)是POST_ROUTING,在該點(diǎn)編寫了相應(yīng)的鉤子函數(shù),并進(jìn)行注冊(cè)和掛接,將tcp數(shù)據(jù)包鉤出來進(jìn)行處理再放回去。
通信tcp包在通過linux網(wǎng)關(guān)轉(zhuǎn)發(fā)時(shí)由預(yù)處理hook程序進(jìn)行處理,程序流程設(shè)計(jì)如 圖2所示:
圖2 程序設(shè)計(jì)流程圖
2.2 報(bào)文預(yù)處理的hook函數(shù)實(shí)現(xiàn)
下文按圖2流程介紹報(bào)文處理的hook函數(shù)部分源代碼。
(1)hook函數(shù)定義如圖3所示:
圖3 hook函數(shù)定義
(2)獲取存放當(dāng)前tcp包數(shù)據(jù)的skb_buff:
圖4 讀取skb_buff
(3)判斷數(shù)據(jù)包是否來自目標(biāo)進(jìn)程的端口號(hào):
if (likely(ntohs(sport) = 5381)) {
return NF_ACCEPT;
} "http://判斷主站進(jìn)程端口號(hào)是否為538
(4)判斷數(shù)據(jù)包是否需要處理
payload = (void *) skb-gt;data + 40;
//+40是從data區(qū)偏移出 ip包頭與tcp包頭
if (*payload==0x68) {
//判斷是否為104規(guī)約報(bào)文
if (*(payload+6)==0x2E) {
//判斷是否為遙控報(bào)文
.......}
}
(5)取出tcp數(shù)據(jù)包中的應(yīng)用層數(shù)據(jù)(data區(qū))也就是實(shí)際的規(guī)約報(bào)文,存入replace字符串:
payload = (void *) skb-gt;data + 40;
replace = payload ;
(6)如圖5處理報(bào)文,以0x00替換16 L1 L2 16型數(shù)字簽名,若想做其他處理都可以借助對(duì)指針字符串replace編程實(shí)現(xiàn):
圖5 替換尾端報(bào)文16 L1 L2 16
(7)重新封裝tcp包,放入傳輸序列:
if (skb!=NULL) {
nf_nat_mangle_tcp_packet(skb,ct,ctinfo, 0,strlen(replace),(char*)replace,strlen(replace)); " " " " "http://重新封裝tcp包 return NF_ACCEPT;
}
這里的mangle函數(shù)調(diào)用是整個(gè)hook功能實(shí)現(xiàn)的核心。
用于修復(fù)seq的hook函數(shù)如圖6所示:
圖6 修復(fù)seq
3.測(cè)試運(yùn)行
本文實(shí)驗(yàn)環(huán)境是在windows系統(tǒng)下,用Linux虛擬機(jī)作為數(shù)據(jù)進(jìn)出內(nèi)網(wǎng)和外網(wǎng)的網(wǎng)關(guān),報(bào)文預(yù)處理程序運(yùn)行在該Linux虛擬機(jī)上,同時(shí)在該windows下用兩個(gè)網(wǎng)絡(luò)調(diào)試助手分別模擬外網(wǎng)主站與內(nèi)網(wǎng)終端。內(nèi)網(wǎng)終端與外網(wǎng)主站通過網(wǎng)關(guān)虛擬機(jī)交換數(shù)據(jù),示意圖見圖7所示:
圖7 模擬通信示意圖
將104規(guī)約下的遙控報(bào)文68 0E 06 00 46 00 2E 01 06 00 01 00 01 60 00 82 16 77 74 16從模擬主站(Tcp server)發(fā)往終端(Tcp client),報(bào)文尾端16 77 74 16為簡(jiǎn)單數(shù)字簽名。如圖8所示:
圖8 主站側(cè)發(fā)出遙控報(bào)文
終端接受到報(bào)文如圖9所示,可見報(bào)文的數(shù)字簽名已被解除,由00 00 00 00替代,如果要對(duì)報(bào)文做其他處理,可以在程序中對(duì)指針字符串replace做相應(yīng)的處理。
4.結(jié)論
本文基于netfilter防火墻提出了一種報(bào)文預(yù)處理方法,用于配電終端側(cè)鑒別并處理配電主站(open3200)的遙控報(bào)文數(shù)字簽名。本方法能夠在傳輸網(wǎng)關(guān)準(zhǔn)確定位到tcp包中的原始報(bào)文數(shù)據(jù),可按用戶需求對(duì)通信報(bào)文進(jìn)行預(yù)處理,無需再在終端應(yīng)用層進(jìn)行報(bào)文處理,減輕了終端的處理壓力、提高終端的響應(yīng)速度。
圖9 終端側(cè)收到的遙控報(bào)文
本文設(shè)計(jì)亦可用于其他的tcp通信場(chǎng)合,提供了一種修改tcp包應(yīng)用層data區(qū)數(shù)據(jù)的實(shí)現(xiàn)方法。
參考文獻(xiàn)
[1]陳慧春.Linux操作系統(tǒng)網(wǎng)絡(luò)協(xié)議棧的設(shè)計(jì)與實(shí)現(xiàn)研究. 成都:電子科技大學(xué)碩士論文,2004:44-47.
[2]岳新. Linux2. 4內(nèi)核下基于Netfilter框架可擴(kuò)展性研究與實(shí)現(xiàn). 哈爾濱:哈爾濱理工大學(xué)碩士論文,2005.
[3]詹瑾,謝贊福. Linux內(nèi)核netfilter包過濾防火墻的設(shè)計(jì)與實(shí)現(xiàn)[J].科學(xué)技術(shù)與工程,2010,10(18):4525.
[4]wjlkoorey,洞悉linux下Netfilteramp;iptables:什么是Netfilter[EB/OL].ChinaUnix.net,2012.