sslstrictsnivhostcheck仅控制tls握手时sni主机名是否严格匹配virtualhost的servername或serveralias,不校验证书域名、有效性或签名;只在有sni但无匹配虚拟主机时终止握手,无sni时仍走默认站点。

SSLStrictSNIVHostCheck 并不执行“证书域名匹配”校验,它只控制 TLS 握手阶段的 SNI 主机名是否必须严格匹配某个 VirtualHost 的 ServerName 或 ServerAlias。它完全不检查证书内容(如 CN 或 SAN 是否与请求域名一致),也不验证证书有效性、过期时间或签名可信度。
它真正管什么?
该指令仅在客户端发送了 SNI 扩展但所填 hostname 没有对应启用 SSL 的 VirtualHost 时起作用:
- 若客户端发 SNI =
api.example.com,而所有<virtualhost></virtualhost>中都没有ServerName api.example.com或ServerAlias api.example.com,且SSLStrictSNIVHostCheck on,Apache 直接终止 TLS 握手(浏览器报 ERR_SSL_PROTOCOL_ERROR) - 若客户端根本没发 SNI(如老 Android、IE6/7/8),该指令完全不生效,请求仍会落到第一个加载的 HTTPS VirtualHost
- 即使证书里写的是
www.other.com,只要 ServerName 匹配 SNI,连接就能建立——证书域名是否匹配,由浏览器或客户端决定,Apache 不干预
想强制证书域名匹配,得靠客户端
证书中域名(CN 或 SAN)与请求 URL 的匹配,是 TLS 协议层和客户端(浏览器、curl、Java 等)的责任,Apache 本身不执行这项检查。你无法通过 SSLStrictSNIVHostCheck 或任何 mod_ssl 指令让 Apache 拒绝“证书域名不匹配”的连接。
唯一能影响这一行为的方式是:确保你为每个域名配置了正确证书,并依赖客户端自身校验逻辑。例如:
Apache Superset 是一个广泛采用的开源 BI 平台,用于 SQL 探索、图表构建和仪表板交付。当代理需要查询仓库数据、组装仪表板或使用成熟的分析界面解释指标而不是临时笔记本代码时,此技能非常有用。
- 浏览器访问
https://shop.example.com,收到的证书若 SAN 中不含shop.example.com,会直接显示“您的连接不是私密连接” - 用
curl -v https://shop.example.com会报Certificate verification failed(除非加-k)
如果你真要服务端干预证书匹配,只能换思路
Apache 不提供证书域名比对能力,但可通过以下方式间接实现部分效果:
- 用 RewriteRule + %{HTTP_HOST} 拦截不匹配请求:在 VirtualHost 内判断请求 Host 是否与当前站点预期一致,不一致则返回 403 或重定向(注意:这是 HTTP 层,TLS 已完成,无法阻止证书警告)
-
反向代理场景下用 SSLProxyCheckPeerName:当 Apache 作为代理访问后端 HTTPS 服务时,可设
SSLProxyCheckPeerName on强制校验后端证书中的 SAN 是否匹配 ProxyPass 目标域名 - 用自定义 Lua 脚本(需 mod_lua):在 SSL 握手后、HTTP 请求解析前读取证书信息(复杂、非标准、不推荐生产使用)
正确配置 SSLStrictSNIVHostCheck 的位置和写法
它必须出现在启用 SSL 的上下文中,且仅两个合法位置:
- 在某个
<virtualhost></virtualhost>块内部(推荐,精准控制) - 在全局段中,包裹在
<ifmodule ssl_module></ifmodule>内(Apache ≥2.4.10 支持)
错误写法示例(会导致启动失败或被忽略):
- 写在
httpd.conf顶层(报错:SSLSNIVHostCheck not allowed here) - 写在
.htaccess中(mod_ssl 完全不读取,静默忽略) - 写在
<virtualhost></virtualhost>里(无 SSL 上下文,无效)










