有时我们需要在一台主机(只有一个公网 ip)上部署多个 https 虚拟主机,如何实现呢?

假如我们想当然的使用如下的配置:

server{
 listen 443 default ssl;
 server_name www.test1.com;
 ssl_certificate xxxxx;
 ssl_certificate_key xxxxx;
}

server{
 listen 443 ssl;
 server_name www.test2.com;
 ssl_certificate xxxxx;
 ssl_certificate_key xxxxx;
}

当然是无法实现的,不论请求哪个主机,都只会收到默认域名www.test1.com的证书,这是 SSL 协议本身造成的–先建立 SSL 连接,再发送 HTTP 请求,因此 nginx 建立 SSL 连接时并不知道所请求的域名,所以只会返回默认的主机。

解决办法

使用多个 IP

最古老的办法就是使用多个 IP,每个域名绑定到一个 IP 上即可。

使用 TLS SNI

使用多 IP 的方法成本太高了,还好 nginx 支持 TLS 协议的 SNI 拓展(这个拓展让同一个 IP 使用不同的 https 证书成为可能)。SNI 拓展需要客户端支持(一般都支持),本地 OpenSSL 支持(这个默认都是不支持的,需要手动编译支持)。

查看 nginx 知否支持 SNI,使用如下命令:

nginx -V

有如下输出说明支持 SNI。

默认情况下是不支持的,下面我们来一步一步让它支持 SNI:

  1. 首先要重新编译安装 openssl,详情参考我之前的博文:https://blog.fleyx.com/blog/detail/20190503

  2. openssl 支持 SNI 后,重装一次 nginx 理论上就可以了(至少我是这样的):

apt remove nginx
apt install nginx

然后就可以在一个 IP 上使用多个不同的 https 证书了.