內(nèi)網(wǎng)穿透工具的原理與開(kāi)發(fā)實(shí)戰(zhàn)

2021-03-05    分類: 網(wǎng)站建設(shè)

在我國(guó),由于網(wǎng)民眾多,運(yùn)營(yíng)商無(wú)法保證為每一個(gè)寬帶用戶提供全球唯一的公網(wǎng)IPv4地址。因此很多用戶會(huì)發(fā)現(xiàn)通過(guò)路由器端查看到的WAN端IP與百度“IP”關(guān)鍵詞所得到的IP不一致,并且前者的IP為一個(gè)私有IP。

而還有一些情況下,公網(wǎng)IP比較昂貴,企業(yè)雖然本身也持有少量的獨(dú)立的公網(wǎng)IP,但是由于成本限制無(wú)法為企業(yè)內(nèi)每一臺(tái)

首先通過(guò)判斷傳入?yún)?shù)決定當(dāng)前使用何種轉(zhuǎn)發(fā)策略。

然后再判斷傳入?yún)?shù)是否正確,通過(guò)正則表達(dá)式等方式驗(yàn)證IP的合法性以及端口范圍。

通過(guò)port2port函數(shù)實(shí)現(xiàn)了兩個(gè)端口同時(shí)監(jiān)聽(tīng)雙向并且轉(zhuǎn)發(fā)數(shù)據(jù)。

在port2host操作中實(shí)現(xiàn)了跳板中轉(zhuǎn)。

在host2host中實(shí)現(xiàn)了主動(dòng)連接打通隧道的功能。

看代碼便可以知道,在Golang中進(jìn)行socket操作的net包要比C語(yǔ)言中的socket.h操作簡(jiǎn)單很多。

轉(zhuǎn)發(fā)功能的核心就在于forward函數(shù)部分。

先輸出一個(gè)日志說(shuō)明是對(duì)哪兩個(gè)連接進(jìn)行雙向轉(zhuǎn)發(fā),然后通過(guò)sync包下的WaitGroup實(shí)現(xiàn)一個(gè)條件阻塞功能,防止在Goroutine還未執(zhí)行完,主線程就已經(jīng)退出了。

然后發(fā)射兩個(gè)Goroutine,分別處理連接1到連接2的IO數(shù)據(jù)包拷貝以及連接2到連接1的IO數(shù)據(jù)包拷貝。因?yàn)橐WC兩個(gè)端口間的通信是全雙工的,也就是兩邊同時(shí)都要能夠互相交換數(shù)據(jù),所以要用Goroutine來(lái)實(shí)現(xiàn)這兩個(gè)操作的并發(fā)。

而IO數(shù)據(jù)包的拷貝核心代碼在connCopy函數(shù)中,根據(jù)是否要記錄流量日志判斷是否要使用io.MultiWriter這個(gè)多路寫(xiě)數(shù)據(jù)流的函數(shù)。

如果打開(kāi)日志文件的文件流成功,則通過(guò)io.MultiWriter函數(shù)生成一個(gè)多路寫(xiě)入流,這里這個(gè)多路寫(xiě)入流的變量名為w,任何寫(xiě)入到w這個(gè)寫(xiě)入流的數(shù)據(jù)都會(huì)同時(shí)寫(xiě)入先前參與執(zhí)行多路寫(xiě)入流創(chuàng)建函數(shù)io.MultiWriter的參數(shù)中,在這里參數(shù)為conn1和logFile,即為端口1和日志文件流。

接著調(diào)用io.Copy將第二參數(shù)的讀取流中讀取到的數(shù)據(jù)源源不斷地拷貝到第一個(gè)參數(shù)的寫(xiě)入流中。

這里要注意io.Copy函數(shù)是同步阻塞的,意味著只要連接沒(méi)有斷開(kāi),那么程序執(zhí)行流將一直卡在這個(gè)函數(shù)。如果拷貝出錯(cuò),那么io.Copy函數(shù)就會(huì)返回,也就是執(zhí)行他下面的代碼??截惓鲥e(cuò)意味著可能連接已斷開(kāi),那么先把寫(xiě)入流的連接斷掉。

這里要重點(diǎn)注意,為什么是斷開(kāi)寫(xiě)入流而不是讀寫(xiě)流全部斷開(kāi)呢。因?yàn)槲覀兦懊姘l(fā)射了兩個(gè)Goroutine,如果盲目全部斷開(kāi),將會(huì)導(dǎo)致另一個(gè)Goroutine中可能還有未寫(xiě)完的數(shù)據(jù)丟失。具體可以根據(jù)TCP四次揮手來(lái)分析。

實(shí)際執(zhí)行

如果沒(méi)有Golang環(huán)境的朋友可以直接下載編譯好的可執(zhí)行文件,下載地址:https://github.com/cw1997/NATBypass/releases

我們先來(lái)看看代碼編譯之后實(shí)際運(yùn)行,上圖左邊為虛擬機(jī)跑的內(nèi)網(wǎng)服務(wù)器,他已經(jīng)設(shè)置了入站規(guī)則,通過(guò)直接連接192.168.2.112:3389是無(wú)法連上遠(yuǎn)程桌面的。

此時(shí)此刻右圖開(kāi)始通過(guò)listen命令監(jiān)聽(tīng)7777和9999端口。

接著內(nèi)網(wǎng)服務(wù)器再通過(guò)slave命令開(kāi)始雙向連接黑客的

大家可以根據(jù)netstat -an的結(jié)果以及控制臺(tái)日志輸出來(lái)綜合理解這個(gè)過(guò)程。

寫(xiě)在最后

這個(gè)工具現(xiàn)在實(shí)現(xiàn)的仍然只是簡(jiǎn)單的透明傳輸,并且存在諸多問(wèn)題。比如說(shuō)本地主動(dòng)連接內(nèi)網(wǎng)服務(wù)是一開(kāi)始就預(yù)連接好的,這樣會(huì)導(dǎo)致一些服務(wù)如果在連上之后長(zhǎng)期沒(méi)有數(shù)據(jù)傳輸,會(huì)主動(dòng)斷掉連接,導(dǎo)致公網(wǎng)端偶爾出現(xiàn)無(wú)法連接上,要重新斷開(kāi)重連后才能連上的小BUG,具體在HTTP服務(wù)器要多刷新幾次頁(yè)面,遠(yuǎn)程桌面則可能要連接上然后又取消,然后再連才能連上。而且在并發(fā)連接上處理還有一些細(xì)節(jié)沒(méi)有做好。并且目前還僅僅支持TCP連接的轉(zhuǎn)發(fā)等等,當(dāng)然要實(shí)現(xiàn)UDP的轉(zhuǎn)發(fā)也不是很困難稍加改進(jìn)即可。大家也可以點(diǎn)個(gè)star,提個(gè)pull request一起來(lái)改進(jìn)這些問(wèn)題。目前相關(guān)的開(kāi)源項(xiàng)目也有做的比較成熟的,比如說(shuō)Golang寫(xiě)的ngork,大家也可以參考參考。

當(dāng)前文章:內(nèi)網(wǎng)穿透工具的原理與開(kāi)發(fā)實(shí)戰(zhàn)
當(dāng)前網(wǎng)址:http://www.muchs.cn/news27/104327.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供自適應(yīng)網(wǎng)站、網(wǎng)站制作、企業(yè)建站、商城網(wǎng)站、Google電子商務(wù)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

營(yíng)銷型網(wǎng)站建設(shè)