You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Apache同一IP端口(SNI)多SSL虚拟主机证书配置异常求助

排查Apache SNI多域名SSL配置异常问题

我来帮你捋捋这个SNI配置的坑——这种情况我在运维中碰到好多次了,大多是配置细节没做到位或者Apache的SNI支持有遗漏。咱们一步步排查:

第一步:先确认Apache的SNI支持是否正常

别忙活半天发现基础条件不满足:

  • 运行 apache2ctl -V(CentOS/RHEL系统用httpd -V),看输出里有没有--enable-ssl--enable-sni。Apache 2.2.12及以后的版本默认开启SNI,但有些自定义编译的版本可能没开。
  • 确认mod_ssl模块已经加载:执行 apache2ctl -M | grep ssl,能看到ssl_module (shared)就没问题,没看到的话要先加载这个模块(比如Ubuntu/Debian用a2enmod ssl,然后重启Apache)。

第二步:检查虚拟主机配置的顺序和匹配规则

这是最常见的问题——Apache会把第一个加载的SSL虚拟主机作为默认,就算请求的是其他域名,只要SNI匹配失败就会用它的证书:

  • 每个域名的<VirtualHost *:443>必须明确指定ServerNameServerAlias,不能含糊。比如:
<VirtualHost *:443>
    ServerName site1.com
    ServerAlias www.site1.com
    SSLCertificateFile /etc/ssl/certs/site1.crt
    SSLCertificateKeyFile /etc/ssl/private/site1.key
    DocumentRoot /var/www/site1
    # 其他常规配置(比如日志、权限等)
</VirtualHost>

<VirtualHost *:443>
    ServerName site2.com
    ServerAlias www.site2.com
    SSLCertificateFile /etc/ssl/certs/site2.crt
    SSLCertificateKeyFile /etc/ssl/private/site2.key
    DocumentRoot /var/www/site2
    # 其他常规配置
</VirtualHost>
  • 注意配置文件的加载顺序:如果你的site1配置文件命名是000-site1.conf(比如在/etc/apache2/sites-available/目录下),它会比001-site2.conf先加载,所以会成为默认。但正常情况下,SNI应该能根据请求的ServerName匹配到对应的虚拟主机——如果site2匹配不上,先检查ServerName是不是和请求的域名完全一致(比如有没有漏写www,或者大小写问题)。

第三步:解决日志显示默认域名的问题

访问site2但日志显示site1,说明Apache根本没识别到site2的请求:

  • 先确认用户访问的域名没有拼写错误,有没有带非标准端口(如果用了其他端口,要对应配置<VirtualHost *:xxxx>的SSL虚拟主机)。
  • 开启SSL调试日志,在每个虚拟主机里加一行:
SSLLogLevel debug

重启Apache后访问site2,查看SSL错误日志(通常在/var/log/apache2/ssl_error.log),里面会详细记录SNI协商过程:比如客户端有没有发送Server Name指示,Apache最终匹配到了哪个虚拟主机,一眼就能看出问题所在。

第四步:排查site2被重定向到site1的问题

这种情况大概率是重定向规则配置错了:

  • 检查全局配置或者site2的虚拟主机里有没有写死的重定向,比如Redirect permanent / https://site1.com/,不小心放到了错误的位置。
  • 看看site2的网站根目录下有没有.htaccess文件,里面有没有重定向到site1的规则(比如RewriteRule ^(.*)$ https://site1.com/$1 [R=301,L])。
  • 确认没开启UseCanonicalName On,这个配置会强制用虚拟主机的ServerName作为规范域名,可能导致意外重定向。

第五步:验证证书配置并测试SNI请求

  • 确保site2的证书是完整的:如果证书需要中间链,要么用SSLCertificateChainFile指定中间证书,要么把中间证书合并到主证书文件里。证书链不完整有时候也会导致SNI匹配异常。
  • openssl命令直接测试SNI请求,模拟客户端的行为:
openssl s_client -connect 你的服务器IP:443 -servername site2.com

看返回的证书信息是不是site2的。如果这里返回的是site1的证书,那肯定是Apache配置的问题;如果返回的是site2的,那可能是客户端浏览器缓存或者DNS解析的问题(比如用户本地DNS还指向旧配置)。

最后:别忘了验证配置和重启

每次修改配置后,先运行 apache2ctl configtest(或httpd configtest)检查语法错误,没问题了再重启Apache。很多时候配置本身没错,但没重启导致不生效。

另外,如果你的服务器在反向代理(比如Cloudflare、Nginx)后面,要确保代理服务器传递了正确的Host头和SNI信息——比如Nginx反向代理要加proxy_set_header Host $host;,并且代理的SSL配置要开启SNI支持。


内容的提问来源于stack exchange,提问作者Isabella Holmes

火山引擎 最新活动