<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>NAT | Chia-An Lee</title><link>https://calee0219.github.io/tag/nat/</link><atom:link href="https://calee0219.github.io/tag/nat/index.xml" rel="self" type="application/rss+xml"/><description>NAT</description><generator>HugoBlox Kit (https://hugoblox.com)</generator><language>en-us</language><copyright>©</copyright><lastBuildDate>Thu, 08 Sep 2022 08:46:29 +0800</lastBuildDate><image><url>https://calee0219.github.io/media/icon_hu_da05098ef60dc2e7.png</url><title>NAT</title><link>https://calee0219.github.io/tag/nat/</link></image><item><title>PPPoE Line 無法連線問題</title><link>https://calee0219.github.io/blog/network_tcp_mss/</link><pubDate>Thu, 08 Sep 2022 08:46:29 +0800</pubDate><guid>https://calee0219.github.io/blog/network_tcp_mss/</guid><description>&lt;p&gt;由於曾經想把家中的 NAT gateway 全部放到 Linux server 上，做包含
、NAT、與 DHCP 的工作，同時可以自由地記憶 mac address、下 firewall 規則、架設 web proxy server 等，不需要再過小烏龜與它家 NAT 打 port forwarding，因此著手了建置。&lt;/p&gt;
&lt;p&gt;在完成 PPPoE 建置後，詐用之下並沒有什麼太大的問題，然而偶有新建立連線時速度較慢的問題。一開始我並不太在意，然而當家人反映 Line 在 wifi 下無法正常傳送訊息，只有在 LTE 網路下才可以時，便發現好像真的是我的網路架設有問題。&lt;/p&gt;
&lt;p&gt;在確認 LINE 的網頁也觸及不到後，便方便確定可以直接用 LINE 網站當 debug target。在觀察問題時發現如果使用 Linux 軟撥接，封包會止步於東京的 Router (使用 traceroute 或 mtr 測試)，但如果使用小烏龜硬撥接在過東京之後也沒有回復，但 LINE 網頁是可以 access 的，因此懷疑 LINE server 只是沒有開 ICMP response。&lt;/p&gt;
&lt;p&gt;接著試著用 tcpdump 把封包抓出來檢查，比較軟撥接與硬撥接封包差異，看起來似乎只差在軟撥接封包 MTU 為 1492，為了增加 8 byte 的 PPPoE header，而硬撥接莫名的可以放 1500 (也許上面的機器 MTU 有開超過 1500)，理論上 MTU 只有過大才會有問題，太小應該只會有效能問題而已。&lt;/p&gt;
&lt;p&gt;而後繼續細看 TCP 的封包內容，看起來硬撥接時可以做完完整的 handshark，可是軟撥接時只能做到 server hello，所以代表其實封包是有送到 LINE 的 server 上，只是在三方交握時莫名的被拒絕，而又觀察 header 內容，會發現 server hello 的 sequence number 會出錯，除錯到此懷疑要馬是 MTU 的問題，要馬就是 TCP 的問題，然而就是想不出到底 root cause 在哪。&lt;/p&gt;
&lt;p&gt;在走投無路下，嘗試詢問在 AWS 工作的大神學弟，結果學弟一比較之下馬上跟我講原因。原來是 TCP MSS 的問題，在 TCP header 裡面會有一個 MSS (maxiumu segment size) 用來告知兩端該放多少 size 的 payload。在連線到一般的 server 時由於兩方都沒有要交換的 MSS，因此照著 MTU 的大小放多可以正常工作，可是當其中一端有要求 MSS (像是 LINE server) 可是另外一端沒有時，就會以 MSS 的大小放置 payload，而常見的 MSS 是 1460 (1500 (MTU) - 40 (IP/TCP header))，然後懷疑由於 LINE 沒有開 ICMP 功能因此無法透過 Path MTU Discovery (PMTUD)，又有手動塞 MSS 1460，然而 client 又不會跟其溝通，因此永遠用大於可接受的封包大小傳送資料。&lt;/p&gt;
&lt;p&gt;解決方法是要嘗試讓 server 知道 MSS 要變小，並且我需要在 gateway (NAT server) 上設定，而不是在 client 上一台一台設。Linux 上常見做法有兩種，一種做法是在防火牆上下規定 TCPMSS: &lt;code&gt;iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN- j TCPMSS --set-mss 1452&lt;/code&gt; (1452 = 1500 - 8 PPPoE header - 40 IP/TCP header)，然而我的防火牆是用 firewalld 設定，不管寫 iptables 或寫 firewalld 例外規定都感覺很彆扭，因此用第二種作法在 route 上面設定 advmss: &lt;code&gt;ip route add default dev ethX mtu 1492 advmss 1452&lt;/code&gt;，後來發現如果改用 network-scripts 設定 PPPoE 可以直接有 &lt;code&gt;CLAMPMSS=1452&lt;/code&gt;，所以就改用 network-scripts 的設定方式了。BTW 我看網路上很多人都把 CLAMPMSS 設定成 1412，不過好像是 PPPoE 有不同種長度的 header (?)。&lt;/p&gt;
&lt;h2 id="reference"&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>