inpfw 模塊防火牆簡介
inpfw 是基於 SylixOS 的一款報文截獲分析工具。藉助它,可以實現基於 SylixOS 的各種嵌入式使用場合的防火牆工具開發。inpfw 具備如下功能:
- 支持多個模塊的註冊;
- 支持多個網卡報文截獲分析;
- 支持截獲網卡驅動傳入到協議棧的所有報文;
- 支持報文動態分析,並將結果傳入到註冊的模塊;
- 支持動態黑白名單;
- 支持記錄發送方設備信息;
- 支持模塊自定義發送方保存信息;
- 支持禁止 inpfw 動態刪除發送端信息;
- 採用 hash + cache 模式,加速發送端信息查找速度。
inpfw 模塊防火牆原理
inpfw 模塊防火牆以 ko 形式,加載進 SylixOS 系統。 inpfw 加載後會將自己的 hook 註冊到 SylixOS 提供的 innerfw。此時,用戶及可以調用 inpfw 提供的一些 API 接口進行子模塊的註冊等各種操作。
inpfw 模塊正常運行時,所有接收到的報文都會被 inpfw 的 hook 截獲,並現在 inpfw 內部先對報文進行整體的分析,分析內容包括:
- 對報文類型進行分析,根據報文類型截獲對應的報文頭,包括,以太網頭部,VLAN 頭部,ARP 頭部,IP 頭部, ICMP 頭部, UDP 頭部, TCP頭部;
- 對報文的發送端設備信息數據進行獲取並管理;
完成上述兩步之後,inpfw 會將分析的結果,報文,以及管理的設備信息一同發給註冊的子模塊接口,由子模塊根據其對應的需求對報文進行進一步細處理。
等到子模塊處理完成之後,inpfw 會根據子模塊返回的結果,確定當前的報文是否需要被過濾;
inpfw 模塊防火牆相關結構
inpfw 防火牆會爲註冊到其內部的子模塊提供對應的報文和設備信息,這些信息主要是由以下這個結構體包含:
/*********************************************************************************************************
報文信息結構定義
*********************************************************************************************************/
struct pkt_info {
struct netdev *pIn; /* 網卡結構 */
struct pbuf *pBuf; /* 報文 */
struct eth_hdr *pEthHdr; /* eth 頭 */
struct eth_vlan_hdr *pVlanHdr; /* vlan 頭 */
struct etharp_hdr *pArpHdr; /* arp 頭 */
struct ip_hdr *pIpHdr; /* ip 頭 */
struct udp_hdr *pUdpHdr; /* udp 頭 */
struct tcp_hdr *pTcpHdr; /* tcp 頭 */
struct icmp_echo_hdr *pImcpHdr; /* icmp 頭 */
PVOID pvRemotDevPriv; /* 對端結點私有信息 */
};
typedef struct pkt_info __PKT_INFO;
typedef struct pkt_info *__PPKT_INFO;
這個結構體主要包含以下內容:
pIn:當前收到這個報文的網卡設備
pBuf: 當前收到的完整報文(pbuf 格式)
pEthHdr: 當前報文的以太網頭部信息
pVlanHdr: 當前報文的 VLAN 頭部信息(如果存在)
pArpHdr: 當前報文的 ARP 頭部信息(如果存在)
pIpHdr: 當前報文的 IP 頭部信息(如果存在)
pUdpHdr: 當前報文的 UDP 頭部信息(如果存在)
pTcpHdr: 當前報文的 TCP 頭部信息(如果存在)
pImcpHdr: 當前報文的 ICMP 頭部信息(如果存在)
pvRemotDevPriv: 用於保存子模塊對當前報文發送端處理的相關信息
inpfw 模塊防火牆使用
-
防火牆的加載:
inpfw 是基於 SylixOS 的 ko 模塊,只需根據對應硬件平臺編譯,並加載即可。 -
防火牆的開啓與關閉:
inpfw 支持所有有線網卡的接收報文截獲,其提供了 inpfw 命令,用於開啓對應網卡的防火牆功能:
如需要開啓 en1 的網絡防火牆,只需要使用如下命令即可:inpfw en1 1
如需要關閉 en1 的網絡防火牆,只需要使用如下命令即可:
inpfw en1 0
如果想看當前那些網口開啓了防火牆,只需輸入 inpfw,如下所示:
-
查詢當前已經註冊了的模塊
使用 proc 文件系統,可以查看當前防火牆註冊的所有子模塊信息,如下所示:
其中 FUNC_HANDLE 記錄當前總模塊回調函數位置。 -
查看防火牆管理的所有網絡環境裏的設備
上文說過,inpfw 防火牆可以管理保存當前網絡環境中跟本設備通信的其他設備信息,同樣的,使用 proc 文件系統可以查看到當前防火牆管理的所有設備,使用如下:
其中, IDLE_TIME 表示當前設備空閒時間,即當前設備多久沒有跟自己通信,FORBIDDEN_TIMES 表示當前設備被拉黑時間。
防火牆相關 API 介紹
inpfw 提供瞭如下 API ,下面對其詳細介紹:
-
子模塊註冊:
INT32 inpFWPktAnaRegister (PCHAR pcName, __PFUNC_PKT_ANA pPktAnaFunc);
參數:
pcName:子模塊的名字
pPktAnaFunc:子模塊的回調函數,子模塊通過這個函數來接收防火牆提供的報文和設備信息。
其格式如下:typedef INT32 (*__PFUNC_PKT_ANA)(__PPKT_INFO);
返回值:
本 API 的返回值,是對應模塊的 ID 號,此 ID 號用於卸載子模塊。如果,註冊失敗,則返回 PX_ERROR. -
子模塊卸載:
INT32 inpFWPktAnaUnRegister (UINT32 uiModID);
參數:
uiModID:子模塊註冊時獲取的 ID
返回值:
本 API 返回卸載結果,註冊成功返回 ERROR_NONE,失敗則返回 PX_ERROR. -
遠端設備不允許自動刪除:
INT32 inpFWDevNotDel (PVOID pvRemotDevPriv);
inpfw 對於空閒時間長的設備會進行自動刪除操作,用戶可以使用此接口,禁止 inpfw 自動刪除對應的模塊。
參數:
pvRemotDevPriv:遠端設備私有信息
返回值:
本 API 返回操作結果,註冊成功返回 ERROR_NONE,失敗則返回 PX_ERROR. -
遠端設備允許自動刪除:
INT32 inpFWDevAllowDel (PVOID pvRemotDevPriv);
此函數用於通知 inpfw ,當前設備可以進行自動刪除操作。
參數:
pvRemotDevPriv:遠端設備私有信息
返回值:
本 API 返回操作結果,註冊成功返回 ERROR_NONE,失敗則返回 PX_ERROR. -
添加黑白名單高級接口:
PVOID inpFWAdd2bAwListEx (UINT32 uiModId, CPCHAR pcIfname, INT iRule, BOOL bIn, UINT8 pucMac[], CPCHAR pcAddrStart, CPCHAR pcAddrEnd, UINT16 usPortStart, UINT16 usPortEnd, BOOL bBaWFlag, UINT32 uiAutoDelTime, PVOID pvCallbkArg, __ITEM_DEL_CALL_BK pItemDelCallBk);
此函數用於添加黑白名單,其提供了豐富的配置參數:
uiModId:子模塊 ID
pcIfname:網卡名稱
iRule:對應的規則, MAC/IP/UDP/TCP/…
bIn:TRUE: INPUT FALSE: OUTPUT
pucMac:通信的 MAC 地址數組
pcAddrStart:通信 IP 地址起始, 爲 IP 地址字符串
pcAddrEnd:通信 IP 地址結束, 爲 IP 地址字符串
usPortStart:通信的本地起始端口號(網絡字節序), 僅適用與 UDP/TCP 規則
usPortEnd:通信的本地結束端口號(網絡字節序), 僅適用與 UDP/TCP 規則
bBaWFlag:黑名單還是白名單 (TRUE: 白名單 FALSE: 黑名單)
uiAutoDelTime:名單條目自動刪除時間(單位:分鐘,0 : 永不刪除)
pvCallbkArg:條目刪除時回調函數參數
pItemDelCallBk:條目刪除時回調函數返回值:
如果添加成功,則返回對應的條目句柄,如果添加失敗,則返回空。 -
添加 MAC 黑名單名單:
PVOID inpFWAddMacRule2bAwList (UINT32 uiModId, CPCHAR pcIfname, BOOL bIn, UINT8 pucMac[], BOOL bBaWFlag, UINT32 uiAutoDelTime);
此函數用於添加一個 MAC 規則的黑白名單,使用方法同 inpFWAdd2bAwListEx。
-
添加 IP 黑名單名單:
PVOID inpFWAddIpRule2bAwList (UINT32 uiModId, CPCHAR pcIfname, BOOL bIn, UINT8 pucMac[], CPCHAR pcAddrStart, CPCHAR pcAddrEnd, BOOL bBaWFlag, UINT32 uiAutoDelTime);
此函數用於添加一個 IP 規則的黑白名單,使用方法同 inpFWAdd2bAwListEx。
-
獲取當前黑白名單個數:
UINT8 inpFWbAwCountGet (UINT32 uiModId, INT32 iRule, BOOL bBaWFlag);
參數:
uiModId:子模塊 ID
iRule:規則
bBaWFlag:黑名單還是白名單 (TRUE: 白名單 FALSE: 黑名單)
返回值:
返回當前需要獲取對應規則的還白名單個數。 -
刪除黑白名單名:
INT32 inpFWDelFromBaWList (PVOID pbAwHandle);
參數:
pbAwHandle:黑白名單添加時返回的句柄
返回:
刪除成功則返回 ERROR_NONE,失敗返回 PX_ERROR。
基於 inpFw 的子模塊開發
上文描述了 inpFw 防火牆框架的相關原理,使用方法和 API 等內容,本節簡要的要描述一種可以基於 inpFw 開發的一種簡單思路,其主要分爲如下幾步:
-
編寫對應的報文處理函數:
這裏指的就是註冊子模塊時,傳入的報文處理回調函數。其格式:
typedef INT32 (*__PFUNC_PKT_ANA)(__PPKT_INFO);
其內部實現內容,大致可如下形式:static INT32 __packetHandle (__PPKT_INFO pPktInfo) { // 1. 通過 pPktInfo 獲取到自己需要的內容,如整個報文pBuf, // 以太網頭pEthHdr,對應的發送端私有信息 pvRemotDevPriv 等 // 2. 通過第一步拿到的內容 ,對當前報文進行對應的分析處理,可以拉黑,或者放入白名單 // 3. 通過 pvRemotDevPriv,對當前的報文的發送方,進行分析判斷等相關處理。 // 處理好後,可以將需要保存的跟發送端相關的數據,存放在 pvRemotDevPriv 中。 // 4. 返回處理結果 }
-
註冊子模塊:
參數上述 API 註冊。 -
啓動對應網口的防火牆:
參考上述防火牆使用方法。