OpenResty Edge で SNI プロキシを設定する方法:復号せずに SNI ホスト名で TLS をルーティング
OpenResty Edge で SNI プロキシを設定するには、SNI Proxy タイプの Stream アプリケーションを作成し、バックエンドごとにアップストリームを追加し、SNI サーバー名変数にマッチするページルールを書いて、各 TLS 接続を復号せずに適切なバックエンドへルーティングします。その後、SNI Proxy ポートをゲートウェイパーティションに追加してリリースします。本チュートリアルではポート 4003 をリッスンし、www.google.com と www.ebay.com を異なるアップストリームへルーティングして、curl とブラウザで結果を検証します。
以下の手順では、Admin Web コンソールでのセットアップ全体を解説します:SNI Proxy アプリケーションの作成、アップストリームと SNI サーバー名ページルールの定義、ポート 4003 の開放、ルーティングのテストです。
SNI Proxy タイプの Stream アプリケーションを作成する
まずは OpenResty Edge の Admin Web コンソールにアクセスしましょう。これはコンソールのサンプルデプロイメントです。各ユーザーは独自のローカルデプロイメントを持っています。
Stream タイプのアプリケーションを作成します。
Stream アプリケーションリストページを選択します。
新しいアプリケーションを作成します。
Stream アプリケーションには SNI Proxy と TCP の2種類があることがわかります。
デフォルトで選択されているのは SNI Proxy タイプで、これが本日のテーマです。
TCP アプリケーションは別のチュートリアルで紹介されています。
ドメイン名として “www.google.com” を入力します。
この例では、異なる SNI 名を持つリクエストを処理する必要があります。そのため、複数のドメイン名が必要です。
このボタンをクリックして、2 つ目のドメイン名 www.ebay.com を追加します。
このアプリケーションを作成します。
アップストリームと SNI サーバー名のページルールを作成する
これはOpenResty Edge で基本的なリバースプロキシとロードバランサーを構築するのと同じアップストリームとページルールの流れですが、ここではルーティングの判断を SNI ホスト名に基づいて行います。
アップストリームページに移動します。
新しいアップストリームを作成します。
このアップストリームに名前を付けます。例えば、“google” とします。
ここで Google のホスト名を入力します。
ポート番号 443 を入力します。
このアップストリームを保存します。
次に 2 つ目のアップストリームを作成します。
このアップストリームを “eBay” と名付けます。
ここに eBay のホスト名を入力します。
ポート番号 443 を入力します。
このアップストリームを保存します。
アップストリームリストページに「google」と「eBay」が表示されています。
次に、これらのアップストリームを使用するページルールを作成します。
最初のページルールを作成します。
このページルールには条件を指定する必要があります。
ここで条件の変数名を選択できます。
リクエストの SNI 名に基づいてプロキシするアップストリームを選択するので、変数名は SNI サーバー名にする必要があります。
SNI を検索します。
SNI サーバー名を選択します。
演算子はデフォルトの String= のままにしておきます。
値の型は String にする必要があります。
値として “www.google.com” を入力します。
プロキシターゲットを追加します。
先ほど作成した最初のアップストリームを選択します。
ここにはいくつかのバランシング戦略が選択可能です。
アップストリームにはサーバーが1つしかないため、どのバランシング戦略を選んでも重要ではありません。
デフォルトのラウンドロビン戦略のままで構いません。
公共ネットワークを介してこのアップストリームにアクセスするため、ここですべてのタイムアウト時間を 60 秒に設定します。
このページルールを作成します。
次に、もう1つのページルールを作成します。
このルールにも条件を指定します。
条件の変数名は引き続き SNI サーバー名です。
値として “www.ebay.com” を入力します。
プロキシターゲットを追加します。
先ほど作成した 2 つ目のアップストリームを選択します。
すべてのタイムアウト時間を 60 秒に変更します。
このページルールを作成します。
プロキシページルールがページルールリストページに表示されていることがわかります。
最後のステップは、新しい設定をリリースすることです。先ほどの変更をすべてのゲートウェイサーバーにプッシュします。
このボタンをクリックして新しいリリースを行います。
リリースします。
変更がすべてのゲートウェイサーバーに同期されました。このサンプルデプロイメントでは、ゲートウェイネットワークに14台のサーバーがあることがわかります。
ネットワーク全体で増分的な設定同期を行っています。
リクエスト単位でリアルタイムに設定を更新しています。アプリケーションレベルの設定変更はすべて、サーバーのリロード、再起動、またはバイナリアップグレードを必要としません。そのため、多くの異なるユーザーが頻繁にリリースを行っても、スケーラビリティが高くなっています。
ゲートウェイパーティションに SNI Proxy ポートを追加する
図に示すように、リッスンポートとして 4003 を使用します。まず、このポートをアプリケーションのパーティションに追加します。
ゲートウェイパーティションページに移動します。
ゲートウェイパーティションページを開きます。現在はパーティションリストページにいます。多くのパーティションが既に存在していることがわかります。
「default」パーティションに SNI Proxy タイプのポートを追加します。
このボタンをクリックします。
ポートを追加します。
リストの一番上に新しい行が表示されていることがわかります。
ポート番号として 4003 を入力します。
タイプとして SNI Proxy を選択します。
保存をクリックします。
新しいポートがデフォルトパーティションに正常に追加されたことがわかります。
このパネルを閉じます。
curl とブラウザで SNI プロキシをテストする
次に、ゲートウェイクラスターページに移動し、テスト用の Edge サーバーを1つ選択しましょう。
米国にあるノードを選択します。IP アドレスが .84 で終わるものに注目してください。
このサーバーを使用して、先ほど追加したページルールをテストします。
SNI 名 www.google.com を使用して、curl リクエストを送信します。
curl -I --resolve www.google.com:4003:3.131.85.84 https://www.google.com:4003
サーバーが確かに Google であることがわかります。これは、先ほど追加したページルールが機能していることを意味します。SNI 名が “www.google.com” のリクエストが正しいアップストリームにプロキシされました。
次に、SNI 名が “www.ebay.com” の別の curl リクエストを送信します。
curl -I --resolve www.ebay.com:4003:3.131.85.84 https://www.ebay.com:4003
サーバーが eBay であることがわかります。2 つ目のページルールも機能しています。
次に、ブラウザを使用してテストを行います。まず、マシンの Host バインディングを確認しましょう。
cat /etc/hosts
Host バインディングが正しいことがわかります。
次に、ブラウザで Google にアクセスします。
eBay にアクセスします。
よくある質問
SNI プロキシはどのように復号せずに TLS トラフィックをルーティングするのですか?
SNI プロキシは、TLS ハンドシェイクの暗号化されていない ClientHello から SNI ホスト名を読み取ってバックエンドを選択し、暗号化されたストリームをそのまま転送します。OpenResty Edge では、ページルールで SNI サーバー名変数にマッチさせることで、ゲートウェイは TLS を終端も復号もせずに各接続を正しいアップストリームへルーティングします。
OpenResty Edge で異なる SNI ホスト名を異なるバックエンドにルーティングするには?
バックエンドごとにアップストリームを 1 つ作成し、ホスト名ごとにページルールを追加します。条件で SNI サーバー名変数をそのホスト名(例:www.google.com や www.ebay.com)に設定し、プロキシターゲットを対応するアップストリームにします。リクエストが到着すると、ゲートウェイはその SNI 名をルールと照合し、該当するアップストリームへプロキシします。
SNI プロキシはどのポートをリッスンしますか?
ポートは、ゲートウェイパーティションに SNI Proxy タイプのポートとして追加したものです。本チュートリアルではポート 4003 を追加するので、Edge サーバーは 4003 でリッスンし、受信 TLS 接続を SNI 名でルーティングします。空いているポートであれば任意に選べます。
設定変更にはゲートウェイの再起動が必要ですか?
いいえ。OpenResty Edge は増分的な設定同期を行い、リクエスト単位でリアルタイムに設定を更新します。アプリケーションレベルの変更にはサーバーのリロード、再起動、バイナリアップグレードは一切不要なので、多くのユーザーが頻繁にリリースしてもスケーラビリティは高いままです。
OpenResty Edge は SNI TLS 以外のプロトコルもプロキシできますか?
はい。SNI Proxy Stream アプリケーションのほか、Edge は TCP Stream アプリケーションと L7 プロキシもサポートします。例えば HTTP/2 ベースのバックエンドについてはOpenResty Edge で gRPC プロキシを設定する方法を参照してください。
SNI プロキシが機能しているかをテストするには?
特定の SNI 名を持つ TLS リクエストを送信し、どのバックエンドが応答するかを確認します。本チュートリアルでは curl -I --resolve www.google.com:4003:<edge-ip> https://www.google.com:4003(www.ebay.com も同様)を使い、その後 /etc/hosts バインディングを使ってブラウザで再確認します。
OpenResty Edge について
OpenResty Edge は、マイクロサービスと分散トラフィックアーキテクチャ向けに設計された多機能ゲートウェイソフトウェアで、当社が独自に開発しました。トラフィック管理、プライベート CDN 構築、API ゲートウェイ、セキュリティ保護などの機能を統合し、現代のアプリケーションの構築、管理、保護を容易にします。OpenResty Edge は業界をリードする性能と拡張性を持ち、高同時接続・高負荷シナリオの厳しい要求を満たすことができます。K8s などのコンテナアプリケーショントラフィックのスケジューリングをサポートし、大量のドメイン名を管理できるため、大規模ウェブサイトや複雑なアプリケーションのニーズを容易に満たすことができます。
→ SNI プロキシはプラットフォームの L4 ツールの一つです。その他の機能は OpenResty Edge プラットフォームの全体像を、オープンソース版との比較もあわせてご参照ください。
→ 関連記事:ゲートウェイで TLS を終端する場合は、OpenResty Edge の ACME モジュールで SSL 証明書の発行・更新を自動化できます。
著者について
章亦春(Zhang Yichun)は、オープンソースの OpenResty® プロジェクトの創始者であり、OpenResty Inc. の CEO および創業者です。
章亦春(GitHub ID: agentzh)は中国江蘇省生まれで、現在は米国ベイエリアに在住しております。彼は中国における初期のオープンソース技術と文化の提唱者およびリーダーの一人であり、Cloudflare、Yahoo!、Alibaba など、国際的に有名なハイテク企業に勤務した経験があります。「エッジコンピューティング」、「動的トレーシング」、「機械プログラミング」 の先駆者であり、22 年以上のプログラミング経験と 16 年以上のオープンソース経験を持っております。世界中で 4000 万以上のドメイン名を持つユーザーを抱えるオープンソースプロジェクトのリーダーとして、彼は OpenResty® オープンソースプロジェクトをベースに、米国シリコンバレーの中心部にハイテク企業 OpenResty Inc. を設立いたしました。同社の主力製品である OpenResty XRay(動的トレーシング技術を利用した非侵入型の障害分析およびトラブルシューティングツール)と OpenResty Edge(マイクロサービスおよび分散トラフィックに最適化された多機能ゲートウェイソフトウェア)は、世界中の多くの上場企業および大企業から高い評価を得ております。OpenResty 以外にも、章亦春は Linux カーネル、Nginx、LuaJIT、GDB、SystemTap、LLVM、Perl など、複数のオープンソースプロジェクトに累計 100 万行以上のコードを寄与し、60 以上のオープンソースソフトウェアライブラリを執筆しております。
翻訳
英文版の原文と日本語訳版(本文)をご用意しております。読者の皆様による他の言語への翻訳版も歓迎いたします。全文翻訳で省略がなければ、採用を検討させていただきます。心より感謝申し上げます!




































































































