TL;DR
/etc/nginx/conf.d/ssl_map.conf1 2 3 4 5 6 7 8 9 10
| map $ssl_server_name $MatchedCert { default '/etc/nginx/ssl/localhost_P256/localhost.crt'; ~*^([^.]+)\.xiaoxuan010\.top$ '/etc/nginx/ssl/ ~*^([^.]+)\.r\.xiaoxuan010\.top$ '/etc/nginx/ssl/ } map $ssl_server_name $MatchedKey { default '/etc/nginx/ssl/localhost_P256/localhost.key'; ~*^([^.]+)\.xiaoxuan010\.top$ '/etc/nginx/ssl/ ~*^([^.]+)\.r\.xiaoxuan010\.top$ '/etc/nginx/ssl/ }
|
/etc/nginx/conf.d/ssl.conf1 2 3 4 5
| server { include /etc/nginx/conf.d/ssl_map.conf; server_name example.xiaoxuan010.top; ... }
|
问题
在一个 Nginx 实例中,持有多个域名通配符证书,传统做法需要为每个网站的 server
块配置证书路径,手动选择证书:
1 2 3 4 5 6 7 8 9 10 11 12 13
| server { server_name example.xiaoxuan010.top; ssl_certificate '/etc/nginx/ssl/#.xiaoxuan010.top_xiaoxuan010.top_P256/fullchain.cer'; ssl_certificate_key '/etc/nginx/ssl/#.xiaoxuan010.top_xiaoxuan010.top_P256/private.key'; ... }
server { server_name example.r.xiaoxuan010.top; ssl_certificate '/etc/nginx/ssl/#.r.xiaoxuan010.top_r.xiaoxuan010.top_P256/fullchain.cer'; ssl_certificate_key '/etc/nginx/ssl/#.r.xiaoxuan010.top_r.xiaoxuan010.top_P256/private.key'; ... }
|
每次新增网站,都要手动配置长长的证书路径,非常繁琐。
解决方案
在 Nginx 配置目录中,创建一个 ssl_map.conf
文件,用于配置域名和证书的映射关系:
/etc/nginx/conf.d/ssl_map.conf1 2 3 4 5 6 7 8 9 10
| map $ssl_server_name $MatchedCert { default '/etc/nginx/ssl/localhost_P256/localhost.crt'; ~*^([^.]+)\.xiaoxuan010\.top$ '/etc/nginx/ssl/ ~*^([^.]+)\.r\.xiaoxuan010\.top$ '/etc/nginx/ssl/ } map $ssl_server_name $MatchedKey { default '/etc/nginx/ssl/localhost_P256/localhost.key'; ~*^([^.]+)\.xiaoxuan010\.top$ '/etc/nginx/ssl/ ~*^([^.]+)\.r\.xiaoxuan010\.top$ '/etc/nginx/ssl/ }
|
这段代码创建了两个 map 块,分别用于匹配证书路径和私钥路径。$ssl_server_name 是 Nginx 内置变量,表示当前请求的域名。$MatchedCert
和 $MatchedKey
这两个变量的值取决于 $ssl_server_name
的值,会根据正则表达式匹配域名,选择对应的证书和私钥路径。
之后,在每个网站配置的 server
块中,引入 ssl_map.conf
文件,并设置 server_name
:
/etc/nginx/conf.d/ssl.conf1 2 3 4 5
| server { include /etc/nginx/conf.d/ssl_map.conf; server_name example.xiaoxuan010.top; ... }
|
大功告成,以后新增域名只需要在 ssl_map.conf
中添加两行映射关系即可,新增网站也不需要再配置证书路径。