小さいリクエストは通り、大きい応答は止まる
一言でいうと
curlでヘッダーは来るのに、本文で止まるなら、十中八九、MTUブラックホールです。接続できることと、大きなパケットが通ることは、別の問題です。
なぜ必要なのか
このような症状は、人をとても長く引き留めます。
curl -I(ヘッダーだけ) → すぐに成功curl(全体) → 数秒止まってからタイムアウト- 小さなAPI応答は正常で、一覧の取得だけが失敗
- VPNをオンにすると再現し、オフにすると再現しない
「接続はできるのに」なので、ファイアウォールを疑わず、「ときどきできるから」と、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は危険だ」として、ファイアウォールですべてブロックします。すると、次のようになります。
- 大きなパケットが、小さなMTUの区間に到達します。
- ルーターがパケットを破棄して、ICMPを送ります。
- ICMPがファイアウォールでブロックされます。
- 送信者は何の知らせも受け取れず、同じサイズで再送し続けます。
- 永遠に失敗します。エラーメッセージもありません。
これがPMTUDブラックホールです。小さなパケット(ハンドシェイク、ヘッダーのリクエスト)は通り、大きなパケット(本文)だけが消えるので、症状がそれほど紛らわしいのです。
診断: 特権なしで確認する方法
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に流れたり、その逆になったりします。
現場での姿
- VPN接続者だけファイルのダウンロードが止まる → トンネルMTU + ICMPのブロック。
- クラウド移行後に、特定のAPIだけがタイムアウト → オーバーレイネットワークのMTU減少。
- コンテナでだけ再現 → CNIのMTU設定がホストと違う。
続くクイズで確認すること
小さなリクエストだけが成功する現象が、なぜMTUブラックホールを指すのか、ss -tinの再送の増加を、他の正常な指標と区別できるかを確認します。