nginx使用不同的证书配置通配符域

问题描述

在使用Nginx进行虚拟主机配置时,遇到了一个新问题。

我尝试使用webmail通配符为我的每个虚拟主机设置一个server_name”子域

server_name ~^(webmail\.)?(?<domain>.+)$;

因为我所有的域都有自己的ssl证书,所以我也想对Webmail子域也使用正确的证书。证书与*.domain1.com等中一样配置为通配符证书。

因此,webmail.domain1.com应该将证书用于*.domain1.com,而webmail.domain2.net应该使用*.domain2.net证书。

我首先尝试了以下方法,但由于它不接受路径中的变量,因此无法启动Nginx

ssl_certificate /etc/letsencrypt/live/$domain/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/$domain/privkey.pem;

是否有一种方法可以通过覆盖所有webmail.*子域的单个配置文件来实现此配置?

解决方法

是的,但不是您希望的方式...

您遇到的问题是nginx需要先终止SSL,然后才能读取流内容以获取Host标头以设置server_name来决定终止SSL所需的证书和密钥。这就是为什么变量和映射永远无法工作的原因,因为在nginx需要读取证书的时候它们还不存在。

(我相信OpenResty中有处理证书处理的Lua函数,但我认为这更多地是关于证书生命周期,而不是根据您的需要即时选择一个请求。)

实现此目标的方法是使用perl,python,bash编写脚本来生成conf脚本,无论您喜欢什么。描述仅需要提供域名的通用server块模板,并为每个域生成一个副本。它们可以全部放在一个文件中,也可以include从单独的文件中删除,无论哪种对您有用。

提示:如果使用点前缀命名conf文件,例如.server-tpl.conf,则通常的include conf.d/*.conf将忽略它。这样,您可以将此模板与其他conf文件一起保存,但仅会填充已填充的副本。