PPPoE 在 iptables 中 TCPMSS 設定問題

PPPoE 在 iptables 中 TCPMSS 設定問題

前言

前一陣子, 想要拿我的 CubieBoard 來當做家裡的firewall, 於是安裝了Debian 7, 並使用pppoe 來連接中華電信的Router, 並且寫了一些iptables 的rules 來當作firewall 及NAT router.
但是總是覺得有問題, 有時連不出去. 現象是這樣的:

這台Cubieboard 連線都很ok, 但是在NAT 後面的電腦, 只要碰上https 的連線, 有時就連不上, 但是用http 就ok, ftp 也ok.

這問題擺了很久都沒去理會. 今天終於有空好好的來追問題的源頭. 發現好像是跟pppoe 有關.
上網查了一下資料, 也順便學習了許多相關知識, 終於解決了問題.

MTU

MTU (Maximum Transmission Unit) 是指網路介面卡上最大傳輸單元, 其單位為bytes. 在大多數的Ehternet 上, 這個值通常是1500. 因為如此, 在PPPoE 中, 因為還有header問題, 所以這個值就得設的比較小, 通常為1492 (= 1500 – 2(PPP)- 6(PPPoE))

MSS

MSS (Maximum segment size) 是TCP protocol 中的一個參數, 是指TCP 每次資料傳輸分段的最大值. 當TCP 在handshake 時, 雙方host 會查看MSS 這個欄位, 來決定雙方資料傳輸分段的大小. 在Ethernet 中MSS 值最大為1460 bytes.
原因是在Ethernet 中 MTU = IP Header + TCP Header + MSS + FCS.
(FCS 是指Frame check sequence, 通常採用CRC演算法, 在Ethernet 中, 它佔4 bytes.)
但是在PPPoE 中MTU 為1492, 所以其MSS 只能設為1452.

問題所在

當Debian 在開機後, 啟動了ppp0, 其內定將MTU 設為1492, 並且會自動設定一條iptable rule, 查看/etc/ppp/ip-up.d/0clampmss 得知如下:

# cat /etc/ppp/ip-up.d/0clampmss 
#!/bin/sh
# Enable MSS clamping (autogenerated by pppoeconf)

iptables -t mangle -o "$PPP_IFACE" --insert FORWARD 1 -p tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1400:65495 -j TCPMSS --clamp-mss-to-pmtu

因為在NAT 後面的電腦, 並不知道前端的router 是用什麼介面連到internet, 所以它和遠端的電腦建立TCP 連線時, 有可能會將MSS 設為1460. 但是由於firewall 或router 端使用PPPoE連線, 若MSS 大於1452會造成資料爆掉, 所以上述的iptable rule 強制偷改其MSS值(在IPV4下 = PMTU – 40, 在IPV6下 = PMTU – 60). 因此MSS 就會被改成1452, 這樣子就不會爆掉了.

但是我自己寫的iptable rule script 中, 一開始就用了下列設定, 清除了原來的所有設定

# 清除所有規則
iptables -F -t filter
iptables -X -t filter
iptables -Z -t filter
iptables -F -t mangle
iptables -X -t mangle
iptables -Z -t mangle
iptables -F -t nat
iptables -X -t nat
iptables -Z -t nat

造成/etc/ppp/ip-up.d/0clampmss 的設定也被清除掉了, 然後NAT 後面的電腦就常常無法連線.

解決方式

既然知道原因, 解法就很簡單, 就是在我自己的iptable rule 中再加上

iptables -t mangle -o ppp0 --insert FORWARD 1 -p tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1400:65495 -j TCPMSS --clamp-mss-to-pmtu

就搞定了!!


參考資料

  1. 最大傳輸單元
  2. Maximum segment size
  3. Can’t connect to certain HTTPS sites
  4. Installing Debian from the start a PPPoE enabled system
  5. pppoeconf not setting correct MTU
  6. 修改 MSS 解決 Linux PPPOE NAT 後部份網頁無法瀏覽問題
  7. How to Setup a Linux Firewall with PPPoE/NAT/iptables
  8. IP over IP tunnels & MTU problems
  9. 小議TCP的MSS(最大分段)以及MTU
  10. TCP中的MSS解读
  11. MTU原理及相關問題分析
This entry was posted in 架站 and tagged , , , , . Bookmark the permalink.

4 Responses to PPPoE 在 iptables 中 TCPMSS 設定問題

  1. Ten says:

    您好,請問您有試過用CB4官方版的Ubuntu IMG做PPPoE的共用嗎? 我使用PPPoE可以撥號成功,但是CB4自己跟周圍的電腦都無法連到Internet。請問有什麼方法可以解決?
    以下是官方下載點:
    桌面版:
    http://dl.cubieboard.org/model/cc-a80/Image/ubuntu-linaro/
    server版:
    http://dl.cubieboard.org/model/cc-a80/Image/ubuntu-linaro-server/

發佈回覆給「Ten」的留言 取消回覆

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *