TT Lab
はじめる
学ぶ 学習パス コース

Linuxネットワーク診断

小さいリクエストは通り、大きい応答は止まる

TT Labで続きを見る

一言でいうと

curlでヘッダーは来るのに、本文で止まるなら、十中八九、MTUブラックホールです。接続できることと、大きなパケットが通ることは、別の問題です。

なぜ必要なのか

このような症状は、人をとても長く引き留めます。

「接続はできるのに」なので、ファイアウォールを疑わず、「ときどきできるから」と、DNSでもないと判断します。原因は、経路のどこかで大きなパケットが黙って捨てられることです。

MTUとPMTUD

MTU(Maximum Transmission Unit)は、一度に送れるパケットの最大サイズです。イーサネットは、通常1500バイトです。

問題は、経路の途中に、より小さいMTUを持つ区間があるときです。

클라이언트(1500) → 라우터 → VPN 터널(1400) → 서버(1500)

TCPは、接続するときに、お互いに「自分は1460バイトまで受け取れる(MSS)」と知らせます。しかし、これは両端の事情であって、途中の区間の事情ではありません。

正常なら、次のように動作します。1500バイトのパケットが1400の区間に到達すると、そのルーターがICMPのFragmentation Neededメッセージを送って、「大きすぎる、1400に縮めろ」と知らせてくれます。送信者がサイズを縮めて、もう一度送ります。この過程をPath MTU Discoveryといいます。

ブラックホールは、ICMPをブロックしたときに生まれる

多くの組織が、「ICMPは危険だ」として、ファイアウォールですべてブロックします。すると、次のようになります。

  1. 大きなパケットが、小さなMTUの区間に到達します。
  2. ルーターがパケットを破棄して、ICMPを送ります。
  3. ICMPがファイアウォールでブロックされます。
  4. 送信者は何の知らせも受け取れず、同じサイズで再送し続けます。
  5. 永遠に失敗します。エラーメッセージもありません。

これがPMTUDブラックホールです。小さなパケット(ハンドシェイク、ヘッダーのリクエスト)は通り、大きなパケット(本文)だけが消えるので、症状がそれほど紛らわしいのです。

両端のリンクは1500バイトなのに、途中のVPNトンネルだけが1400バイトです。小さなリクエストは狭い区間をそのまま通過しますが、1500バイトのパケットは入口で黙って捨てられ、そのことを知らせるICMP fragmentation neededは、ファイアウォールがブロックします。送信者は何の知らせも受け取れず、同じサイズで再送を繰り返すだけです

診断: 特権なしで確認する方法

ping -M do -sでサイズを変えながら測るのが教科書的な方法ですが、pingはNET_RAW capabilityが必要で、ロックされた環境では使えません。幸い、別の道があります。

1. 経路とMTUを確認する

ip route get 8.8.8.8
# 8.8.8.8 via 10.0.0.1 dev eth0 src 10.0.0.5
ip -o link show          # 각 인터페이스의 mtu 값
cat /sys/class/net/eth0/mtu

2. 応答サイズを変えながら再現する

curl -s -o /dev/null -w '%{size_download} %{time_total}\n' \
  'https://api.example.com/items?limit=1'
curl -s -o /dev/null -w '%{size_download} %{time_total}\n' \
  'https://api.example.com/items?limit=1000'

小さな応答だけが成功するなら、強いシグナルです。

3. ヘッダーと本文を分けて見る

curl -I https://target/            # 헤더만 → 성공?
curl --max-time 5 https://target/  # 전체 → 멈춤?

4. ソケットの状態を見る

ss -tin dst 10.0.3.20
# ... mss:1460 ... retrans:0/14 ...

retransがずっと増え続けていれば、同じパケットを繰り返し送っているという意味です。MTUブラックホールの典型的な指紋です。

対応

対応 方法 備考
ICMPを許可 ファイアウォールで、type 3 code 4だけでも開ける 根本的な解決
インターフェースMTUの引き下げ ip link set eth0 mtu 1400 特権が必要
MSSクランピング ルーター/ファイアウォールで、MSSを経路に合わせる よくある現場の解決策
アプリケーションの応答の縮小 ページネーション 回避策にすぎない

現場で最もよく使われるのは、MSSクランピングです。ゲートウェイがTCPハンドシェイクのMSS値を、経路MTUに合わせて下げてくれれば、そもそも大きなパケットが作られません。

ルーティングもあわせて見る

MTUではない場合もあります。ip route getが予想と違うインターフェースを指していれば、経路そのものが問題です。

ip route get 10.0.5.10
# dev eth1 이 나온다면 — eth0 로 갈 줄 알았는데 아니었다
ip rule show           # 정책 라우팅이 있는가
ip route show table all

VPNをオンにすると、デフォルトルートがまるごと変わることがよくあり、そのとき、社内ネットワークへ向かうべきトラフィックがVPNに流れたり、その逆になったりします。

現場での姿

続くクイズで確認すること

小さなリクエストだけが成功する現象が、なぜMTUブラックホールを指すのか、ss -tinの再送の増加を、他の正常な指標と区別できるかを確認します。