一直都是用 rp-pppoe 讓 linux 撥號當路由器,但最近用起來怪怪的,剛好看到 NetworkManager 也可以做撥號,就換過去試看看
只要有裝 NetworkManager-ppp 就可以直接從 nmcli 設定,如以下範例:
nmcli conn add type pppoe ifname ppp0 con-name {connection-name} autoconnect yes pppoe.parent eno1 pppoe.username {username} pppoe.password {password} nmcli conn up {connection-name}
值得注意的是,網路上都會教 ifname 用網路卡的代號,但這樣做會導致撥號後 LAN 會斷線,所以這邊用 ppp0 當作連線裝置
到這邊都沒什麼問題,等我開始用個兩天之後,就發現特定網站,連線會整個卡住,最後就 timeout
稍微 google 一下看起來是 mtu 的問題,裝了 wireshark 來看,確實有很多封包是 TCP Out of Order
所以我試著把內網的電腦網卡 mtu 調低看看,果然馬上就好了
造成的原因不難理解,就是 Ethernet 和 PPPoE 最大能乘載的資料量不同,TCP 在建立連線時提供的 MSS(max segment size) 要和底層相應,不然資料會對不上
只是原本 rp-pppoe 似乎有處理這個情況,而 NetworkManager 就沒有
知道原因之後,查到解決的方法是用 iptables 在 TCP SYN 封包轉送的時候修改 MSS 成該路徑對應的大小
firewalld 的設定檔寫起來會是這樣:
<rule ipv="ipv4" table="mangle" chain="POSTROUTING" priority="0">-o ppp0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu</rule>
那個 clamp-mss-to-pmtu 會自動偵測路徑上的 mtu 作調整,很方便
如果要手動寫的話,也可以用 --set-mss 1452 這樣的寫法
改完後測試之前不能上的網站,全部都沒問題了
留言