pptp搭建的***代理上網很慢 終於解決

問題:用pptp搭建了linux平臺的***服務器,撥入後訪問內網ftp,下載文件極慢;用其作網關上網,除了baidu外,大部分網站訪問速度極慢,幾乎無法訪問。 解決: 在pptp所在的linux服務的iptables的*filter表中加入 -I FORWARD -p tcp --syn -i ppp+ -j TCPMSS --set-mss 1356 /sbin/iptables -I FORWARD -p tcp --syn -i ppp+ -j TCPMSS --set-mss 1356 原因分析
=====在斷開***鏈接的情況下:
在windowsXP下用ping -f -l XXXXXX 192.168.0.1一步一步測試(XXXXXXX爲MTU大小,可以從1500開始,逐漸減小,知道可以ping通)
我們可以得到可以ping通的MTU最大爲1426;
=====在連接***的前提下
在windowsXP下用ping -f -l XXXXXX 192.168.0.1一步一步測試(XXXXXXX爲MTU大小,可以從1500開始,逐漸減小,知道可以ping通)
我們可以得到可以ping通的MTU最大爲1372; 超過這個數則不能通,
====撥通***,在服務器上用netstat –i查看接口,得到
Iface   MTU Met    RX-OK RX-ERR RX-DRP RX-OVR    TX-OK TX-ERR TX-DRP TX-OVR Flg
eth0   1500   0 102528561      0      0      0 194391413      0      0      0 BRU
eth1   1500   0 519820535    954 11553    924 208798037      0      0      0 BRU
lo    16436   0   151062      0      0      0   151062      0      0      0 LRU
ppp0   1396   0       19      0      0      0        8      0      0      0 OPRU 可知ppp的最大mtu爲1396,當然,對應的mss應爲(mtu-20字節的IP頭部+20字節的TCP 頭部=)1356 【小知識1】計算機網絡中的MSS:
MSS: Maximum Segment Size 最大分段大小
MSS最大傳輸大小的縮寫,是TCP協議裏面的一個概念。
MSS就是TCP數據包每次能夠傳輸的最大數據分段。爲了達到最佳的傳輸效能,TCP協議在建立連接的時候通常要協商雙方的MSS值,這個值TCP協議在 實現的時候往往用MTU值代替(需要減去IP數據包包頭的大小20Bytes和TCP數據段的包頭20Bytes)所以往往MSS爲1460。通訊雙方會 根據雙方提供的MSS值得最小值確定爲這次連接的最大MSS值。
【小知識2】mtu是網絡傳輸最大報文包。
mss是網絡傳輸數據最大值。
mss加包頭數據就等於mtu.
簡單說拿TCP包做例子。
報文傳輸1400字節的數據的話,那麼mss就是1400,再加上20字節IP包頭,20字節tcp包頭,那麼mtu就是1400+20+20.
當然傳輸的時候其他的協議還要加些包頭在前面,總之mtu就是總的最後發出去的報文大小。mss就是你需要發出去的數據大小。 【小知識3】http://www.cnpaf.net/Class/TCPANDIP/200511/9898.html 假設PC建立了到SERVER的HTTP連接,PC希望從SERVER下載一個大的網頁。SERVER接收到PC的請求後開始發送大網頁文件,其IP的 DF位置1,不允許分片,IP報文長度爲1500字節。到達***網關2的外網口(以太)後,***網關2發現其長度超過了1500個字節,於是將其丟 棄,並給SERVER發回一個目的地址不可達的ICMP信息,同時指出“MTU of next hop: 1500”。PC接收到該消息後,又按照1500字節對外發送,又被丟棄,於是就形成了循環,無法通訊。
根據上述的分析,很容易得到如下解決方式,在***網關2的出接口設置MTU爲1500-4-20=1476,這樣***網關2返回ICMP不可達消息時 將給出”MTU of next hop: 1476”。SERVER將以1476作爲自己的最大MTU對外發送,到達***網關1,封裝GRE和外層IP頭後就不會超過1500而順利發到對端。 -I FORWARD -p tcp --syn -i ppp+ -j TCPMSS --set-mss 1356 因爲mss是在TCP連接建立開始時,通過帶有syn標誌的IP數據包進行傳輸的,所以我們在iptables裏面規定,在轉發數據時,只要發現產生於 ppt*的帶有 syn標誌數據包時,將其mss設定爲1356字節,這樣就與ppp0接口的路徑MTU向匹配了,數據自然就可以暢通無阻啦。 (注,***撥入一個,則建立一個ppt*的虛擬設備,這個可以再linux上用ifcpnfig看到,第一個爲ppt1,第二個爲ppt2……)
參考: 1、http://fanqiang.chinaunix.net/app/other/2005-09-13/3655.shtml 2、http://technet.microsoft.com/zh-cn/library/cc768084(en-us).aspx 3、這是一個比較複雜的問題。首先,發現問題的過程是這樣的:使用一臺WinXP的電腦(簡稱主機A)連接公司的***成功後,訪問內網的一個基於 B/S的CRM系統(簡稱主機B)時,發現首頁可以顯示(頁面比較簡單,包含的數據量較小),輸入賬號密碼登陸後,發現只能顯示頁面頂部的一點點內容,而 下面大部分內容無法顯示。而換一臺Win2000的電腦登陸,內容就可以完全顯示出來。登陸到Linux ***主機上,利用tcpdump對數據傳輸過程進行抓包分析,發現:每當B向A傳輸大於1396字節的數據時,***主機就會反饋B如下信息 10.87.0.200:***主機的內網網卡的IP地址
10.87.200.1:主機A的IP地址
10.87.200.6:主機B通過***獲取的IP地址
21:54:21.953848 IP 10.87.0.200 > 10.100.0.100: icmp 556: 10.100.0.203 unreachable -
need to frag (mtu 1396)
可以看到***主機向提供web服務的主機B返回了一個ICMP不可達的差錯報文。其含義是***主機收到了一個需要分片才能通過的數據包,而這個數據包在其IP頭部又設置了不能分片(DF)的標誌。所以該數據包不能通過***主機。
根據TCP/IP協議,在建立TCP連接時,傳輸雙方都要指明自己的mss(最大報文長度)大小,然後選取雙方之中最小的那個mss,以避免在隨後的數據 傳送過程中出現數據包分片傳輸的情況。通過抓包分析,主機B的mss爲1460字節,主機A的mss爲1357字節。兩者取小所以雙方協商的結果確定 mss爲1357字節,也就是說以後進行TCP數據傳輸時,數據包的最大傳輸單元MTU不能超過1397(mss+20字節的IP頭部+20字節的TCP 頭部),同時在IP頭部設置了不能分片(DF)的標誌。
然後在***主機上執行netstat –i,觀察各個網絡接口的路徑MTU值爲多少。觀察結果如下:
Iface MTU
eth0 1500 //外網網卡接口
eth1 1500 //內網網卡接口
lo 16436 //本機迴環接口
ppp0 1396 //WinXP ***接入通道接口
可以看到ppp0接口的路徑MTU爲1396字節,也就是說如果一個數據包想要通過這個接口的話,一定不能大於1396字節,如果大於這個值,會出現兩種結果:
1、如果這個數據包的IP頭部沒有設置不能分片(DF)的標誌,那麼***主機就把這個數據包分片,使其數據包大小小於1396字節,然後允許其通過。
2、反之,如果這個數據包的IP頭部設置不能分片(DF)的標誌,那麼***主機就會返回一個ICMP不可達的差錯報文。同時丟棄這個數據包。
問題就出在這裏,主機A和主機B協商的mss爲1357字節,也就是說其TCP數據包的MTU爲1397,而ppp0允許的路徑MTU卻爲1396,主機 A的MTU居然大於ppp0的路徑MTU!當主機B向主機A發送了一個1397字節的數據包時,自然不能通過ppp0接口了。回到發現問題的那個情況,首 頁之所以能夠顯示成功,是因爲首頁包含的數據較小,傳輸時只需要一個沒有超過1396字節的IP數據包就可以了,所以能夠顯示出來,而登陸成功後的頁面包 含的數據較大,需要分爲多個IP數據包進行傳輸。這裏可以假設一下,開頭的一個IP數據包因爲沒有超過1396字節因而通過,而隨後的IP數據包因爲其大 小爲1397字節,超過了路徑MTU,所以不予通過。反映到頁面,就是登陸頁面下面的大部分內容無法顯示了。
我們再來看看用安裝了Win2000主機C連接***又是什麼狀況呢?通過抓包發現,主機C提出的mss爲1360(可以推算出其MTU爲1400),而 執行netstat –i,發現此時的ppp0的MTU爲1496,路徑MTU大於主機C的MTU,這個結果是正常的。
大家一定會問,何主機B提出的MTU小於路徑MTU,這個問題只能問問微軟了,我查了一些英文資料,說這是WinXP本身系統的一個問題。
知道了問題的原理,那讓我們來看看如何進行解決吧。解決方法很簡單,就是藉助iptalbes,設定主機B進行協商時提出的mss爲1356。即在 iptables裏面加入一條規則: iptables -A FORWARD -p tcp --syn -s 10.87.200.0/31 -j TCPMSS --set-mss 1356   因爲mss是在TCP連接建立開始時,通過帶有syn標誌的IP數據包進行傳輸的,所以我們在iptables裏面規定,在轉發數據時,只要發現帶有 syn標誌並且源地址爲主機B的IP數據包時,將其mss設定爲1356字節,這樣就與ppp0接口的路徑MTU向匹配了,數據自然就可以暢通無阻啦。 因爲mss是在TCP連接建立開始時,通過帶有syn標誌的IP數據包進行傳輸的,所以我們在iptables裏面規定,在轉發數據時,只要發現帶有 syn標誌並且源地址爲主機B的IP數據包時,將其mss設定爲1356字節,這樣就與ppp0接口的路徑MTU向匹配了,數據自然就可以暢通無阻啦
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章