VPN の説明に TLS という語を見つけて、Web プロキシならこのトラフィックを理解できると結論づけるのはよくある近道です。このプロトコルの内側では、ピア同士が自分たちのパケットを交換し、TLS はその交換のなかの一つのチャネルの一部として動作します。利用者にとって重要なペイロードは別のメッセージ形式で流れるため、両者が通常の HTTPS セッションと一致することはありません。

まず外側の封筒がある

すべてのトンネルパケットは、プロトコル自身のヘッダーから始まります。メッセージ種別、鍵識別子、そしてバイトストリーム輸送ではパケットの終わりを示す長さの接頭辞です。この封筒を解析しない読み手は、次のフィールドがどこから始まるのか分かりません。

outer transport (UDP datagram or TCP stream)
  -> OpenVPN header (opcode, key id, length where needed)
    -> control message (reliability wrapper, TLS exchange)
    -> data message (protected inner packet)

この図はバイト表ではなく地図です。正確なフィールドはメッセージ種別によって変わるからです。ただし先頭のオクテットは常にオペコードと鍵識別子をまとめて格納します。ポート番号からメッセージ種別を推測すると、デコーダーは見えているものを誤って名付けることになります。診断で重要なのは順序です。輸送、次にプロトコルの封筒、次に二種類の作業のどちらかです。その後に何が続くかを判断する前に、封筒を読んでください。間違った位置から始めるデコーダーは、自信満々の無意味な結果を生みます。

信頼性の層はプロトコルに属する

制御メッセージには順序どおりの確認済み配送が必要で、プロトコルは確認応答と再送によってそれを自前で提供します。確認応答は単独のメッセージとして届くことも、別の制御メッセージと一緒に運ばれることもあり、きれいな一往復を期待する人にはトレースが不規則に見えます。

利点は、外側の輸送が UDP であっても TLS ハンドシェイクが信頼できる搬送路を得られることです。代償は、一つのデータグラムがその会話の一部しか含まないことがあり、単独の TLS レコードとして扱うと無意味になることです。再組み立てはプロトコル層で行う必要があります。だからこそ、捕捉したパケットが完全なハンドシェイク手順に見えることはめったにありません。

外側の輸送を TCP に切り替えても、この層はなくなりません。信頼できる輸送とはプロトコル層での再送が減るという意味であり、フレーミングが消えるとか、トラフィックが HTTP になるという意味ではありません。

データパケットは別の形式を使う

セッションができると、有用なペイロードは内部 IP パケットや Ethernet フレームを運ぶデータメッセージとして届きます。それらは独自の鍵と独自の処理で保護され、TLS ライブラリが受け入れるいかなる意味でも TLS アプリケーションレコードではありません。

この分離は設定に表れます。制御チャネルとデータチャネルは別々の暗号設定を持ち、片方を名指すログ行はもう片方について何も語りません。強い制御暗号を強いデータ暗号の証拠として読むのは、よくある報告の誤りです。

関連する誤解も説明から外しておいてください。TLS は対称データチャネルの隣に座る公開鍵チャネルではありません。鍵が確立された後、TLS 自身がそのレコードを対称的に保護するからです。本当の違いは役割とパケット形式であり、どちらの側がどの種類の暗号を使うかではありません。

HTTPS プロキシが役に立たない理由

TLS を終端するプロキシは、TLS レコードのストリームと、その内側のアプリケーションプロトコルを期待します。 このプロトコルの制御チャネルは独自のフレーミングの内側に、周囲に信頼性の層を伴って運ばれるため、終端するプロキシはそのフレーミングを壊れた入力として読みます。

バイトやデータグラムを解釈せずに通過させる透過的なフォワーダーは、ストリームを書き換えたり再組み立てしたりしない限り機能します。中間装置について尋ねるべき問いは、実際の輸送とフレーミングを転送するかどうかであり、どこかで TLS に対応しているかどうかではありません。プロキシ規則に一晩を費やす前に、それを尋ねてください。ここでの失敗の多くは設定漏れではなく設計上のものです。

トレースを正しく読む

まず制御の交換があり、その後にはるかに多くのデータメッセージが続き、両方が一つの輸送を共有すると予想してください。制御段階が完了してデータ段階が止まるなら、障害はハンドシェイクではなく、鍵、経路、またはデータ経路のフィルタリングに関係します。データメッセージをいくつか捕捉し、そもそもクライアントを出ているかを確認してください。その一つの観察が探索を半分に分けます。

鍵方式に関する歴史的な説明は、プロトコルのドキュメント において、あるリリースが今もすべての古い形式に対応していることを意味しません。物事が以前どう動いていたかを述べた段落に期待を築く前に、実行しているバージョンを確認してください。

関連記事