You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NGINX中通过$host动态指定SSL证书路径失败的问题排查

单Nginx Server块动态加载多域名SSL证书失败问题排查

问题描述

我拥有两个SSL证书,分别对应域名foo.com和bar.com。我希望通过单个server配置块同时为这两个域名提供服务,配置如下:

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name foo.com bar.com;

    ssl_certificate     $cert_path/fullchain.pem;
    ssl_certificate_key $cert_path/privkey.pem;
}

在http { .. }块中,我通过map指令定义了$cert_path变量:

map $host $cert_path {
  foo.com      /etc/certbot/live/foo.org;
  bar.com      /etc/certbot/live/bar.org;
}

但我持续收到如下日志错误:

2024/10/04 11:30:13 [error] 9#9: *73 cannot load certificate "/fullchain.pem": BIO_new_file() failed (SSL: error:80000002:system library::No such file or directory:calling fopen(/fullchain.pem, r) error:10000080:BIO routines::no such file) while SSL handshaking, client: x.x.x.x, server: 0.0.0.0:443

这种通过map结合$host动态加载证书的方式似乎无法正常工作,请问可能是什么原因导致的?

原因分析与解决办法

核心问题

  1. 变量时机错误:Nginx在SSL握手阶段无法获取$host变量——$host依赖HTTP请求头中的Host字段,而SSL握手发生在HTTP请求之前。这导致$cert_path变量在加载证书时为空,Nginx只能尝试加载/fullchain.pem(缺少前缀路径),最终报错文件不存在。
  2. 路径笔误:map配置中,foo.com对应的证书路径写为/etc/certbot/live/foo.org,bar.com对应/etc/certbot/live/bar.org,域名后缀与实际证书目录不一致,即使变量正常工作,也会找不到正确的证书文件。

正确配置方案

要实现单server块动态加载多域名证书,需使用$ssl_server_name变量(该变量在SSL握手阶段即可通过SNI扩展获取),并确保Nginx版本≥1.15.9(此版本开始支持用变量动态指定SSL证书路径):

  1. 修正map指令,替换变量并修正路径:
map $ssl_server_name $cert_path {
  foo.com      /etc/certbot/live/foo.com;
  bar.com      /etc/certbot/live/bar.com;
}
  1. 保留server块配置,可显式声明SNI支持(默认已开启):
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name foo.com bar.com;

    ssl_certificate     $cert_path/fullchain.pem;
    ssl_certificate_key $cert_path/privkey.pem;
    ssl_prefer_server_ciphers on;
}

额外注意事项

  • 确保Nginx进程用户(如www-data、nginx)拥有证书目录及文件的读取权限,Certbot生成的证书目录默认权限通常需要调整为755,文件权限为644。
  • 验证Certbot生成的符号链接是否有效:/etc/certbot/live/域名/下的fullchain.pem和privkey.pem是指向真实证书文件的符号链接,需确保链接未失效。

内容的提问来源于stack exchange,提问作者Jeanluca Scaljeri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 19:25:12