Linux 做 DNAT 無法順利傳資料, 因為MSS的問題(ADSL遇上一般內網)

No Comments

以下這篇只適用於 , 內往外走
http://ppc52776.blogspot.tw/2011/04/mss-linux-pppoe-nat.html

有用 Linux 當作家裡 ADSL 分享器/防火牆 的人應該會發現
有些網頁透過 NAT 後就是無法開啟
但是如果直接在 Linux 主機上卻又可以正常開啟
解決方法:
在 Linux Firewall 上增加以下 rule:
iptables -A FORWARD -p tcp –tcp-flags SYN,RST SYN -j TCPMSS –clamp-mss-to-pmtu

搞定

為什麼呢?

這主要原因是因為 ppp 網路的 MTU 問題
MTU 的功能在於指定最大可傳輸的單一封包大小
當使用 ADSL(PPP) 時
會再封包裡另外增加 PPP 的 Header 導致單一封包會超過上限
為了解決此問題
一般會把 PPP 的 MTU 設定為原本 Ethernet MTU – 8 也就是 1492

TCP 傳輸方式有自動切割與組合封包的特性
MTU 的值就會被拿來當作 TCP 預設切割的大小(MSS)
MSS = Maximum Segment Size
每次建立 TCP 連線時
雙方會於 handshaking 時互相告知對方允許的 MSS 最後以小的為主
但 NAT 後的 PC 看到的是自己的 MTU 也就是 1500 而非 1492
因此會給對方過大的 MSS 建議
正常來說~當路由器收到大於自己可處理最大封包時
會透過 ICMP 回應給 sender
sender 接下來就會嘗試較小的 MSS
但大多數 ISP 會擋掉 ICMP 導致 sender 傻傻一直等待直到 timeout…

參考資料:
How to Setup a Linux Firewall with PPPoE/NAT/iptables
您或許對這些文章有興趣:
解決CI網頁圖片路徑問題
linux 中使用 pptp client 連線到windows vpn server 包含 mppe-128 支援
用 ip 指令設定特定的 routing rule

Leave a Reply

Share via
Copy link