如何正确使用SNI? (两种不同的 Nginx SNI 写法)

How to use SNI correctly? (Two Different Nginx SNI Writing Style)

这两种不同的SNI写法有什么区别?有人能从原理、性能等方面判断他们的区别吗?

样式 1

stream{
    map $ssl_preread_server_name $backend_name{
        A.example.com A;
        B.example.com B;
    }
    upsteam A{
        server 127.0.0.1:10086
    }
    upsteam B{
        server 127.0.0.1:10087
    }
}

http{
    server{
        listen 10086 ssl http2;
        server_name A.example.com
        ...
    }
}

风格2

server {
    listen 127.0.0.1:443 ssl;
    server_name A.example.com;
    ...
}
server {
    listen 127.0.0.1:443 ssl;
    server_name B.example.com;
    ...
}

从问题看来,您正在尝试在 443 端口上侦听不同的主机名。带有主机名 A.example.com 的请求应该转发到 127.0.0.1:10086,而带有主机名 B.example.com 的请求将转到 127.0.0.1:10087。让我解释一下这两种风格的幕后发生的事情。

样式 1

stream block lets you load balance over TCP/UDP. The ngx_stream_ssl_preread_module module lets you extract information from the request without ssl/tls termination. You're using map so connections coming as A.exammple.com set A in the variable $backend_name while those coming as B.example.com set B in the variable $backend_name. Based upon your upstream blocks the requests either get forwarded to 127.0.0.1:10086 or 127.0.0.1:10087. Since there is an http block with server blocks listening on port 10086 and 10087 respectively, it creates a new connection every time fulfilling those requests. The ssl termination is also happening inside the http block.

样式 2

Both server block are listening over 443 and depending on the hostname of the request it either goes through one of the server blocks. The ssl termination is happening before the request goes to ports where the application is actually running.

两种样式都可以很好地实现这一点,但我个人更喜欢 Style 2,因为 ssl 终止是在转发请求之前处理的。此外,在 Style 1 中创建了一个额外的连接,在我看来这是一个轻微的性能开销。