1. 程式人生 > >內網通過外網IP訪問內網伺服器?

內網通過外網IP訪問內網伺服器?


如圖,這個圖是本貼的初始圖,大圈是本地路由器,和他相連的是isp路由器,和isp相連的是internet上隨便一個路由器。

本地出口地址是5。5。5。1,isp對端是5。5。5。2(掩碼沒寫,稍後會分別討論)。 1。1。1。1和1。1。1。2是內網兩臺伺服器的內網地址,被靜態對映到公網上的5。5。5。4和5。5。5。5。 內網的pc全部被pat到出口上。本地路由器一條預設路由到isp對端。

我想這個拓撲應該是非常普遍的了,我認為就是因為這個非常普遍的拓撲,造成了很多人所反應的“內網不能通過公網地址訪問內網伺服器”這個問題。我認為這個問題的關鍵原因就在於掩碼,就是在3層上做文章。

第一節

先來看看一般情況下,這個環境的掩碼的規劃。假設isp分配一段8地址子網給本地,這樣isp路由器介面和本地路由器介面共佔用2個,網路地址、廣播地址共佔用2個,可用的一共4個,掩碼是248。對於圖示的拓撲,假設本地路由器出口掩碼是248(內網pc的pat地址相應的也就是掩碼為248),被對映的兩個地址掩碼也是248,這個最普遍的掩碼規劃,結果是:伺服器、內網pc的pat地址、本地出口地址全部處於同一個網段。我們分析一個包的來龍去脈,來看看到底內網pc通過公網地址可否訪問到內網伺服器。

假設內網一臺pc1。1。1。111發出ping 5。5。5。4(伺服器的公網地址)請求,包源地址1。1。1。111,目的地址5。5。5。4,路由器收到這個包後,檢查路由表,發現5。5。5。4就位於自己的出口網段(假設出口為以太口),所以直接通過arp廣播請求5。5。5。4的mac地址,問題出現了,誰會應答這個請求呢?沒有人,所以,這種情況下(所有公網地址在同網段)當然不會通。不但內網訪問伺服器不行,伺服器之間通過公網地址訪問也不會通。

結論一:只要出口地址和伺服器對映的公網地址在同網段,就有問題。

第二節

基於上面的討論,我們知道了只要出口地址和伺服器對映的公網地址在同網段,就會發生“無人應答”的必然結果,所以我們這次改變掩碼規劃,將出口掩碼變長,變為252(isp掩碼也要相應改變)。在這裡首先宣告一個要點,就是nat池的地址可以和出口不在同網段,以前有帖子也討論過,我自己一開始也迷惑,後來想明白了,只要isp路由器上有這些地址的路由就可以,下一條是本地路由器,這樣本地路由器便可以接受到這些包。

我們再次分析一個包的流程。內網pc1。1。1。111發出ping 5。5。5。4請求,包源地址1。1。1。111,目的地址5。5。5。4,路由器收到這個包後,檢查路由表,這一次,發現5。5。5。4不在本地的任何介面,所以走了預設路由,將包發給了isp對埠,並在本地nat表中生成一條專案,記錄內網地址1。1。1。111被轉換成公網地址5。5。5。1加上埠號(假設埠號是8888),isp接受到的包,目的地址是5。5。5。4,源地址變成了5。5。5。1,它檢查它的路由表,發現5。5。5。4路由下一條是5。5。5。1,也就是本地路由器,所以又將此包發給本地路由器,經過了一次往返後,本地收到這個包,首先接受nat引擎的過慮,發現5。5。5。4正在被靜態對映到內網的1。1。1。1的主機,所以改變目的地址為1。1。1。1,源地址還是5。5。5。1,這樣就交給了路由引擎,檢視路由表,1。1。1。1的路由當然有了,通過2層直接發給1。1。1。1,至此,去程的包分析完畢。

我們再分析回程的包。伺服器1。1。1。1收到包後,準備迴應給5。5。5。1(加埠號),發出reply包,源地址1。1。1。1,目的地址5。5。5。1:8888,本地路由器收到後,先給路由引擎,發現5。5。5。1就是出口地址,問題又來了,包的目的就是出口,而不是經過出口,這時候路由器該怎麼辦呢?假如是從外向內來的包訪問5。5。5。1:8888,這時候會先提交個nat引擎,做nat轉換。但是這是從內向外發出的包,要先提交給路由引擎,我認為此時,由於收到的包是從內向外的,目的直接就是針對出口來的,而出口並沒有開啟什麼埠,除非為了web管理,或者telnet管理開啟80或23埠,所以路由器會丟棄,因為沒有得到應答。

結論二:只要出口地址和內網pc的pat地址同網段,同樣會有問題

第三節


我們再變更掩碼方案,使得內網pc的pat地址和伺服器對映地址同網段,但和出口不同網段。假設內網pc的pat地址為5。5。5。6(和伺服器地址同網段)

我們再次分析一個包,內網pc1。1。1。111發出ping 5。5。5。4請求,包源地址1。1。1。111,目的地址5。5。5。4,路由器收到這個包後,檢查路由表,發現5。5。5。4不在本地的任何介面,所以走了預設路由,將包發給了isp對埠,並在本地nat表中生成一條專案,記錄內網地址1。1。1。111被轉換成公網地址5。5。5。6加上埠號,isp接受到的包,目的地址是5。5。5。4,源地址變成了5。5。5。6,它檢查它的路由表,發現5。5。5。4路由下一條是5。5。5。1,也就是本地路由器,所以又將此包發給本地路由器,經過了一次往返後,本地收到這個包,首先接受nat引擎的過慮,發現5。5。5。4正在被靜態對映到內網的1。1。1。1的主機,所以改變目的地址為1。1。1。1,源地址還是5。5。5。6,這樣就交給了路由引擎,檢視路由表,1。1。1。1的路由當然有了,通過2層直接發給1。1。1。1,至此,去程的包分析完畢。

我們再分析回程的包。伺服器1。1。1。1收到包後,準備迴應給5。5。5。6(加埠號),發出reply包,源地址1。1。1。1,目的地址5。5。5。6,本地路由器收到後,先給路由引擎,發現5。5。5。6不在本地任何埠下,所以走了預設路由,發給isp,並在nat表中生成一條記錄,將1。1。1。1轉換為5。5。5。4,isp接受到包源地址變為5。5。5。4,目的地址是5。5。5。6,通過檢查路由表,發現5。5。5。6這個地址的路由下一條應該是5。5。5。1,也就是本地路由器,所以包又被髮回來了,經過一次往返,本地收到了這個包,首先提交給nat引擎,發現目的地址5。5。5。6在nat表中對應著內網pc1。1。1。111,所以將5。5。5。6替換成1。1。1。111,源地址不變,還是5。5。5。4,然後提交給路由引擎,路由器在2層將包發給1。1。1。111,這時,1。1。1。111這臺主機收到了從5。5。5。4返回的包,而他一開始ping請求包,就是發給5。5。5。4這個公網地址
的,所以ping通了!!!!


結論三:內網pc的pat地址和伺服器公網地址同網段,同時和出口地址不同網段,這樣沒有問題。


第四節


本貼的高潮部分已經達到,至此,只剩下一種情況,就是內網pat地址、伺服器公網地址、出口地址全部不在同網段。假設出口掩碼252,伺服器公網地址段掩碼248,內網pc的pat地址改為5。5。5。254,這樣三種地址都不在同網段。而且isp也必須有伺服器公網地址和內網pc的pat地址的路由,下一條是5。5。5。1我們再次分析一個包,內網pc1。1。1。111發出ping 5。5。5。4請求,包源地址1。1。1。111,目的地址5。5。5。4,路由器收到這個包後,檢查路由表,發現5。5。5。4不在本地的任何介面,所以走了預設路由,將包發給了isp對埠,並在本地nat表中生成一條專案,記錄內網地址1。1。1。111被轉換成公網地址5。5。5。254加上埠號,isp接受到的包,目的地址是5。5。5。4,源地址變成了5。5。5。254,它檢查它的路由表,發現5。5。5。4路由下一條是5。5。5。1,也就是本地路由器,所以又將此包發給本地路由器,經過了一次往返後,本地收到這個包,首先接受nat引擎的過慮,發現5。5。5。4正在被靜態對映到內網的1。1。1。1的主機,所以改變目的地址為1。1。1。1,源地址還是5。5。5。254,這樣就交給了路由引擎,檢視路由表,1。1。1。1的路由當然有了,通過2層直接發給1。1。1。1,至此,去程的包分析完畢。

我們再分析回程的包。伺服器1。1。1。1收到包後,準備迴應給5。5。5。254(加埠號),發出reply包,源地址1。1。1。1,目的地址5。5。5。254,本地路由器收到後,先給路由引擎,發現5。5。5。254不在本地任何埠下,所以走了預設路由,發給isp,並在nat表中生成一條記錄,將1。1。1。1轉換為5。5。5。4,isp接受到包源地址變為5。5。5。4,目的地址是5。5。5。254,通過檢查路由表,發現5。5。5。254這個地址的路
由下一條應該是5。5。5。1,也就是本地路由器,所以包又被髮回來了,經過一次往返,本地收到了這個包,首先提交給nat引擎,發現目的地址5。5。5。254:某個埠,在nat表中對應著內網pc1。1。1。111,所以將5。5。5。254替換成1。1。1。111,源地址不變,還是5。5。5。4,然後提交給路由引擎,路由器在2層將包發給1。1。1。111,這時,1。1。1。111這臺主機收到了從5。5。5。4返回的包,而他一開始ping請求包,就是發給5。5。5。4這個公網地址的,所以ping通了!!!!



結論四:三種地址全部不在同網段,沒有問題。


綜上所述,得到了4個結論:

結論一:只要出口地址和伺服器對映的公網地址在同網段,就有問題。
結論二:只要出口地址和內網pc的pat地址同網段,同樣會有問題。
結論三:內網pc的pat地址和伺服器公網地址同網段,同時和出口地址不同網段,這樣沒有問題。
結論四:三種地址全部不在同網段,沒有問題。

可以簡單的發現,前兩個是充分條件,只要滿足了其中一個,就會出現問題,而現在大多數的接入都符合前兩個情況,而幾乎沒有人“多此一舉”的去改變掩碼規劃,所以造成如此多的普遍現象:內網不能用公網地址訪問內網伺服器!!!!!

出口地址只要不和其他兩種地址同網段,就可以保證不出問題。

至此,已經探討了問題的原因。此過程中我還得到了一個推論和一個待驗證的問題。

推論:如果nat池中的公網地址和出口地址不同網段,不管在內網還是公網ping nat池中未參與轉換的公網地址,會出現環路,包在本地和isp之間來回往返。


待驗證的問題:
對於第三節和第四節,如果只在本地出口變長掩碼,isp端不作任何改變,會怎麼樣?以第三節的環境來說:我們再次分析一個包,內網pc1。1。1。111發出ping 5。5。5。4請求,包源地址1。1。1。111,目的地址5。5。5。4,路由器收到這個包後,檢查路由表,發現5。5。5。4不在本地的任何介面,所以走了預設路由,將包發給了isp對埠,並在本地nat表中生成一條專案,記錄內網地址1。1。1。111被轉換成公網地址5。5。5。6加上埠號,isp接受到的包,目的地址是5。5。5。4,源地址變成了5。5。5。6,它檢查它的路由表,由於此時isp的介面掩碼沒有變長,還是248,所以,它發現5。5。5。4路由就在它自己的介面上,所以直接在介面發arp請求5。5。5。4的mac地址,此時,按理說,沒人會應答(除非本地開了代理arp),但是有一次偶爾發現在路由器上show arp,會發現有些奇怪的條目,ip地址都是nat池中的地址,mac地址不管ip多少,都是本地出口的mac地址,這樣的話,即使arp請求的地址不和出口同段,一樣會得到應答,不知道這個對不對。


對這個問題的解決方法,在ios層面,一般是利用修改dns回包中的payload實現的,將dns返回的公網地址,修改成內網地址,這樣直接通過內網通訊,就不會有問題了。對於直接用公網ip訪問的包,會在路由器內部先nat,然後調頭,不走出口,直接再回到內網,以支援用公網地址訪問。

寫了這麼多,不知道各位有沒有耐心看完,不管怎麼樣,請大家多發表評論,謝謝!

該貼已經同步到 狐海劍的微博
hi大家好,今天我們來討論一個很多人都找不到答案得問題:究竟為什麼內網不能用公網地址訪問內網伺服器。不是任何裝置都存在此問題,拿cisco的裝置來說,不同版本的ios,有的就沒有這個問題,而有的版本就有問題,netscreen的防火牆也沒有這個問題,關鍵是開發者有沒有意識到這個問題,通過修改ios,完全可以避免。對於這個問題,解決方法是有,比如內網dns欺騙、pix上得alias等等,但是究竟為什麼有些裝置不支援呢?今天我斗膽發個貼,因為有些結論純粹靠想,也沒有裝置進行試驗,所以希望大家跟貼討論,達到拋磚引玉的目的,謝謝了先!