Linux IPsec ゲートウェイでの TCP MSS クランプ:何を直すのか
小さなリクエストは通り、大きな応答は止まる。内部 TCP 経路の MSS ルールが正しい対処か、どこに置くべきかを確認します。
Ping は通り、SSH も通り、小さなページは読み込めるのに、そのあと大きな応答はどれもタイムアウトまで止まったままになる。古典的なパターンが示すのは到達性ではなくパケットサイズで、経路はハンドシェイクと最初の数キロバイトを運び、そのあとフルサイズのセグメントが消える。Linux IPsec ゲートウェイでは TCP MSS ルールが解決策になることが多いが、それが何を変え、触れるパケットが実際どこにあるのかを理解している場合に限る。以下の順序は症状からルールの配置までパケットを追うので、説明が合わなくなった時点で読むのをやめればよい。
MSS を示唆する症状
TCP はハンドシェイクで最大セグメントサイズを交渉する。その値がカプセル化後に経路が運べる量より大きいと、送信側は届かないセグメントを作り続け、接続は最初の往復のあとで止まる。小さな応答は収まり、大きな応答は収まらない。
ICMP のフィードバックは経路 MTU 探索を通じて接続を救えるが、そのメッセージを落とすファイアウォールは停止を静かなブラックホールに変えてしまう。だから同じトンネルが一方のアプリケーションでは動き、他方では設定に目立った違いもないまま失敗する。
TCPMSS ルールがすること、しないこと
このルールは通過する TCP ハンドシェイクパケットの MSS オプションを書き換える。トンネルインターフェースの MTU を設定するわけでも、IPsec ポリシーを変えるわけでもなく、現在のカーネルではすでに小さい値を大きくするのではなく、広告された値に上限をかけるだけだ。しかも触れるのは TCP だけで、UDP のペイロード、DNS の挙動、交渉されたトラフィックセレクタはその範囲外にある。
変更はハンドシェイク中に起きるので、ルールより前に確立した既存の接続は古い値のまま残る。新しい接続で試し、変更後の最初の試行こそが何かを教えてくれると期待しよう。ルールのどこも、すでに開いている接続には届かない。だからインシデントの最中に当てた修正は、何もしていないように見えることがある。
ルールは内部 TCP 経路に置く
ポリシーベースの Linux ゲートウェイでは、転送されるパケットはファイアウォールから見ると今も普通の TCP に見える。IPsec ポリシーはそのパケットが保護されると決めるが、ファイアウォールは内部フローの ESP ヘッダーを見ないので、ここで ESP に一致させようとするとまったく別のパケットを指すことになる。このずれが、正しそうに見えて決して一致しないルールを生む。
iptables の言葉で言えば、ルールは転送経路の mangle テーブルに属し、ハンドシェイクパケットに限定される:iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1270。この数値は一例であって普遍的な定数ではなく、カプセル化のオーバーヘッドと経路の実際の MTU から導くこと。nftables の同等物は forward または postrouting チェーンで最大セグメントサイズを設定する。
IKE と ESP の外側の待ち受けルールは、内側の転送ルールとは分けておく。アプリケーションのフローと外側のプロトコルの両方を許可しようとする一つのルールは、結局どちらとも確実に一致しない。
ファイアウォールの所有者と NAT の順序を尊重する
UFW がホストのファイアウォールを管理しているなら、次のリロードで消えるコマンドを打つのではなく、対応している永続設定を通して mangle と転送の変更を加える。誤ったテーブルや終端ルールの後ろに挿入したルールは効果がなく、稼働中のテーブルはそのことを隠してしまう。
送信元変換は別の判断であり、しばしばこの判断と絡み合う。一般的な masquerade ルールの前に置いた除外は、保護されたトラフィックがポリシーの求める送信元を失うのを防ぐが、サイズの問題を直すわけではなく、サイズのルールが変換の問題を直すわけでもない。
狭く検証して、そこで止める
失敗しているサービスへ新しい接続を開き、アプリケーションとルールのカウンターの両方を見る。停止が消えれば、そのカプセル化でのその TCP 経路についての証拠は得られる。すべての VPN プロトコルに合うとか、すべての UDP アプリケーションが直ったとか、特定の上流サービスが元の原因だったという証拠は得られない。
ポリシーが許す範囲で ICMP のサイズフィードバックを働かせたままにし、外側の IPsec 経路が内側のルートで表されていないときは、ルート MTU に基づく自動クランプを慎重に扱う。結論が狭いほど、次のインシデントは診断しやすい。