Nginx中ssl_certificate与ssl_certificate_key变量无法生效问题排查
问题原因
你遇到的问题是set指令的执行时机和ssl_certificate的加载时机不匹配:
set属于请求处理阶段的指令,只有当Nginx开始处理HTTP请求时才会为变量赋值- 而
ssl_certificate和ssl_certificate_key需要在SSL握手初始化阶段就确定证书路径,这时候请求阶段的变量还未被赋值,导致自定义变量为空,Nginx只能使用默认路径(错误日志里的/etc/nginx/就是这种情况的表现)
而$host这类内置变量是在SSL握手阶段就已经可用的,所以能正常生效。
解决方案
改用map指令定义变量,map是在Nginx配置加载阶段就完成变量映射的,能在SSL握手阶段被正确读取。
配置示例
在http块中定义map规则(必须放在http级别,不能在server块内):
http { # 根据User Agent映射证书路径 map $http_user_agent $ssl_cert { default /etc/letsencrypt/live/redacted.com/fullchain.pem; # 匹配Chrome浏览器 ~*chrome /etc/letsencrypt/live/chrome.example.com/fullchain.pem; # 匹配Firefox浏览器 ~*firefox /etc/letsencrypt/live/firefox.example.com/fullchain.pem; } map $http_user_agent $ssl_key { default /etc/letsencrypt/live/redacted.com/privkey.pem; ~*chrome /etc/letsencrypt/live/chrome.example.com/privkey.pem; ~*firefox /etc/letsencrypt/live/firefox.example.com/privkey.pem; } server { listen 443 ssl; server_name redacted.com; ssl_certificate $ssl_cert; ssl_certificate_key $ssl_key; # 其余站点配置... } }
注意事项
- 确保所有证书文件及所在目录的权限允许Nginx进程读取(可将Nginx用户添加到证书所在的用户组,或调整文件权限为
640) - 修改配置后执行
nginx -t检查语法正确性,再重启Nginx生效 - User Agent的正则匹配可根据实际需求调整,注意匹配的优先级(
map中越靠前的规则优先级越高)
内容的提问来源于stack exchange,提问作者Artem Milosevic
相关产品推荐
相关产品推荐

