对于nginx多https站点通常的做法是这样:

server 443 ssl;
server_name nixops1.me;
ssl_certificate     /usr/local/nginx/keys/nixops1.me.crt;
ssl_certificate_key /usr/local/nginx/keys/nixops1.me.key;
......

如果有多个https站点,就是每个站点复制一份这个配置。如nixops2.me、nixops3.me等等,在只有几十个https站点的时候还好,如果某个站点的域名特别多,例如有几千个域名甚至上万个域名的时候,这个配置就很恐怖了,需要精简并合并配置。

下面举例说明,假设应用场景为:

  1. 同一站点有大量域名需要配置https证书,其它配置一样
  2. 每个之证书都是泛域名证书,如let's encrypt的wildcard证书
  3. 所有证书命名均为公钥domain.com.crt、私钥为domain.com.key 这样的格式
  4. 所有证书保存在相同目录中,如/usr/local/nginx/conf/keys/

具体做法可以用nginx的map和正则表达式,根据ssl_server_name(即https的访问域名),获取公钥和私钥的完整路径做为变量。配置证书时使用该变量即可。先来看nginx配置文件中HTTP段的map配置:

map $ssl_server_name $NixopsCert {
    default /usr/local/nginx/conf/keys/nixops.me.crt; #指定一个默认的证书
    ~*^(.+\.)*([^\.]+\.[^\.]+)$ /usr/local/nginx/conf/keys/$2.crt;
}

map $ssl_server_name $NixopsKey {
    default /usr/local/nginx/conf/keys/nixops.me.key;
    ~*^(.+\.)*([^\.]+\.[^\.]+)$ /usr/local/nginx/conf/keys/$2.key;
}

这样配置好后,如果通过https访问nixops1.me或*.nixops1.me,获取到的路径分别为:

$NixopsCert  --> /usr/local/nginx/conf/keys/nixops1.me.crt;
$NixopsKey   --> /usr/local/nginx/conf/keys/nixops1.me.key;

然后配置server段证书公钥和私钥时就不需要按传统作法复制配置,只需指定变量即可:

server {
    listen  80;
    listen  443 ssl http2;
    server_name
        nixops.me
        nixops1.me
        nixops2.me
        #......
    ;

    ssl_certificate     $NixopsCert;
    ssl_certificate_key $NixopsKey;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
   #其它server段配置
}

这样同一站点有多个证书时,就可以只在server_name里添加,不需要指定https配置了,和http站点添加域名绑定非常类似。