需求分析
微信公眾號的開發過程中,微信伺服器和專案的後端會相互傳送資訊。如果需要測試,就必須保證專案可以被公網訪問,但大多數情況下家庭網路都是經過了運營商層層 NAT 之後的網路,並沒有公網IP,此時就需要使用內網穿透來解決“公網訪問”的問題。
實現內網穿透後,就可以在微信的公眾號頁面設定 URL 到自己的專案上了。
“為什麼我的電腦不能被公網訪問到?”
早期的網際網路的總裝置量還沒有那麼多,運營商確實會給每個使用者都分配一個公網 IP,大家都在公網上其樂融融。
但隨著裝置增加,IPV4的地址池即將耗盡,運營商不得不減少 IP 地址的使用來讓網際網路容納更多的裝置,NAT 技術實現了節省 IP 地址的目的。
NAT
NAT 全稱“網路地址轉換”,它允許區域網內的一系列裝置使用同一個公網地址傳送資料,而路由器會記錄下轉換的過程,並在收到公網的返回之後根據之前的記錄轉發給內網。
具體的轉換過程是:內網地址+埠 <--> 外網地址+埠,如圖:
① 當位於區域網192.168.1.100的電腦1想訪問公網伺服器39.100.100.100的 Web 埠8080時,由於它不知道伺服器的具體位置,所以向它的閘道器(路由器)所在的192.168.1.1傳送請求(Request)(這個請求會隨機從一個空閒的高位埠發出,如27777)。
② 路由器一側連線公網(WAN),一側連線內網(LAN),當路由器收到請求(Request)後,由於路由器知道伺服器的位置,所以會把資料轉發出去,但內網資料包不允許在公網上轉發,於是資料會被轉化成源地址是公網的地址的資料包,也就是把請求頭變成路由器的公網地址122.122.122.122,並且隨機使用一個空閒的高位埠,如60000。
③與此同時,路由器會記錄下內網到外網的轉換關係,也就是 192.168.1.100:27777<---->122.122.122.122:60000,如果後面伺服器向60000埠返回資料,路由器就知道這個資料應該返回給電腦1所在的192.168.1.100。在電腦1和伺服器的連線斷開之前,這條對映規則不會失效。
④ 伺服器收到資料包後,它只知道傳送人是位於122.122.122.122的路由器,並不知道真正的傳送者,所以返回(Response )資料也會傳送到路由器的公網地址122.122.122.122
⑤路由器收到伺服器的 Response 後,透過檢視NAT 表知道,這個資料應該返回給電腦1,所以把 Response 傳送到192.168.1.100
這樣就完成了一次請求和返回,當連線斷開一段時間後,NAT 表的記錄失效。
但 NAT 的原理就決定了它有一個問題:公網無法主動向內網發起請求,這就導致了家裡的電腦無法做伺服器。
如圖:
① 如果公網電腦主動向路由器發起請求(Request)
② 路由器查詢 NAT 表之後發現並沒有記錄,因此不知道轉發給哪一臺內網機器,資料被丟棄。
看到這裡讀者可能會想,既然能透過 NAT 表完成臨時的埠對埠的對映,並且來自公網的 Response 可以轉發回來,那麼有沒有一種方法,能實現一種“長久的”埠對映,這樣公網伺服器是不是可以透過特定的埠來主動連線內網伺服器呢?
確實是可以的,而這種方式叫做埠轉發,用一個固定的“埠轉發表”來記錄永久的轉發規則
埠轉發
如圖:
①在路由器中設定好規則:將公網的60000埠對映到內網電腦1的8080埠
②伺服器向路由器發起請求時,傳送到122.122.122.122的60000埠
③路由器透過埠轉發表,知道了該把資料傳送到192.168.1.100的8080埠
④路由器把資料發給電腦1
經過這麼一通操作,我們可以理解成,埠轉發把電腦1的8080埠變成了“公網上的埠”
DMZ
還有一種特殊的埠轉發叫做 DMZ,它可以理解為“所有埠都轉發”,也就是隻要有來自公網的請求,全部都轉發給電腦1
那麼為什麼我用了埠轉發還是不能被公網訪問到呢?
上文的例子是一個理想情況,它的前提在於:路由器是自己家裡安裝的,並且運營商給路由器分配的地址是公網地址,換言之,只經過了路由器這一層 NAT
但實際的情況是,在家庭寬頻連線到路由器之前,運營商就已經進行了好幾層 NAT 了,也就是說,或許一個小區透過 NAT 共用了一個 IP 地址,再換句話說,到達我家的網路,已經是一個內網地址了。如圖:
所以這種情況再使用埠轉發就沒有意義了,我們可以突破家裡路由器的 NAT,但無法突破運營商的 NAT。
除非我們能控制運營商的路由器,在他們的路由器上,一層一層的設定轉發規則,直到最外層的路由器,但這並不可能。
所以就有了內網穿透的方法
內網穿透的原理
內網穿透需要藉助一臺在公網上的電腦(這臺電腦的作用就是轉發資料,我們稱為跳板機),本質上是使用內網電腦連線到跳板機,建立長連線(長連線的作用是保證 NAT 表一直有效),並完成埠的一一對映,當其他裝置需要訪問內網電腦時,只需要訪問到我們的跳板機,由跳板機轉發到內網機器,如圖:
①內網電腦啟動內網穿透,主動連線到位於公網180.2.2.2的跳板機
②連線過程中,途徑的各級路由器都會產生 NAT規則,並且由於即將形成長連線,這個 NAT 規則不會失效
③內網電腦和跳板機握手後形成了長連線,也就是一直抓住不斷開,此時雙方都可以隨意向對方傳送資料,
此時我們可以設定一份規則,只要有人向跳板機的8080傳送資料,跳板機就向內網機器的8000埠傳送資料
④如果有其他電腦想訪問內網機器,只需要連線180.2.2.2的8080埠
⑤跳板機沿著隧道把請求轉發到內網上
⑥內網機器處理完之後,會把返回的資料傳送到跳板機上
⑦跳板機會把資料返回給發起請求的電腦
這樣就實現了從公網主動向內網發起請求。
總結
什麼是內網穿透:在公網上部署一個負責轉發的跳板機,與內網主機進行長連線,當其他裝置訪問跳板機時,跳板機將資料轉發到內網主機,實現內網穿透
為什麼使用內網穿透:① IP 地址池有限 ② NAT 技術使得外網無法主動向內網發起請求 ③埠轉發不適用於多層 NAT 的情況
多看看上文的幾張圖片,可以有更好的理解。