因为宝塔默认未启用SNI或配置不当,Nginx在单IP多域名HTTPS下仅返回首个server块证书,导致证书错配;需确保各站点独立ssl_certificate路径、listen 443 ssl http2;、无全局证书,并对旧客户端设default_server。

宝塔面板里添加多个站点时,为什么只有一张SSL证书生效?
因为默认情况下,宝塔在单IP上为多个域名配置HTTPS时,如果没启用SNI(Server Name Indication),Nginx 会按配置顺序返回第一个匹配的 ssl_certificate,其余站点访问时浏览器可能报 ERR_SSL_VERSION_OR_CIPHER_MISMATCH 或直接显示第一个站点的证书,导致证书错配。
这不是宝塔的bug,而是Nginx+OpenSSL在旧版本中对SNI支持不完整,或宝塔未自动开启SNI协商所致。关键点在于:SNI必须由客户端(浏览器)发起、服务端(Nginx)明确启用、且OpenSSL版本 ≥ 1.0.2(宝塔7.9+默认满足)。
确认Nginx是否已启用SNI并正确加载多证书
进入宝塔 → 网站 → 对应站点 → SSL → 勾选「强制HTTPS」后,务必点击「其他设置」→「配置修改」,检查以下三处:
-
listen 443 ssl http2;行必须存在,且不能写成listen 443 ssl;(缺http2不影响SNI,但常见配置模板漏掉会导致部分老客户端握手失败) - 每个
server块内必须有独立的ssl_certificate和ssl_certificate_key,路径不能共用同一组文件 - 确保没有全局
ssl_certificate写在http块里——这种写法会让所有 server 共享一张证书,覆盖SNI行为
示例正确片段:
server {
listen 443 ssl http2;
server_name site-a.com;
ssl_certificate /www/wwwroot/site-a.com/fullchain.pem;
ssl_certificate_key /www/wwwroot/site-a.com/privkey.pem;
# …
}
server {
listen 443 ssl http2;
server_name site-b.net;
ssl_certificate /www/wwwroot/site-b.net/fullchain.pem;
ssl_certificate_key /www/wwwroot/site-b.net/privkey.pem;
# …
}使用Let’s Encrypt申请多域名证书 vs 单域名证书?
不要混用:一个站点用泛域名证书,另一个用单域名证书,看似可行,但宝塔在「SSL→申请」界面中,若勾选了「通配符」,它会自动把 *.example.com 和 example.com 合并在一张证书里;而 site-a.com 和 site-b.net 属于不同根域,无法放进同一张Let’s Encrypt证书(ACME协议限制最多100个域名,但必须属同一主控账户且验证通过,跨主域需分别申请)。
实操建议:
- 每个站点单独点「申请」,用「DNS验证」或「文件验证」均可,宝塔会自动为该站点生成专属证书
- 避免手动复制证书文件到其他站点目录——路径硬编码进Nginx配置后,更新证书时不会同步,极易过期
- 如需统一管理,可改用「SSL→证书管理→导入」,但导入后仍需逐个绑定到对应站点,不能批量关联
Chrome/Firefox能访问,但微信内置浏览器或安卓4.4 WebView打不开HTTPS?
这是典型的SNI兼容性问题:微信X5内核和旧版Android WebView使用 OpenSSL 1.0.1e 或更早,不支持SNI扩展。它们在TLS握手时不会发送 server_name 字段,Nginx就只能返回默认server块的证书(通常是配置文件里第一个 server)。
解决思路不是“让旧客户端升级”,而是调整Nginx默认行为:
- 在宝塔「网站→设置→配置修改」中,把你要设为“兜底”的站点(比如主品牌站)移到配置文件最上方,并确保其
server_name包含_或留空(server_name _;) - 或者显式定义默认server:
server { listen 443 ssl http2 default_server; ... },并指向一个有效证书 - 注意:宝塔不提供图形化设
default_server的入口,必须手动编辑配置,在对应server块的listen行末尾加default_server
这个细节常被忽略——多数人只关注“能不能用”,却没意识到“谁在用”决定了默认证书该给谁。


















