【问题标题】:Configure NGINX SNI to use different header than 'Host'将 NGINX SNI 配置为使用与“主机”不同的标头
【发布时间】:2021-01-20 17:04:09
【问题描述】:

我有一个启用了 SNI 的有效 NGINX 配置,并且我能够根据传入的请求 Host 标头提供两个不同的 SSL 证书。

我需要的是能够将 NGINX 配置为使用不同的标头,而不是使用 Host 进行基于标头的“路由”。有谁知道这是否可能?

【问题讨论】:

  • SNI 是 TLS 协商的一部分,发生在发送 HTTP 请求之前。 SNI 中不涉及 HTTP 标头。你想达到什么目的?
  • 在 NGINX 配置中,我创建了两个具有两个不同服务器名称的服务器:server_name Test1;server_name Test2。当我使用标头 Host: Test1 发出请求时,我会从该服务器获得 SSL 证书,如果我使用标头 Host: Test2 发出请求,我会从第二台服务器获得 SSL 证书。所有这些对我来说都很好,但我想知道我是否可以使用与 Host 不同的不同标头来实现相同的结果?

标签: nginx header host sni


【解决方案1】:

Host 标头不用于确定您从服务器获得的证书。

TLS 握手以 ClientHello 开始,您的客户端提供主机名 (SN​​I) 作为此握手的一部分。然后服务器以正确的证书进行响应。 (在 NGINX 的情况下,如果您请求一个它不知道的服务器名称,它会使用其配置中定义的第一个证书进行响应。)

在 TLS 设置之后,您的客户端会发出一个包含 Host 标头的 HTTP 请求。通常,这将匹配 ClientHello 的 SNI 部分。

您正在测试的客户端很可能采用您正在设置的 Host 标头并使用它来设置 TLS 握手的 SNI,但它们是不相关的,甚至不需要匹配。

为了说明这一点,您可以使用openssl s_client -connect <server_ip>:443 -servername Test1,然后发送以下请求:

GET / HTTP/1.1
Host: Test2

在发出 HTTP 请求之前,您将看到您已获得 Test1 的证书。服务器将从Test2 发回响应。瞧,证明Host 标头没有按照您的想法进行。

您可以滥用 NGINX 来使用除 Host 之外的任意标头,但这并不能解决客户端 SNI 问题。有关基于请求正文使用 proxy_pass 的示例,请参阅此答案,并将其修改为使用标头:nginx conditional proxy pass

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-02
    • 2013-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多