发布时间:2026-09-24 05:00 更新时间:2026-09-24 05:00 阅读量:0
手上有一台服务器、几个域名,却给每个域名单独申请一张证书,续期时挨个续、部署时挨个传,时间一长总有一张忘了换。更省事的做法是申请一张包含多个域名的证书,用同一份证书文件同时服务多个站点。但很多人第一次这么配就撞上浏览器报错或 Nginx 启动失败,问题通常出在两处:证书的 SAN 列表没写全,或者 server_name 和证书覆盖范围对不上。这篇把这两件事讲透,顺带说清新增域名后该先签发还是先 reload。
早年的 SSL 证书靠 Common Name(CN)标识域名,一张证书只能写一个名字,多域名只能靠通配符。现在主流浏览器和客户端都按 Subject Alternative Name(SAN) 扩展来判断证书是否匹配,CN 字段基本只剩展示作用。也就是说,证书能不能用于 a.com 和 b.com,只看 SAN 列表里有没有这两个名字,跟 CN 写什么关系不大。
用 Let's Encrypt 的 certbot 举例,想在一张证书里放多个域名,签发时把域名都列上即可:
certbot certonly --webroot -w /www/wwwroot/a.com \
-d a.com -d www.a.com -d b.com -d www.b.com \
--email you@example.com --agree-tos --no-eff-email签发完成后,可以用 openssl 直接查看这张证书的 SAN 列表,确认域名是否都在:
openssl x509 -in /etc/letsencrypt/live/a.com/fullchain.pem \
-noout -text | grep -A1 "Subject Alternative Name"输出里会列出 DNS 名称,凡是没出现在这个列表里的域名,用它访问 HTTPS 就会报证书错误。需要提醒的是,免费证书对单张证书包含的域名数量通常有限制,具体上限以签发机构官方文档为准;域名特别多时,可以拆成几张证书分别管理。
Nginx 处理 HTTPS 请求的流程是:先完成 TLS 握手(这一步用到证书),再根据 HTTP 请求头里的 Host 去匹配 server_name。证书选哪一张,取决于请求里携带的 SNI 信息以及该端口上哪个 server 块带 default_server 标记。这就带来两类典型故障。
第一类是浏览器直接拦下,页面出现“您的连接不是私密连接”,提示证书名称与网站名称不符。这属于证书 SAN 没覆盖当前域名,跟 Nginx 配置无关,需要重新签发证书。
第二类是证书没问题但访问串站:浏览器地址栏是 b.com,打开的却是 a.com 的页面。原因是 b.com 没有对应的 server 块,或者有 server 块但没配 SSL 证书,请求被兜底到了默认站点。多站点共用 443 端口时,建议给默认站点加 default_server 明确兜底,其他站点各自写清 server_name 与证书路径:
server {
listen 443 ssl default_server;
server_name _;
ssl_certificate /etc/letsencrypt/live/a.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/a.com/privkey.pem;
return 444;
}
server {
listen 443 ssl;
server_name b.com www.b.com;
ssl_certificate /etc/letsencrypt/live/a.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/a.com/privkey.pem;
root /www/wwwroot/b.com;
index index.php index.html;
}
注意上面两个 server 块指向的是同一份证书文件,只要 b.com 在 SAN 列表里,这样写就是合法的。另外别忘了 80 端口的 server 块,把 HTTP 请求 301 到 HTTPS,否则用户从 http 进来仍会落到默认站点。如果同时用了 CDN,回源 Host 和回源协议也要和这里保持一致,否则 SNI 传错同样会命中错误的 server 块。
给已有证书加新域名,不能只改 Nginx 配置。证书文件里没有新域名,配置写得再对,握手阶段照样报错。稳妥的顺序是:先重新签发让 SAN 包含新域名,再改 Nginx 配置并 reload,最后验证。签发命令和上面一样,把新域名补进 -d 列表;certbot 会复用原有证书目录并覆盖文件。
改配置时逐个检查这几处:新域名的 server_name 是否写全了带 www 和不带 www 两种;ssl_certificate 与 ssl_certificate_key 路径是否指向更新后的文件;该站点是否监听在 443 且带了 ssl 参数;证书文件权限是否让 Nginx 工作进程可读。改完后先做语法检查再 reload,避免配置错误导致服务中断:
nginx -t
nginx -s reload验证环节不要只看浏览器,缓存和 CDN 都可能让你看到旧结果。用 curl 指定域名直连服务器比较可靠:
curl -I --resolve b.com:443:你的服务器IP https://b.com/
openssl s_client -connect b.com:443 -servername b.com < /dev/null 2>/dev/null | openssl x509 -noout -subject -ext subjectAltName几条容易踩的坑:一是只签了裸域忘了 www,或者反过来,SAN 和 server_name 要成对出现;二是证书更新了但 Nginx 没 reload,进程仍加载着旧证书;三是把新域名解析指到了别的机器上,排查半天其实是解析问题;四是宝塔面板这类工具会接管证书路径,手动替换文件后要注意面板里显示的证书信息是否同步,具体行为以面板实际版本为准。
小结一下:多域名共用证书的核心就一句话,证书 SAN 决定能服务哪些域名,server_name 决定这些域名各自路由到哪个站点,两者必须一一对应。新增域名时记住“先签发、后改配置、再 reload、最后用 curl 验证”这个顺序,基本可以绕开绝大多数证书不匹配的报错。域名数量多了以后,建议把签发命令和 reload 写进续期后的钩子里,让证书更新自动生效,省得每次手动补一遍。
| 📑 | 📅 |
|---|---|
| 网站切HTTPS后百度统计没数据:referrer、混合内容与代码位置排查 | 2026-09-23 |
| 宝塔面板SSL证书手动替换:证书链、私钥校验与reload排查 | 2026-09-23 |
| WordPress后台自动更新失败:权限、FTP常量与目录属主逐项定位 | 2026-09-23 |
| 宝塔新建站点403 Forbidden:权限位、属主与open_basedir三重排查 | 2026-09-23 |
| 网站备案主体与接入商变更:新增接入、注销重备顺序与访问影响 | 2026-09-23 |
| 网站被CDN缓存住旧页面:缓存键、边缘刷新与源站头冲突排查 | 2026-09-24 |
| 宝塔面板磁盘挂载与网站目录迁移:/www 换盘后的路径、权限与面板数据同步 | 2026-09-24 |
| WordPress改文章前台不变:三层缓存清理顺序与验证 | 2026-09-24 |
| WordPress数据库连不上但宝塔显示正常:主机名与socket排查 | 2026-09-24 |
| 宝塔面板Nginx伪静态改了不生效:规则文件位置与重载验证 | 2026-09-24 |