我有多个域,它们都由同一个 NGINX 实例提供服务。我正在尝试为 HTTPS 设置通用服务器配置,以便每个域都使用自己的证书并启用 SSL 装订。这些设置定义如下default.conf
:
server {
listen 443 default_server ssl;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256;
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /ssl/chain.pem;
ssl_certificate /ssl/$ssl_server_name/fullchain.pem;
ssl_certificate_key /ssl/$ssl_server_name/privkey.pem;
}
每个域在单独的配置文件中都有一个分配给它的服务器块,继承上面定义的 SSL 设置。例如,example.conf
会说:
server {
listen 443 ssl;
server_name example.com;
location / {
return 200 "Hello, world!";
}
}
不幸的是,这不起作用。使用此配置,运行openssl s_client -connect example.com:443 -status
结果会显示一条消息,提示“ OCSP response: no response sent
。
有趣的是,当我将配置更改为不使用$ssl_server_name
其中一个域名(比如说example.com
,参见下面的代码片段)时,我做收到该特定域的正确 OCSP 响应。正如预期的那样,由于提供了错误的证书,因此其他域的响应失败。
server {
...
ssl_certificate /ssl/example.com/fullchain.pem;
ssl_certificate_key /ssl/example.com/privkey.pem;
...
}
这对我来说当然不是一个解决方案,因为它仍然需要我为每个域指定每个证书。
问题
- 是否可以结合使用
$ssl_server_name
和 SSL 装订?如果可以,如何做? - NGINX 的行为是否如我所描述的那样符合预期/记录?
- 此处介绍的配置是否存在可能导致麻烦的问题?
答案1
ssl_stapling on
被默默忽视的行为在文件名中使用变量被追踪为缺陷 #1813。
唯一表明这是特殊情况的文献是ssl_certificate
在该指令的文件中(重点是我的):
自 1.15.9 版本起,使用 OpenSSL 1.0.2 或更高版本时可以在文件名中使用变量:
ssl_certificate $ssl_server_name.crt; ssl_certificate_key $ssl_server_name.key;
请注意,使用变量意味着每次 SSL 握手都会加载证书,这可能会对性能产生负面影响。
目前似乎没有计划完成这方面的“ssl_* 指令中的变量”的实现以及相关方面。
如果你没有办法通过付钱请人来加快这一进程,你也许有兴趣观察增强 #813- 能够在需要之前获取并存储 OCSP 响应的机制可能会解决最多您的问题也是如此。假设解决方案以动态证书缓存的形式出现,则只需向所有已知域发送请求以加载它们即可初始化该缓存。
在此之前,只需让您的 nginx 配置静态列出所有域和在文件名中反复提及它们..使用配置管理软件(例如 Ansible)来简化生成更新和发出重新加载的工作。
无论如何,请default_server
为那些可怜的非 SNI 客户端定义一个静态的、单独的块。Nginx 在每个服务器配置和处理未说明要与哪个客户端通信的客户端之间有一些令人惊讶的交互。