1. 程式人生 > >高速網絡包過濾

高速網絡包過濾

tegra 端口號、ip 位置 fire 產品 計算 tcp/ip 異常 highlight

  版權申明:本文為博主窗戶(Colin Cai)原創,歡迎轉帖。如要轉貼,必須註明原文網址

  http://www.cnblogs.com/Colin-Cai/p/7609137.html 

  作者:窗戶

  QQ:6679072

  E-mail:[email protected]

  WAF(Web Applicantion firewall, Web防火墻)的實現有多種手段,基於regex(Regular Expression,正則表達式),然後編譯成一個大狀態機是目前主流的方式。當然,阿拉雲安全的主架構師講了個ppt,直接說regex來做防火墻有不合理的地方,理由是使用regex做防火墻,其計算復雜度最高的那一個regex是整個系統的短板,如果這個regex的時間復雜度過高,攻擊者完全可以利用這一點攻擊WAF達到DDOS的效果。從而,他覺得regex遲早應該退出WAF的領域,而用人工智能白名單的新一代WAF才是未來WAF的主流。這位仁兄說的是有道理的,正則表達式做的WAF異常復雜,運算強度高,這些瓶頸業內早就熟知,未來應當屬於人工智能。接下去的相當一段時間,我也的確需要思考思考下一代的WAF是具體如何更好的結合人工智能。話說回來,畢竟在可預見的時間裏,基於regex的WAF還是主流。吐槽一下,正則表達式真的是一個我不知道該說是天才還是該說是垃圾的翻譯,讓我每當寫到一次就想吐槽一次。

  話題有些扯遠了,越是今天信息如此膨脹,WAF越是會偏向於用電腦來解決而非嵌入式設備,但和我要提到的話題牽涉到的都是包過濾。在信息膨脹的今天,百M甚至千M已經不能滿足我們的需求,主幹網上萬M交換機用來滿足大數據量的交換。速度太快,我們實在無法完全使用CPU來處理這一切,CPU只可以作為終端配置等功能,而對於萬M網絡本身的控制應使用ASIC(Application Specific Integrated Circuit,專用集成電路),也就是為此應用專門設計一個芯片,而非用於多種場合的通用芯片。然而ASIC無法升級,若要升級只能替換。FPGA可以替代這個,同時滿足ASIC的需求和升級的需求,目前高端的FPGA的主時鐘可以很快,但當然也挺昂貴。

  想起大約十年以前,我們利用FPGA處理NGN信令,涉及到網絡包的過濾、統計等。當時,我們對於包的過濾是半定死的,比如UDP還是TCP、端口需要不需要過濾、如果需要端口過濾端口多少、IP需要補需要過濾、如需要IP過濾IP如何過濾,如此設計是因為對於當時的應用來說也已經足夠。

  如果熟悉抓包工具,比如tcpdump,會想到平常的時候我們對於2~4層的抓包的確不會想WAF那樣動輒regex作為判斷條件,而是一堆基於固定位置(比如對於UDP包,其端口號、IP地址等在包中的偏移都是固定的)的數值等式或不等式作為bool值連成的bool表達式。我們就以tcpdump命令的參數來說明,比如tcpdump tcp and dst host 192.168.218.1 and src port 22,其中tcp、 dst host 192.168.1.1、src port 23就是三個不同的bool值。如果熟悉tcpdump和TCP/IP,對照資料,我們可以重新修改上述規則,把tcp、dst host、src port解析為偏移,從而整個規則寫作偏移的形式。在絕大多數的應用下,一條過濾裏面這樣獨立的bool值不超過8個。

  硬件的好處是快速、直接,軟件的好處是高擴展性,我們完全可以結合兩者。用上位機(可能是控制的電腦,也可能只是內部的一個嵌入式CPU)把tcp and dst host 192.168.218.1 and src port 22這樣容易閱讀的東西翻譯為偏移量、bool值這樣的東西,並且給出各個bool值計算中偏移量從小到大排列,如果基礎的bool值計算只有最多8條這樣的情況,那麽其實只需要FPGA內部做一個8位地址1位輸出的RAM(可以設置,所以選擇RAM而非ROM)即256bits的存儲的RAM,上位機把RAM裏面存儲的所有值算出來並傳給FPGA。

  比如之前,tcp and dst host 192.168.218.1 and src port 22,3個bool值映射到1個布爾值,其實只需要2^3=8bits存儲,8個bits分別為0,0,0,0,0,0,0,1,這就是RAM存儲的內容。

  甚至於,軟件還可以比這個更加強大,可以考慮合並多條規則,切割多條規則,其實多條規則的多個bool表達式最終也通過and或者or來連接的,最後或許還有一個not,從整體來看歸根結底還是一條規則。

  用RAM來計算bool表達式雖說無法通用,因為其存儲伴隨著bool表達式的長度是乘方級的擴展,但簡單、快。設計此類電路,簡單就是美,對於電路的綜合來說是至關重要的。並且,可以可以如此設置多條規則,但每條規則基本是獨立工作。

  隨著FPGA收包的過程,依次匹配規則中的偏移量,計算出每個bool值,從而最終拼出查RAM的地址,從而查出該包是通過還是攔截。

  我曾經考慮過用逆波蘭式去計算,但對於這種場合似乎有很多的不方便,倒是RAM簡單暴力直接。那可能會問,如何過濾規則過於復雜了怎麽辦,那就直接考慮不支持,任何產品都有一個設計規格,不可能無條件的滿足所有人的需求。

高速網絡包過濾