ログインは成功し、ポータルのフロントページは描画されるのに、そのあとダッシュボードのウィジェットやレポートが waiting for host のまま止まり、やがてブラウザが諦めます。公開サイトはその間ずっと普通に読み込まれ、資格情報も何も変わっていません。小さい応答は届くのに大きい応答が止まるのは、アクセス規則ではなくパケットサイズの上限の兆候です。プロファイルのほかを編集する前に、この読みを確かめてください。

サイズの問題とポリシーの問題を切り分ける

まず拒否の可能性を排除します。ゲートウェイに拒否されていれば、ページが半分読み込まれるのではなく接続が即座に失敗したはずです。トンネルが立ち上がり、より大きな転送でだけ止まるということは、外側の経路が内側のパケットを運べないという合図です。

仕組みはカプセル化です。内側のパケットはそれぞれトンネルのヘッダーを得るため、物理リンクに収まっていたペイロードが収まらない外側のパケットになり、do-not-fragment ビットを持つものは、ブラウザが解釈できる応答なしに捨てられます。

do-not-fragment プローブで上限を測る

推測するのではなく上限を測ります。断片化を拒否するプローブを送り、応答が返るまでペイロードを段階的に下げます。まずは次のようなコマンドから始めます: ping -M do -s 1472 host。DF を設定しているのに断片化が必要だと訴える応答は、値がまだ大きすぎるという意味です。1462 で、次に 1452 で繰り返し、応答が返る最初のサイズで止めます。番号は、試したホストと一緒に記録してください。なぜなら その答えはその経路に属し、プロトコル全般に属するものではないからです。

トンネルが実際にトラフィックを送るアドレスを調べます。ゲートウェイの公開名に対する外側のプローブと、内部サーバーに対する内側のプローブは別のホップを測るので、どちらかでの ICMP フィルタリングが健全な経路を壊れて見せることがあります。

値をトンネルデバイスに適用する

結果は Wi-Fi アダプターではなく、クライアントが作ったインターフェースに適用します。Linux クライアントなら ip link set dev tun0 mtu 1300 に続けて ip link show tun0 を実行し、値が反映されたことを確かめます。デバイス名は実装やトンネルの組み方で変わるので、クライアントが報告する名前を使ってください。

トンネルの MTU を下げると、各パケットが運ぶペイロードが小さくなるため、全体のスループットは少し落ちます。それが、大きい応答をブラックホールに捨てないための代償です。小さい数値が自動的に安全なわけではありません。代わりに物理アダプターを変えると、そのリンク上のすべての接続に被害が広がる一方、大きすぎる内側のパケットは大きすぎるままです。

まずクライアント自身の MTU 要求を使う

呼び出しを自分で制御しているなら、クライアントにあとからパッチを当てるのではなく、サイズを要求させられます。 --mtu はサーバーにトンネルの MTU を要求し、 --base-mtu は下位の経路の MTU を宣言して、ゲートウェイがトンネルの数値を導けるようにします。どちらも要求であり、クライアントの マニュアル はゲートウェイがそれに従うことを約束していません。

この違いが作業の順序を決めます。まず要求を試して、それが作るインターフェースを確認し、ゲートウェイが選んだ値でまだ止まるならデバイスをローカルに設定する方法へ戻ります。

失敗した転送で検証し、そのうえで永続化する

ローカルの ip link の変更は、クライアントがトンネルを作り直すまでしか持ちません。それは次の再接続やレジュームで起こります。値を接続が始まる場所に置いてください。クライアントを起動してからデバイスを調整するラッパー、ExecStartPost ステップを持つ systemd ユニット、あるいはゲートウェイが受け入れる場合のクライアントオプションです。プロファイルの隣にバージョン管理で置き、次の人が数値の理由を見られるようにします。

フロントページではなく、失敗した要求で試します。レポートを開く、添付を取得する、止まったリポジトリ取得を実行する、のいずれかを行い、まだ止まるなら正確にどこで止まるかを記録します。変更後に描画されるページはほとんど何も証明しません。変更前も描画されていたからです。

同じ転送が同じ地点で止まるなら、MTU の理論は証明されていません。トンネル上でトラフィックを取得し、数値を再び変える前にどちら側が送信をやめるかを確認し、ロールバックがひとつのコマンドで済むよう前の値を記録しておきます。

関連記事