Nginx使用$ssl_server_name加载证书报错,硬编码路径正常
问题根源
当你用硬编码路径指定证书时,Nginx在启动阶段由root进程加载证书,此时拥有访问/etc/letsencrypt目录的权限;但使用$ssl_server_name变量时,证书是在SSL握手阶段由worker进程动态加载,而Ubuntu 22.04上Nginx的worker进程默认以www-data用户运行,该用户没有访问LetsEncrypt证书目录的权限,这就是权限拒绝错误的核心原因。
解决方案
1. 确认Nginx运行用户
验证Nginx worker进程的运行用户,默认应为www-data:
grep 'user' /etc/nginx/nginx.conf
2. 将www-data加入ssl-cert组
Ubuntu系统中,LetsEncrypt的证书目录默认归ssl-cert组管理,将www-data加入该组即可安全获取访问权限:
sudo usermod -aG ssl-cert www-data
3. 调整证书目录的权限链
确保证书所在的整个路径对www-data有执行权限(目录需要执行权限才能进入):
sudo chmod 710 /etc/letsencrypt/live sudo chmod 710 /etc/letsencrypt/archive
4. 重启Nginx生效
sudo systemctl restart nginx
额外优化
为避免因域名无对应证书导致的握手失败,可以用map指令提前映射合法域名的证书路径,同时设置默认证书:
map $ssl_server_name $cert_path { default /etc/letsencrypt/live/default-domain/fullchain.pem; test.example.com /etc/letsencrypt/live/test.example.com/fullchain.pem; foo.example.com /etc/letsencrypt/live/foo.example.com/fullchain.pem; } map $ssl_server_name $key_path { default /etc/letsencrypt/live/default-domain/privkey.pem; test.example.com /etc/letsencrypt/live/test.example.com/privkey.pem; foo.example.com /etc/letsencrypt/live/foo.example.com/privkey.pem; } server { listen 443 ssl http2; server_name _; ssl_certificate $cert_path; ssl_certificate_key $key_path; location / { add_header Content-Type text/html; return 200 $ssl_server_name; } }
内容的提问来源于stack exchange,提问作者Jasper
相关产品推荐
相关产品推荐

