キルスイッチが作動したとき、開いている TCP セッションはどうなる?
ブロックされたパケットは切断された接続ではありません。セッションが途切れを乗り越えるべきかを決め、ブロックと復旧を別々の性質として検証します。
トンネルが落ち、キルスイッチが作動し、四分の三まで進んでいたダウンロードがフリーズするか、すぐに失敗する。この二つの結果は保護の度合いの違いではなく、適用の選択の違いから生じます。破棄されたパケットは接続を待たせたままにし、拒否されたパケットは接続を閉じてアプリケーションに通知します。どちらの挙動を望むかは設計の問いであり、それを検証するのは別の作業です。
破棄・拒否・リセットは別物
トラフィックを破棄するファイアウォール規則はパケットを捨てて何も返さないため、送信側は独自のタイマーで再送を続けます。TCP リセットで拒否する規則は接続を即座に閉じ、アプリケーションにはエラーが見えます。ほとんどのキルスイッチは、拒否がポリシーを明かしてしまい、破棄が死んだネットワークの振る舞いに似ているため、破棄を選びます。
ブロックはソケットを閉じることと同じではありません。アプリケーションは確立状態のディスクリプタを保持したままで、欠けているのはパケットだけです。そのため、OS が接続は存在すると主張する間、ページは何分もスピナーの上に留まれます。アプリケーションのメッセージから推測するのではなく、どちらの挙動もネットワークが落ちたように見えるので、文書化された適用ポリシーを読んでください。
途切れている間、アプリケーションは何をするか
TCP は遅延を増やしながら再送し、Linux の既定の再試行予算は数秒ではなく十五分ほどで尽きます。それまではソケットは役に立つほど開いてもおらず、閉じてもいません。独自の keepalive やリクエストのタイムアウトを持つアプリケーションは早めに諦めることが多く、同じマシン上の二つのプログラムが一つの障害の間に違う振る舞いをするのはそのためです。
トンネルが戻っても、ローカルのソケットは変わらないままですが、経路は変わり得ます。新しい公開元アドレスはサーバー側で別の四つ組を生むため、向こう側のステートフルなファイアウォールはもうセッションと一致しません。クライアントがエラーを見ていなくても、接続は死んでいます。
復旧が必要かどうかを決める
二つの契約から選びます。短い途切れをセッションが乗り越えるには安定したアドレッシングと状態を保つサーバーが必要で、アプリケーションがきれいに再接続するには繰り返しても安全な再試行ロジックが必要です。その中間は、サーバーがすでに記録したものを再送するクライアントか、誰にも見えないセッションの成功を報告するクライアントという最悪の結果を生みます。
安定したアドレッシングは忘れられがちな部分です——別の公開アドレスに着地する再接続は、クライアントのソケットが健全に見えてもサーバー側の状態を無効にするからです。すべてが一致することはめったにないので、二つの契約のどちらが各アプリケーションに当てはまるかを書き留めてください。
ブロックと復旧を別々に確認する
漏えい防止とセッションの生存は二つの性質として扱ってください。片方を満たしてももう片方については何も言えず、生き残ったセッションは直接トラフィックがブロックされた証拠ではなく、死んだセッションはすべての直接経路がブロックされた証拠でもありません。
ss -tnp state established '( dport = :443 )'
sudo conntrack -L -p tcp --dport 443
sudo tcpdump -ni any 'tcp port 443 and tcp[tcpflags] & tcp-syn != 0'
復旧を観察するときは無害なテスト操作を使い、二重送信がインシデントにならないようにしてください。実際に見た障害の形——アプリケーションが何を表示したか、ソケットが生き残ったか、それが自力でいつ回復したか——を記録します。
期待する挙動を適用規則の隣に書き、日付を添えてください。その規則を次に変える人は、展開がどちらの契約を約束したのかを知る必要があります。