はじめに
Turbonomicで、SecureClientにプロキシサーバーを使う要件として、以下があります。
この辺りのイメージが湧かないので、整理します。
TLS over TCP
TLS passthrough
SNI(Server Name Indication)サポート
参考:
https://www.ibm.com/docs/en/tarm/8.20.2?topic=client-configuring-proxy-server-secure
IBM Turbonomic | SecureClient構築手順例
1. TLS over TCP
TLS over TCP要件の
通信が純粋なTLS(HTTPS)トラフィックである必要があります。プロキシはそのまま中継するだけで、通信内容を解釈・変更してはいけません。
とは、TCPポート443を流れるTLS(HTTPS)通信を、Proxyが復号・解析・変更せず、そのまま中継できることを指します。
クライアント ──TCP接続──▶ サーバー
──TLSハンドシェイク──▶
──暗号化データ──▶
- TCP は単なるバイトストリーム(0,1,0,1,1,1,...)の転送層
-
TLS はその上で動く「暗号化レイヤー」
プロキシ自体がTCP, TLS, HTTPSと対応していてHTTP通信が変えられないこと。
TLSハンドシェイク
TLS over TCP を理解するうえで、ハンドシェイクの各ステップを把握しておくことが重要。
クライアント サーバー
│ │
│──① ClientHello ──────────────────▶│
│ (TLSバージョン, 暗号スイート, │
│ SNI, 乱数 など ※平文) │
│ │
│◀─② ServerHello ──────────────────│
│ (選択した暗号スイート, 乱数) │
│ │
│◀─③ Certificate ──────────────────│
│ (サーバー証明書 ※平文) │
│ │
│◀─④ ServerHelloDone ──────────────│
│ │
│──⑤ ClientKeyExchange ────────────▶│
│ (プリマスターシークレット) │
│ │
│──⑥ ChangeCipherSpec ─────────────▶│
│──⑦ Finished (暗号化開始) ─────────▶│
│ │
│◀─⑧ ChangeCipherSpec ─────────────│
│◀─⑨ Finished (暗号化開始) ─────────│
│ │
│══ ⑩ 暗号化されたアプリケーションデータ ══│
⑦で、鍵交換がされたら暗号化される。
2. TLS Passthrough とは
プロキシが TLS を「終端」するかどうか。プロキシを終端としないことで、複合、再暗号化が行われないのでE2Eで同じデータが保たれる。
【TLS 終端あり(通常のリバースプロキシ)】
クライアント ──TLS──▶ プロキシ ──TLS(別)──▶ バックエンド
↑
ここで一度復号・再暗号化
プロキシが中身を見られる
【TLS Passthrough(パススルー)】
クライアント ──TLS──▶ プロキシ ──TLS(同じ)──▶ バックエンド
↑
バイトをそのまま転送
プロキシは中身を見られない
3. SNI(Server Name Indication)とは
TLSハンドシェイクの中に、SNI(server name)を入れることで、TLSを複合しなくてもバイトを解析することで、サーバー名を特定できて「どのドメインに接続したいか」がわかる。
生バイト列(-msg オプション)の結果:
>>> TLS 1.3 Handshake [length 0131], ClientHello
01 00 01 2d 03 03 46 ee ed 3a ea 8c 15 cb 7d 8f
...
TLSハンドシェイク(ClientHello)の中身:
┌─────────────────────────────────────────┐
│ TLS Version: 1.3 │
│ Random bytes: ... │
│ Extensions: │
│ server_name: "api.turbonomic.com" ◀── SNI(平文!)
│ supported_groups: ... │
└─────────────────────────────────────────┘
バイト列の中に server-a.local という文字列が平文で埋まっています。プロキシは TLS を復号しなくても、この先頭バイトを解析するだけで SNI を取り出せます。
TLS Passthrough プロキシにとっての SNI の意味:
- プロキシはTLSを復号できないが、ClientHelloのSNIは平文で読める
- SNIを見るだけで「どのバックエンドへ転送するか」がわかる
- → 復号なしにルーティングできる!
おわりに
まとめると、
プロキシが SNI を読んで接続先(バックエンド)を特定したい。
でも TLS を復号したら E2E 暗号化が壊れる。
だから「復号せずに SNI だけ読める」TLS Passthrough が必要。
その前提として通信が純粋な HTTPS(TLS over TCP)である必要がある。
という理解ができました。