TLS 服务器名称指示 (SNI
)
此示例演示了一个 Envoy 代理,它在同一个 IP
地址上侦听三个 TLS
域。
前两个域 (domain1
和 domain2
) 终止 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'
-----
步骤 2:启动容器
构建并启动容器。
这将启动两个上游 HTTP
容器,它们在内部 Docker 网络上的端口 80
上侦听,以及一个上游 HTTPS
服务,它在内部端口 443
上侦听
在这些容器前面是一个 Envoy 代理,它在 https://127.0.0.1:10000 上侦听,并提供三个 SNI
路由的 TLS
域
domain1.example.com
domain2.example.com
domain3.example.com
前两个域使用 您在步骤 1 中创建的 密钥和证书来终止 TLS
并代理到两个上游 HTTP
服务器。
第三个域根据请求的 SNI
地址代理到上游 TLS
服务器,但本身不执行 TLS
终止。
该组合还启动了一个 Envoy 代理客户端,它在 https://127.0.0.1:20000 上侦听。
客户端代理没有 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-upstream
或 https-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-upstream
或 https-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 如何配置以使用通过
TLS
的HTTP
进行加密连接的示例。- 双代理沙箱
使用
mTLS
(带非HTTP
流量)进行验证和双向身份验证来保护代理之间流量的示例。