陸超杰,楊鑫,王啟蒙,朱逸廷,陶松
(1.國核自儀系統(tǒng)工程有限公司,上海 200240;2.烽臺科技(北京)有限公司,北京 100195)
隨著互聯(lián)網(wǎng)技術(shù)在工業(yè)控制領(lǐng)域的廣泛應(yīng)用,工業(yè)控制網(wǎng)絡(luò)智能化和自動化的水平越來越高,系統(tǒng)也從隔離封閉的環(huán)境逐步轉(zhuǎn)為半開放的系統(tǒng),甚至與互聯(lián)網(wǎng)直接進行連接[1-2]。工業(yè)控制網(wǎng)絡(luò)的發(fā)展造成生產(chǎn)力提高的同時,也帶來了安全方面的挑戰(zhàn)。
通過對工業(yè)控制網(wǎng)絡(luò)熱數(shù)據(jù)的分析,可以實現(xiàn)對生產(chǎn)環(huán)境的監(jiān)控,實現(xiàn)對諸如高溫、高壓等異常狀況的預(yù)警。同時大多數(shù)安全軟件依靠對數(shù)據(jù)幀進行捕獲與分析來實現(xiàn)安全防護的功能,但工業(yè)控制網(wǎng)絡(luò)日益增長的帶寬對數(shù)據(jù)流量的捕獲造成了極大的限制[3]。為了應(yīng)對這些問題,需要一種在高速網(wǎng)絡(luò)環(huán)境下能夠?qū)崿F(xiàn)低延遲、低丟失率的方法,對數(shù)據(jù)包進行捕獲轉(zhuǎn)儲。通過對轉(zhuǎn)儲數(shù)據(jù)的分析處理,實現(xiàn)對工業(yè)控制網(wǎng)絡(luò)的安全監(jiān)控。
在傳統(tǒng)的網(wǎng)絡(luò)數(shù)據(jù)轉(zhuǎn)儲中常用 Wireshark、TCPDUMP 等軟件進行數(shù)據(jù)包捕獲,這類軟件依賴操作系統(tǒng)提供的接口獲取數(shù)據(jù)幀,當數(shù)據(jù)量過大時不能完整對數(shù)據(jù)流進行捕獲,從而出現(xiàn)丟包等現(xiàn)象[4-6]。并且在工業(yè)控制網(wǎng)絡(luò)中數(shù)據(jù)包長度在 64~ 100 bit 區(qū)域附近數(shù)據(jù)包較多,而操作系統(tǒng)的網(wǎng)絡(luò)協(xié)議棧是通過中斷來獲取數(shù)據(jù)包到達的消息,長度較短的數(shù)據(jù)包在相同的帶寬下造成的中斷次數(shù)更多,給操作系統(tǒng)造成了極大的中斷開銷[7]。
而 DPDK 則通過用戶空間驅(qū)動的方式繞過內(nèi)核網(wǎng)絡(luò)協(xié)議棧,將所有必要的驅(qū)動程序移至用戶空間,從而避免系統(tǒng)調(diào)用并實現(xiàn)應(yīng)用程序的零拷貝訪問。在用戶空間通過輪詢的方式判斷數(shù)據(jù)幀的到達,直接從網(wǎng)絡(luò)設(shè)備獲取數(shù)據(jù)并進行處理,極大地提高了數(shù)據(jù)包獲取的性能。
針對萬兆級工業(yè)熱數(shù)據(jù)采集存儲問題,本文提出了一種基于數(shù)據(jù)平面開發(fā)框架 DPDK 的網(wǎng)絡(luò)數(shù)據(jù)幀采集存儲方案,在構(gòu)建的工控網(wǎng)絡(luò)靶場中得以驗證,在保證快速采集工業(yè)熱數(shù)據(jù)的同時,保證數(shù)據(jù)的完整性。
數(shù)據(jù)平面開發(fā)框架 DPDK 是一個由 Linux 開源基金會管理的開源軟件項目。它提供一組用于數(shù)據(jù)平面處理的函數(shù)庫和基于輪詢模式的用戶空間網(wǎng)卡驅(qū)動程序,將數(shù)據(jù)包的處理從內(nèi)核空間轉(zhuǎn)移到了用戶空間。與內(nèi)核空間提供的基于中斷的驅(qū)動程序相比,實現(xiàn)了更高的計算效率與更高的數(shù)據(jù)吞吐量。
DPDK 框架通過環(huán)境抽象層,隱藏了具體的實現(xiàn)細節(jié),并且為不同的硬件平臺和操作系統(tǒng)提供了統(tǒng)一的編程接口,實現(xiàn)了源代碼級別的可移植性。DPDK 還提供多線程與多進程模型、CPU 親和性、內(nèi)存緩沖池、原子與鎖定操作及無鎖循環(huán)隊列等功能。
Libpcap 是一個可移植的用于網(wǎng)絡(luò)流量捕獲和分析的函數(shù)庫,包括數(shù)據(jù)包嗅探、網(wǎng)絡(luò)監(jiān)視、流量生成等功能。Libpcap 為不同操作系統(tǒng)提供一套與操作系統(tǒng)無關(guān)的接口,來實現(xiàn)應(yīng)用程序?qū)Χ鄠€操作系統(tǒng)數(shù)據(jù)包捕獲的需求。
REST 是一種基于超媒體構(gòu)建分布式系統(tǒng)的架構(gòu)風格。在通常情況下,RESTful API 會使用 HTTP 作為應(yīng)用程序協(xié)議。RESTful API 圍繞任何類型的對象、數(shù)據(jù)或服務(wù)等資源進行設(shè)計,每一個資源可以被 URL 唯一標識。RESTful API 使用統(tǒng)一的接口,有助于實現(xiàn)客戶端與服務(wù)器分離。
gRPC 是一個開源的高性能遠程過程調(diào)用框架,可以在多種不同的編程語言環(huán)境和硬件平臺下進行工作。它可以通過負載均衡、跟蹤和身份驗證動態(tài)的與數(shù)據(jù)中心進行連接。典型的 gRPC 客戶端將會公開實現(xiàn)特定功能的本地函數(shù),以供遠程計算機上的另一個進程調(diào)用。并且將遠程調(diào)用偽裝成本地調(diào)用。
本方案采用模塊化設(shè)計思想,按照所負責的功能分為控制層與數(shù)據(jù)層兩大模塊,模塊之間通過遠程過程調(diào)用進行通信??刂茖臃譃閮蓚€子模塊,分別是調(diào)度模塊與信息采集模塊。數(shù)據(jù)層分為收發(fā)模塊、采集模塊與匯聚模塊。控制層根據(jù)任務(wù)需求,對位于本地或遠程的數(shù)據(jù)層下達指令完成相應(yīng)任務(wù),并采集數(shù)據(jù)層上報的相關(guān)信息;數(shù)層根據(jù)控制層下發(fā)的任務(wù)完成采集匯聚,并將過程信息與執(zhí)行結(jié)果上報給控制層。整個系統(tǒng)的架構(gòu)如圖1 所示。
圖1 基于軟件定義網(wǎng)絡(luò)的數(shù)據(jù)采集存儲系統(tǒng)結(jié)構(gòu)
調(diào)度模塊負責本系統(tǒng)與外部應(yīng)用的協(xié)同工作,具體過程如圖2 所示。調(diào)度模塊根據(jù)外部應(yīng)用發(fā)布的任務(wù)信息生成任務(wù),并放入按照一定優(yōu)先級排序的任務(wù)隊列,等待任務(wù)執(zhí)行。當數(shù)據(jù)層空閑的時候,調(diào)度模塊向控制層下發(fā)指令并推送任務(wù)信息,使控制層開始工作。同時調(diào)度模塊根據(jù)外部應(yīng)用的請求返回任務(wù)的執(zhí)行情況或任務(wù)的執(zhí)行結(jié)果信息。
圖2 采集調(diào)度模塊流程示意圖
在開發(fā)跨編程語言或跨硬件平臺軟件時,通常會因為進程之間的通信問題而不能簡單高效地集成,而單一程序又不能有效地實現(xiàn)系統(tǒng)需求。所以為了更好地與外部應(yīng)用集成以進行協(xié)同工作,需要合適的通信協(xié)議來完成進程之間的通信。
在與外部應(yīng)用集成的情況下,要求協(xié)議層次清晰、語義簡潔,而對性能要求不高。所以調(diào)度模塊采用 HTTP RESTful API 風格的接口進行與外部應(yīng)用的通信,以保證與其他應(yīng)用簡單集成。
而在與同一應(yīng)用不同模塊之間的通信,則要求高性能與快速響應(yīng)。所以調(diào)度模塊采用gRPC 框架進行不同模塊之間的通信。
在系統(tǒng)數(shù)據(jù)層運行時,會產(chǎn)生系統(tǒng)運行時數(shù)據(jù),包括運行狀況、轉(zhuǎn)儲數(shù)目、轉(zhuǎn)儲文件大小等,通過這些數(shù)據(jù)可以對系統(tǒng)健康狀況、任務(wù)完成進度等進行判斷。
信息采集模塊會在控制層執(zhí)行任務(wù)時,采集控制層上報的運行數(shù)據(jù),并緩存在特定的存儲空間中,供外部應(yīng)用調(diào)取。并且在任務(wù)結(jié)束時采集任務(wù)完成信息。具體操作流程如圖3 所示。
圖3 信息采集模塊流程示意圖
同時,在萬兆級別的網(wǎng)絡(luò)環(huán)境下,每秒產(chǎn)生的數(shù)據(jù)量通常有1G 以上,遠超普通機械硬盤的寫入速度,而固態(tài)硬盤價格昂貴,不適合作為大量數(shù)據(jù)的存儲介質(zhì)。為了實現(xiàn)轉(zhuǎn)儲文件在高網(wǎng)絡(luò)負載的情況下,能夠快速存儲,本方案采用 Linux 內(nèi)存文件系統(tǒng) tmpfs 來作為系統(tǒng)臨時文件的緩存方式。tmpfs 是Linux 中的一種文件系統(tǒng),他將所有的文件都存儲在內(nèi)存或交換分區(qū)中。將文件放入tmpfs 是加快文件訪問速度的有效方法。
在本方案中,使用 Libpcap 將從無鎖循環(huán)隊列中取出的數(shù)據(jù)幀存儲為 pcapng 格式的臨時文件。pcapng 是下一代網(wǎng)絡(luò)數(shù)據(jù)包跟蹤轉(zhuǎn)儲格式,具有良好的可擴展性、可移植性,并且可以進行數(shù)據(jù)的合并與追加。pcapng 格式嵌入了豐富的文件信息,供其他程序使用,并且數(shù)據(jù)格式獨立于網(wǎng)絡(luò)設(shè)備、硬件平臺與操作系統(tǒng),可以簡單地將數(shù)據(jù)幀轉(zhuǎn)儲文件推送到服務(wù)器等其他設(shè)備進行分析。pcapng 格式解決了pcap 格式的一些不足,支持諸如多網(wǎng)絡(luò)接口捕獲、更高精度與長度的64 位時間戳、在文件中存儲額外元數(shù)據(jù)等,是工業(yè)互聯(lián)網(wǎng)熱數(shù)據(jù)轉(zhuǎn)儲的良好選擇。
采集模塊會在的采集線程在采集工作開始時,會在內(nèi)存文件系統(tǒng)中創(chuàng)建一個臨時的 pcapng 文件。之后采集模塊會從無鎖循環(huán)隊列中取出數(shù)據(jù)幀,并通過 Libpcap 寫入臨時pcapng 文件。當文件臨時到達一定大小,采集線程會創(chuàng)建新的臨時文件并將之前的文件路徑通過無鎖循環(huán)隊列發(fā)送到匯聚模塊。
在采集模塊中,不同工作線程同時進行工作,相同時間段產(chǎn)生的數(shù)據(jù)幀可能分散在不同的臨時文件中,直接使用臨時文件進行分析等工作將會產(chǎn)生不確定的結(jié)果。
在傳統(tǒng)的數(shù)據(jù)包轉(zhuǎn)儲方案中,Linux 系統(tǒng)的網(wǎng)絡(luò)流量通過內(nèi)核協(xié)議棧進行處理,并且通過內(nèi)核中的網(wǎng)絡(luò)過濾器 Netfilter 進行過濾。當網(wǎng)絡(luò)數(shù)據(jù)幀到達網(wǎng)絡(luò)設(shè)備時,網(wǎng)絡(luò)設(shè)備會以中斷的形式通知內(nèi)核協(xié)議棧對數(shù)據(jù)幀進行處理,在數(shù)據(jù)量大時會產(chǎn)生大量的中斷,導致CPU 無法處理其他進程。而內(nèi)核對數(shù)據(jù)幀進行處理后還需將數(shù)據(jù)負載拷貝到用戶空間,并通知用戶空間應(yīng)用程序。在這個過程中存在兩次上下文切換、內(nèi)核協(xié)議棧數(shù)據(jù)處理和內(nèi)核空間到用戶空間數(shù)據(jù)拷貝造成的開銷。本方案中采用的是DPDK 收發(fā)框架構(gòu)建系統(tǒng)收發(fā)能力,與傳統(tǒng)的網(wǎng)絡(luò)數(shù)據(jù)幀轉(zhuǎn)儲方案不同,通過用戶空間驅(qū)動的方式繞過內(nèi)核網(wǎng)絡(luò)協(xié)議棧,將所有必要的驅(qū)動程序移至用戶空間,從而避免系統(tǒng)調(diào)用并實現(xiàn)應(yīng)用程序的零拷貝訪問。在用戶空間通過輪詢的方式判斷數(shù)據(jù)幀的到達,直接從網(wǎng)絡(luò)設(shè)備獲取數(shù)據(jù)并進行處理,極大地提高了數(shù)據(jù)包獲取的性能,具體流程示意圖如圖4 所示。
圖4 收發(fā)模塊DPDK 收發(fā)框架示意圖
DPDK 框架使用內(nèi)存池技術(shù),避免了在高并發(fā)場景下內(nèi)存申請造成的開銷與延遲。DPDK 將數(shù)據(jù)幀緩存在一種名為Mbuf 結(jié)構(gòu)體中,當收包模塊輪詢過程中檢測到網(wǎng)絡(luò)設(shè)備的接收隊列不為空時,將會根據(jù)隊列中數(shù)據(jù)幀的數(shù)量在內(nèi)存池中申請若干個Mbuf 內(nèi)存塊,并將隊列中的數(shù)據(jù)幀通過直接存儲器訪問寫入到Mbuf 中;DPDK 發(fā)送數(shù)據(jù)包時,等待網(wǎng)卡將數(shù)據(jù)發(fā)送完畢后將Mbuf 內(nèi)存塊重新放回內(nèi)存池中。整個過程沒有不確定大小的內(nèi)存塊的申請與釋放,極大地提高了數(shù)據(jù)幀的處理效率。
DPDK 框架支持CPU 親和與CPU 獨占功能特性,它可以將每個工作線程綁定到不同的CPU 核心上面,使該線程只能在特定的核心上運行,線程不會在不同核心之間頻繁遷移,減少調(diào)度產(chǎn)生的開銷,避免了緩存失效造成的命中問題或其他消耗。
DPDK 提供流分類技術(shù),DPDK 流分類器通過無鎖循環(huán)隊列,將數(shù)據(jù)幀均勻分配給收發(fā)模塊的各個工作線程,工作線程從隊列中取出數(shù)據(jù)幀進行克隆操作后推入發(fā)送隊列進行發(fā)送,然后將克隆的數(shù)據(jù)幀推入采集隊列交由采集模塊進行采集。
在本方案中,收發(fā)模塊根據(jù)調(diào)度模塊發(fā)送的指令信息,創(chuàng)建流規(guī)則并使能 DPDK 流分類器用來捕捉符合特定規(guī)則的數(shù)據(jù)幀。對于不能匹配流規(guī)則的數(shù)據(jù)幀直接進行轉(zhuǎn)發(fā),以節(jié)省存儲空間。對于匹配流規(guī)則的數(shù)據(jù)幀,則增加對存放該數(shù)據(jù)幀的 Mbuf 內(nèi)存塊的引用以進行淺拷貝,然后將淺拷貝數(shù)據(jù)幀包推入存儲隊列,之后將原數(shù)據(jù)幀推入網(wǎng)卡發(fā)送隊列。
本方案提出了一種工業(yè)控制網(wǎng)絡(luò)熱數(shù)據(jù)采集存儲方案,采用數(shù)據(jù)平面開發(fā)框架作為開發(fā)框架,并結(jié)合Libpcap、gRPC 等函數(shù)庫,能夠在高負載工業(yè)控制網(wǎng)絡(luò)場景下,實現(xiàn)對萬兆級別的工業(yè)控制網(wǎng)絡(luò)熱數(shù)據(jù)采集與存儲,并保證轉(zhuǎn)儲數(shù)據(jù)的可靠性與實時性。并且本方案可以結(jié)合鏈路聚合技術(shù)使用,對數(shù)據(jù)層進行動態(tài)擴容,實現(xiàn)更高帶寬網(wǎng)絡(luò)數(shù)據(jù)的采集與轉(zhuǎn)儲。系統(tǒng)可以穩(wěn)定高效地完成相應(yīng)工作,并實現(xiàn)相應(yīng)系統(tǒng)要求。