1. 程式人生 > >一種攔截Linux原始套接字IO的方法

一種攔截Linux原始套接字IO的方法

描述
   原始套接字具有廣泛的用途,特別是用於自定義協議(標準協議TCP、UDP和ICMP等外)的資料收發。在Linux下攔截套接字IO的一般方法是攔截對應的套接字系統呼叫,對於傳送為sendmsg和sendto,對於接收為recvmsg和recvfrom。這種方法雖然也能攔截原始套接字IO,但要先判斷套接字的型別,如果為SOCK_RAW(原始套接字型別),那麼進行攔截處理,這樣一來由於每次IO都要判斷套接字型別,效能就比較低了。因此為了直接針對原始套接字來攔截,提高效能,發明了本方法。
   本方法可用於防火牆或主機防護系統中,丟棄接收和傳送的攻擊或病毒資料包。

特點
   執行在核心態,直接攔截所有程序的原始套接字IO,支援IPv4和IPv6。

實現

   原理
      在Linux核心網路子系統中,struct proto_ops結構提供了協議無關的套接字層到協議相關的傳輸層的轉接,而IPv4協議族中內建的inet_sockraw_ops為它的一個例項,對應著原始套接字。因此先找到inet_sockraw_ops,再替換它的成員函式指標recvmsg和sendmsg,就可以實現攔截了。下面以IPv4為例(IPv6同理),說明幾個流程。

   搜尋inet_sockraw_ops
      該流程在掛鉤IO前進行。由於inet_sockraw_ops為Linux核心未匯出的內部符號,因此需要通過特別的方法找到它,該特別的方法基於這樣的一個事實:
      
所有原始套接字介面均存放在以SOCK_RAW為索引的雙向迴圈連結串列中,而inet_sockraw_ops就在該連結串列的末尾。
       核心提供了註冊套接字介面的API inet_register_protosw,對於原始套接字型別,該API將輸入的套接字介面插入到連結串列頭後面。
      演算法如下
      
      註冊p前或登出p後,連結串列如下
      註冊p後,連結串列如下

   掛鉤IO
      該流程在核心模組啟動時進行。

   卸鉤IO
      該流程在核心模組退出時進行。

執行部署

   該方法實現在Linux核心模組中,為了防止其它核心模組可能也註冊了原始套接字介面,因此需要在作業系統啟動時優先載入。   posted on 2016-07-14 10:27 春秋十二月 閱讀(1319) 評論(3)  編輯 收藏 引用 所屬分類: Network