2021-03-05 分類: 網站建設
在我國,由于網民眾多,運營商無法保證為每一個寬帶用戶提供全球唯一的公網IPv4地址。因此很多用戶會發現通過路由器端查看到的WAN端IP與百度“IP”關鍵詞所得到的IP不一致,并且前者的IP為一個私有IP。
而還有一些情況下,公網IP比較昂貴,企業雖然本身也持有少量的獨立的公網IP,但是由于成本限制無法為企業內每一臺
首先通過判斷傳入參數決定當前使用何種轉發策略。
然后再判斷傳入參數是否正確,通過正則表達式等方式驗證IP的合法性以及端口范圍。
通過port2port函數實現了兩個端口同時監聽雙向并且轉發數據。
在port2host操作中實現了跳板中轉。
在host2host中實現了主動連接打通隧道的功能。
看代碼便可以知道,在Golang中進行socket操作的net包要比C語言中的socket.h操作簡單很多。
轉發功能的核心就在于forward函數部分。
先輸出一個日志說明是對哪兩個連接進行雙向轉發,然后通過sync包下的WaitGroup實現一個條件阻塞功能,防止在Goroutine還未執行完,主線程就已經退出了。
然后發射兩個Goroutine,分別處理連接1到連接2的IO數據包拷貝以及連接2到連接1的IO數據包拷貝。因為要保證兩個端口間的通信是全雙工的,也就是兩邊同時都要能夠互相交換數據,所以要用Goroutine來實現這兩個操作的并發。
而IO數據包的拷貝核心代碼在connCopy函數中,根據是否要記錄流量日志判斷是否要使用io.MultiWriter這個多路寫數據流的函數。
如果打開日志文件的文件流成功,則通過io.MultiWriter函數生成一個多路寫入流,這里這個多路寫入流的變量名為w,任何寫入到w這個寫入流的數據都會同時寫入先前參與執行多路寫入流創建函數io.MultiWriter的參數中,在這里參數為conn1和logFile,即為端口1和日志文件流。
接著調用io.Copy將第二參數的讀取流中讀取到的數據源源不斷地拷貝到第一個參數的寫入流中。
這里要注意io.Copy函數是同步阻塞的,意味著只要連接沒有斷開,那么程序執行流將一直卡在這個函數。如果拷貝出錯,那么io.Copy函數就會返回,也就是執行他下面的代碼。拷貝出錯意味著可能連接已斷開,那么先把寫入流的連接斷掉。
這里要重點注意,為什么是斷開寫入流而不是讀寫流全部斷開呢。因為我們前面發射了兩個Goroutine,如果盲目全部斷開,將會導致另一個Goroutine中可能還有未寫完的數據丟失。具體可以根據TCP四次揮手來分析。
實際執行
如果沒有Golang環境的朋友可以直接下載編譯好的可執行文件,下載地址:https://github.com/cw1997/NATBypass/releases
我們先來看看代碼編譯之后實際運行,上圖左邊為虛擬機跑的內網服務器,他已經設置了入站規則,通過直接連接192.168.2.112:3389是無法連上遠程桌面的。
此時此刻右圖開始通過listen命令監聽7777和9999端口。
接著內網服務器再通過slave命令開始雙向連接黑客的
大家可以根據netstat -an的結果以及控制臺日志輸出來綜合理解這個過程。
寫在最后
這個工具現在實現的仍然只是簡單的透明傳輸,并且存在諸多問題。比如說本地主動連接內網服務是一開始就預連接好的,這樣會導致一些服務如果在連上之后長期沒有數據傳輸,會主動斷掉連接,導致公網端偶爾出現無法連接上,要重新斷開重連后才能連上的小BUG,具體在HTTP服務器要多刷新幾次頁面,遠程桌面則可能要連接上然后又取消,然后再連才能連上。而且在并發連接上處理還有一些細節沒有做好。并且目前還僅僅支持TCP連接的轉發等等,當然要實現UDP的轉發也不是很困難稍加改進即可。大家也可以點個star,提個pull request一起來改進這些問題。目前相關的開源項目也有做的比較成熟的,比如說Golang寫的ngork,大家也可以參考參考。
當前文章:內網穿透工具的原理與開發實戰
當前網址:http://m.newbst.com/news27/104327.html
成都網站建設公司_創新互聯,為您提供自適應網站、網站制作、企業建站、商城網站、Google、電子商務
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯
猜你還喜歡下面的內容