TLS 伺服器名稱指示 (SNI)

此範例示範一個 Envoy 代理,該代理在相同的 IP 位址上監聽三個 TLS 網域。

前兩個網域 (domain1domain2) 終止 TLS 並代理到上游 HTTP 主機。

另一個網域 (domain3) 會根據 SNI 標頭進行未終止的代理。

它還示範了 Envoy 作為用戶端代理連接到上游 SNI 服務。

步驟 1:為每個網域端點建立金鑰對

將目錄變更為 Envoy 儲存庫中的 examples/tls-sni

此範例建立兩個 Envoy TLS 端點,它們將需要自己的金鑰對。

如下所示,為這些端點建立自我簽署憑證

$ pwd
envoy/examples/tls-sni

$ mkdir -p certs

$ openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 \
         -subj "/C=US/ST=CA/O=MyExample, Inc./CN=domain1.example.com" \
         -keyout certs/domain1.key.pem \
         -out certs/domain1.crt.pem
Generating a RSA private key
.............+++++
...................+++++
writing new private key to 'certs/domain1.key.pem'
-----

$ openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 \
         -subj "/C=US/ST=CA/O=MyExample, Inc./CN=domain2.example.com" \
         -keyout certs/domain2.key.pem \
         -out certs/domain2.crt.pem
Generating a RSA private key
.............+++++
...................+++++
writing new private key to 'certs/domain2.key.pem'
-----

警告

SNI 不會 驗證所提供的憑證對於網域是否正確,或是否由已識別的憑證授權單位發行。

請參閱 保護 Envoy 快速入門指南 以取得有關 驗證憑證 的更多資訊。

步驟 2:啟動容器

建置並啟動容器。

這會啟動兩個在上游 Docker 網路的 80 連接埠上監聽的上游 HTTP 容器,以及一個在上游內部 443 連接埠上監聽的上游 HTTPS 服務

在這些前面是一個 Envoy 代理,該代理在 https://127.0.0.1:10000 上監聽,並提供三個 SNI 路由的 TLS 網域

  • domain1.example.com

  • domain2.example.com

  • domain3.example.com

前兩個網域使用 您在步驟 1 中建立的金鑰和憑證來終止 TLS 並代理到兩個上游 HTTP 伺服器。

第三個網域會根據要求的 SNI 位址代理到上游 TLS 伺服器,但本身不會執行任何 TLS 終止。

組合還會啟動一個在 https://127.0.0.1:20000 上監聽的 Envoy 代理用戶端。

用戶端代理沒有 TLS 終止,而是將三個路由路徑 - /domain1/domain2/domain3 - 代理到啟用 SNI 的代理。

$ pwd
envoy/examples/tls-sni
$ docker compose pull
$ docker compose up --build -d
$ docker compose ps

       Name                        Command                State         Ports
-------------------------------------------------------------------------------------------
tls-sni_http-upstream1_1   node ./index.js                Up
tls-sni_http-upstream2_1   node ./index.js                Up
tls-sni_http-upstream3_1   node ./index.js                Up
tls-sni_proxy_1            /docker-entrypoint.sh /usr ... Up      0.0.0.0:10000->10000/tcp
tls-sni_proxy-client_1     /docker-entrypoint.sh /usr ... Up      0.0.0.0:20000->10000/tcp

步驟 2:使用 curl 直接查詢 SNI 端點

您可以使用 curl 直接查詢 Envoy 代理的 SNI 路由 HTTPS 端點。

若要執行此操作,您必須明確告知 curl 正確解析端點的 DNS

每個端點都應代理到各自的 http-upstreamhttps-upstream 服務。

$ curl -sk --resolve domain1.example.com:10000:127.0.0.1 \
      https://domain1.example.com:10000 \
     | jq -r '.os.hostname'
http-upstream1

$ curl -sk --resolve domain2.example.com:10000:127.0.0.1 \
      https://domain2.example.com:10000 \
     | jq -r '.os.hostname'
http-upstream2

$ curl -sk --resolve domain3.example.com:10000:127.0.0.1 \
      https://domain3.example.com:10000 \
     | jq -r '.os.hostname'
https-upstream3

步驟 3:透過 Envoy 代理用戶端查詢 SNI 端點

接下來,使用路由路徑查詢 Envoy 代理用戶端。

這些路徑會透過 SNI 代理端點路由到各自的 http-upstreamhttps-upstream 服務。

$ curl -s https://127.0.0.1:20000/domain1 \
     | jq '.os.hostname'
http-upstream1

$ curl -s https://127.0.0.1:20000/domain2 \
     | jq '.os.hostname'
http-upstream2

$ curl -s https://127.0.0.1:20000/domain3 \
     | jq '.os.hostname'
https-upstream3

另請參閱

保護 Envoy 快速入門指南

保護 Envoy 的重要概念概述。

TLS 沙箱

沙箱包含有關如何設定 Envoy 以使用透過 TLSHTTP 加密連線的範例。

雙重代理沙箱

一個使用 mTLS 和非 HTTP 流量驗證和相互驗證來保護代理之間流量的範例。