Webship ブログに戻る

Webship エンジニアリング

TLS 終端またはパススルー?適切な Webship リバースプロキシ境界の選択

TLS 終端によりルーティング、キャッシュ、HTTP セキュリティ検査が可能になります。パススルーでは、プレーンテキストとセッションキーがオリジンに保持されます。このガイドでは、トレードオフ、測定されたパフォーマンス、実際の Webship 設定について説明します。

TLS終了とTLSパススルーのどちらを選ぶかは、見かけだけのプロキシ設定ではありません。それは、暗号化がどこで終了するか、どのシステムがセッションキーを保持するか、Webship がHTTPを検査できるかどうか、そしてどのレイヤーがアプリケーションセキュリティを強制する必要があるかを決定します。

Webship はデフォルトでパススルーになります。これにより、アプリケーションの平文およびアクティブなセッションキーはオリジンに保持されます。エッジが HTTP リクエストを理解して処理する必要がある場合にのみ、終了を有効にしてください。

一文での決定

オリジンがTLS境界を所有する必要がある場合は、TLSパススルーを使用します。Webship がHTTPトラフィックをルーティング、保護、変換、キャッシュ、または監視する必要がある場合は、TLSターミネーションを使用します。

どちらのモードも普遍的により安全というわけではありません。パススルーはエッジで扱う機密情報を減らしますが、エッジのHTTPセキュリティコントロールを無効にします。ターミネーションは検査可能な施行ポイントを追加しますが、Webship を信頼されたTLS境界の一部にします。

| 関心事 | TLS終了 | TLSパススルー | | --- | --- | --- | | TLS エンドポイント | Webship | オリジン | | アプリケーションのプレーンテキストは Webship です | はい | いいえ | | Webship でのアクティブな下流セッションキー | はい | いいえ | | HTTPパスまたはメソッドによるルート | はい | いいえ | | WAF、APIシールド、ボディ制限は Webship で | はい | いいえ | | プロキシキャッシュ、書き換え、転送ヘッダー | はい | いいえ | | TCP ルーティング入力 | HTTP オーソリティおよびルートポリシー | ClientHello SNI | | HTTP/3 ルーティング | HTTP リクエストデータ | 1つの共有 UDP オリジン | | オリジン責任 | HTTP または個別に構成されたアップストリーム TLS | フル TLS、ALPN、および HTTP スタック |

したがって重要な質問は「どのスイッチが速いか?」ではありません。「どのコンポーネントがリクエストを見て制御できるようにすべきか?」です。

Webship にどの終了が与えられるか

tls_termination = true を用いることで、Webship は下流の TLS を完了し、復号されたリクエストを HTTP リバースプロキシパイプラインに入力します。これにより、以下の機能が可能になります。

  • パス、ホスト、およびメソッド認識ルーティング;
  • WAFおよびAPIシールドの検査;
  • リクエストボディの制限とポリシーのタイムアウト;
  • プロキシキャッシュと生成安全な無効化;
  • 転送ヘッダ管理およびHTTPアクセスログフィールド;
  • ボディ認識型のクエリ処理、安全な場合のリトライ、およびサーキットブレーカーポリシー;
  • クライアント向け接続と上流接続間のプロトコル変換。

このモードはセキュリティ責任も変更します。Webship ホストは、証明書の秘密鍵、セッションキー、復号化されたリクエストおよびレスポンスデータ、可観測性出力、およびキャッシュされた表現を保護する必要があります。次のホップを暗号化したままにする必要がある場合は、型指定のアップストリームTLSを別途構成してください。そうでない場合、HTTPアップストリームは平文です。

終了は、Webship が暗号化されたトランスポートリレーとしてだけでなく、アプリケーション対応のエッジとして動作することが期待されるときの右側の境界です。

パススルーが保持するもの

tls_termination = false(デフォルト)を使用すると、Webship は HTTP リクエストやレスポンスを復号せずに暗号化された TLS または QUIC トラフィックを中継します。アプリケーションのプレーンテキストおよびアクティブなセッションキーはオリジンに保持されます。

証明書をアプリケーション層に保持する必要がある場合、コンプライアンスポリシーでエッジでの復号を禁止している場合、または特定のオリジンのTLS識別情報をクライアントに変更せずに届ける必要がある場合に、このより小さな信頼境界は有用です。また、リレーパスからHTTPの解析やポリシー処理を取り除くこともできます。

トレードオフは厳格です:Webship は復号できないものを検査できません。HTTP WAF ルールを適用したり、パスごとにルーティングしたり、ヘッダーを書き換えたり、本文対応の API ポリシーを施行したり、HTTP フィールドアクセスログを生成したりすることはできません。これらすべての制御はオリジン自身が提供する必要があります。

したがって、パススルーは「機能が少ない終了」ではありません。これは、異なるセキュリティ責任者を持つ異なるアーキテクチャです。

プロトコル固有の制限は重要です

HTTP/1.1 TLSおよびHTTP/2 TLSの場合、WebshipはSNIによって設定されたTCP宛先を選択するために、ClientHelloを必要最小限だけ検査します。各パススルードメインは、実際のリクエストパスが暗号化されたままであるため、キャッチオールpath_prefix = "/"ルートが必要です。SNIのないクライアントは、構成に1つのドメインしかない場合のみ受け入れられます。

オリジンはクライアントのALPNを交渉し、選択されたプロトコルをサポートする必要があります。Webship は、TLSセッションが変更されずに通過している間、HTTP/2 クライアントを HTTP/1.1 オリジンに変換することはできません。

HTTP/3 は UDP 上で QUIC を使用し、より厳密な境界を持っています。暗号化された HTTP オーソリティで安全にルーティングできないため、構成されたすべての HTTP/3 ルートは同じ IP ソケット UDP オリジンに解決する必要があります。Webship は、構成の検証中に Unix ソケットや複数の HTTP/3 パススルーオリジンを拒否し、曖昧にルーティングすることを避けます。

クリアテキスト HTTP/1.1 および h2c は reverse_proxy.tls_termination に影響されません。この設定は、下流の HTTP/1.1 TLS、HTTP/2 TLS、および HTTP/3 TLS のみを制御します。

測定されたリクエスト容量

Webship 1.3.1 Debianの容量ベンチマークは、2つの暗号化リバースプロキシモードを個別に測定しました。受け入れられたすべてのサンプルには、HTTP、ソケット、プロトコル、プロキシ、メジャーページフォルト、およびHTTP/3パケット損失エラーがゼロであることが必要でした。

| リバースプロキシモード | HTTP/1.1 TLS | HTTP/2 TLS | HTTP/3 TLS | | --- | ---: | ---: | ---: | | TLS 終端 | 123,344 RPS | 124,957 RPS | 131,529 RPS | | TLS パススルー | 203,950 RPS | 266,845 RPS | 167,010 RPS |

小規模レスポンスパススルーは処理するアプリケーション作業が少ない:TLSを終了させたり、HTTPを解析したり、ポリシーを評価したり、新しい下流のTLSストリームを生成したりする代わりに、暗号化されたトランスポートデータを中継する。パススルーのリクエストレートが高いのは、その狭い作業内容を反映している。

これらの行は同一の機能セットを表しておらず、あるセキュリティアーキテクチャが普遍的に優れていると主張するために使用すべきではありません。Termination は、パススルーでは意図的に提供できない HTTP 対応機能に対して対価を支払います。

一度に大量にストリーミングすると結果が変わる

同じベンチマークでは、100 MBのストリーミングマトリックスに対して正確に99,943,778バイトのレスポンスボディが使用されました。ここでは、TLSターミネーションが3つのプロトコルすべてに対して中央値のペイロードスループットを向上させました。

| リバースプロキシモード | HTTP/1.1 TLS | HTTP/2 TLS | HTTP/3 TLS | | --- | ---: | ---: | ---: | | TLS 終端 | 3,585.7 MiB/s | 3,355.0 MiB/s | 1,938.6 MiB/s | | TLS パススルー | 2,783.2 MiB/s | 2,135.0 MiB/s | 1,748.5 MiB/s |

なぜ方向が変わるのですか?終了モードでは、ベンチマークのオリジンがクリアテキストHTTPをWebshipに送信し、Webshipが最適化された下流バルクパスを所有しています。大きなHTTP/1.1およびHTTP/2のレスポンスは、適応型Linux kTLSおよび境界付きトランスポート固有バッファリングを使用できます。HTTP/3は、kTLSの代わりにQUICペーシング、DPLPMTUD、およびリアクターごとのバッチ処理を使用します。

パススルーモードでは、オリジンがダウンストリームTLSを所有し、Webshipが生成された暗号化ストリームまたはQUICパケットを中継します。これによりオリジンのTLS境界は保持されますが、WebshipのHTTP対応バルクリスポンス経路は使用できません。

7サンプルのHTTP/3資格では安定性も確認されました。ストリーミングを終了した場合、中央値は1,938.6 MiB/sで、変動係数は2.12%でした。パススルーでは1,748.5 MiB/sで、変動係数は1.65%でした。どちらもクライアント、プロトコル、パケット損失のエラーなしで、正確なボディを配信しました。

パススルーを意図的に構成する

最小限のパススルー構成では、TLS識別情報がステージングされ、オペレーターが証明書パスを変更せずに後で終了を有効にできるようにします:

[reverse_proxy]
enabled = true
tls_termination = false

[reverse_proxy.protocols]
h1 = true
h2 = true
h3 = true

[reverse_proxy.tls]
cert = "/etc/webship/proxy-cert.pem"
key = "/etc/webship/proxy-key.pem"

[[reverse_proxy.routes]]
domain = "app.example.com"
path_prefix = "/"
upstreams = ["10.0.0.20:443"]

[[reverse_proxy.policies]]
name = "default"
path_prefixes = ["/"]
total_timeout_ms = 30000

ステージングされた Webship 証明書は検証されましたが、アクティブなパススルーセッションでは使用されていません。10.0.0.20:443 のオリジンは TLS を終了し、クライアントが交渉したプロトコルをサポートする必要があります。

エッジがHTTPを必要とするときに終了を有効にする

アプリケーション対応エッジの場合、終了を有効にし、生成されたHTTPトラフィックを選択したオリジンに送信します:

[reverse_proxy]
enabled = true
tls_termination = true

[reverse_proxy.protocols]
h1 = true
h2 = true
h3 = true

[reverse_proxy.tls]
cert = "/etc/webship/proxy-cert.pem"
key = "/etc/webship/proxy-key.pem"

[[reverse_proxy.routes]]
domain = "app.example.com"
path_prefix = "/api"
strip_path_prefix = true
upstreams = ["10.0.0.20:8080", "10.0.0.21:8080"]

[[reverse_proxy.policies]]
name = "default"
hosts = ["app.example.com"]
path_prefixes = ["/"]
max_body_bytes = 1048576
request_body_idle_timeout_ms = 5000
upstream_header_timeout_ms = 5000
response_body_idle_timeout_ms = 5000
downstream_write_idle_timeout_ms = 5000
total_timeout_ms = 30000

この構成はHTTPをルーティングおよび検査できます。Webshipとオリジン間のネットワークが既に信頼されていないか、隔離されていない場合は、アップストリームTLSを追加してください。

再起動せずにモードを切り替える Webship

Webship は、設定ファイルのリロードやバージョン確認済みの webship.reverse_proxy.apply_config MCP ツールを通じて tls_termination を変更できます。現在のオブジェクトとバージョンを webship.reverse_proxy.get_config で読み取り、返されたオブジェクト全体の中で意図したフィールドだけを変更し、対応する expected_version_id とともに提出してください。

新しいTCP接続は新しいモードを使用します。HTTP/3 クライアントは置き換えられたUDPトランスポートに再接続します。証明書およびキーのパス変更はプロセスに依存しており再起動が必要なため、ライブスイッチの前に有効な終了識別情報を準備しておいてください。

バージョンチェックは、あるオペレーターが同時に行われた設定の変更を上書きするのを防ぎます。更新が拒否されると、アクティブなランタイムおよび保存された設定は変更されません。

実用的な選択チェックリスト

次のすべてが当てはまる場合は、パススルーを選択してください:

  1. オリジンは証明書の境界とセッションキーを保持する必要があります。
  2. SNIレベルのTCPルーティング、または1つの共有されたHTTP/3 UDPオリジンで十分です。
  3. オリジンは、必要なWAF、認証、ログ記録、ボディ制限、および不正使用防止の制御を提供します。
  4. エッジキャッシュ、パス書き換え、転送ヘッダーポリシー、またはHTTPプロトコルの変換は必要ありません。

Webshipで次のいずれかが必要な場合は、終了を選択してください:

  1. ホスト、パス、またはメソッドによってルートを指定します。
  2. WAFまたはAPIシールドでリクエストを検査する。
  3. ボディ制限、HTTPタイムアウト、またはエッジ認証を強制する。
  4. レスポンスをキャッシュするか、HTTPヘッダーを書き換える。
  5. 下流および上流のHTTPプロトコル間で変換する。
  6. プロキシ境界でHTTPフィールドを観察する。

どのモードを選択しても、SNI、ALPN、証明書の識別、クライアントのキャンセル、上流のハーフクローズ、正確なレスポンスの整合性をテストしてください。リクエスト容量とストリーミングスループットは別々に測定してください:小さいレスポンスに対して最速のモードが、必ずしも100 MBのボディに対して最速のモードであるとは限りません。

Webship は、プロキシが信頼境界を黙って広げるべきではないため、デフォルトでパススルーを行うようにします。HTTP対応のエッジ動作がその責任に値する場合、終了は依然として明示的な運用上の選択肢として残ります。

完全な[リバースプロキシのドキュメント](/docs/1.3.1)を読み、承認された[ベンチマークマトリックス](/benchmarks)と比較するか、[ダウンロード](/downloads)からWebshipをダウンロードしてください。

情報源とコンテンツ方法

パフォーマンス値は、2026年9月11日付のWebship 1.3.1統一Debian容量ベンチマークから受け入れられた中央値です。その受け入れ基準は、クライアント、HTTP、ソケット、プロトコル、プロキシ、主要ページフォルト、およびHTTP/3パケットロスのエラーをゼロとすることを要求します。