小さな TCP 接続は成功するのに、大きな接続は失敗するのはなぜですか?

小さな TCP 接続は成功するのに、大きな接続は失敗するのはなぜですか?

Linux システムでは、次のような奇妙な動作が時々見られます。

ping は実行でき、場合によってはいくつかのサービスも使用できますが、ネットワークの状態は非常に悪いです。

たとえば、今私はラップトップ ( -j MASQUERADE) 経由で接続をルーティングし、次のことを観察しています。TCP 接続をほとんど行わない場合 (サーバーからデータがほとんど送信されない場合)、次のように処理されます。

# nc 86.57.151.3 80
GET /404
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>

/proc/net/ip_conntrack には、tcp 6 431998 ESTABLISHED src=192.168.99.9 dst=86.57.151.3 sport=49104 dport=80 src=86.57.151.3 dst=93.125.21.218 sport= 80 dport=49104 [ASSURED] mark=0 use=2「GET /404」と入力する前にあります。

しかし、大きな接続を行う場合:

root@localhost:~# nc 86.57.151.3 80
GET /

停止します。「GET /」を入力する前は通常どおり ESTABLISHED ASSURED と表示されますが、Return キーを押すと になりますtcp 6 0 CLOSE_WAIT src=192.168.99.9 dst=86.57.151.3 sport=56991 dport=80 src=86.57.151.3 dst=93.125.21.218 sport=80 dpo rt=56991 [ASSURED] mark=0 use=2。 のパケットは受信されません。最後に Ctrl+C キーを押すと、FIN がサーバーに送信され、Wireshard はサーバーの FIN が「順序が間違っている」と警告します。まるで、応答パックがどこかにドロップされたかのようです。

同じことをルーターから実行するとnc 86.57.151.3 80GET /動作します。

何が間違っているのかデバッグするにはどうすればいいですか?

答え1

これは、MTU とフィルタリングされた ICMP メッセージのどこかに問題があるためです。

回避策としては、クライアント デバイスで MTU を設定するか、ルーターで TCP MSS クランプを使用します。

iptables -t mangle -A FORWARD -o ppp4 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

関連情報