基於VpnService實現網絡防火牆的思路

前言

網絡防火牆相信大家都司空見慣了,市面上app的原理也都以root,監聽底層傳輸狀況爲主,非root通過vpnService監聽數據的爲數不多。這個學期末,剛好學校有實訓課需要做應用,爲了補補網絡的知識,便踏上了非root防火牆,流量監控,網絡抓包等功能的不歸路~

實現原理

通過VpnService監聽到實際應用發送的虛擬數據包,然後解析數據包,記錄數據包的源port【方便構建回覆的虛擬數據包】,目的IP和目的port,以及應用層數據【用於發起真實的應用請求】。
本應用與實際應用構建好虛擬網絡通道後(三次握手),獲取到實際數據後,併發起實際的請求,將返回的數據再包裝成虛擬數據包,發送回實際的應用。
整個過程中,本應用充當實際應用虛擬服務器,且作爲實際請求的客戶端。

實現思路

數據包流向

數據包流向圖

由數據包流向圖可以看出,我們只需要對接收到的虛擬數據包進行過濾處理就可以實現網絡防火牆的功能,流量統計精確到每一個數據包的應用層數據。

底層socket編程

網絡底層實現

考慮到數據小,併發數大的情況下,NIO取代原來的BIO能夠有效減少開銷,同時實際通道的管理會更加方便統一。

網絡調度管理

網絡調度管理

網絡調度使用線程來管理,通信方面用共享內存的方式,使用的是BlockingQueue。每一個實際連接維護一份TCB的連接信息,使用的是ConcurrentHashmap來存儲。併發編程過程中,注意各線程域中的數據同步,也要避免讀寫衝突。

設想:
1)如果能夠對實際的applicationData作緩存處理,或許就能減少網絡請求數。
2)對於頻繁的網絡請求,或許可以通過某種規則認定爲惡意應用。

應用與端口號綁定

應用信息與數據包綁定

因爲數據包不具備實際應用信息,只能夠通過以上途徑獲取綁定信息。可是有時候uid是無法對應上端口號信息,精確性方面有待提高。而且每個請求都需要進行一次IO讀操作,大大延緩了網絡請求。

設想:
對於常駐應用的數據包請求,在第一次截取數據包就把appId和目的IP的映射關係存儲起來,方便以後複用。可問題有二:
1)對於瀏覽器來說,發送的數據包的目的IP會有很多不同,這樣,沒辦法做映射關係。
2)對於使用了負載均衡和重定向的服務器,重定向ip也是變化的,這樣無法做映射關係。

小結

瞭解原理後,設計和開發起來就更簡單了,主要是解析和包裝數據需要點時間,另外構建虛擬網絡通道,根據報文信息進行握手和揮手等相對比較麻煩,且要做好數據包分割,重傳,擁塞控制等,不然準確性與穩定性無法得到保障。

附上github地址,感興趣的可以looklook,一起討論討論:
https://github.com/pencil-box/NetKnight

等有空的時候,繼續把這個項目完善得更好^_^

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章