在典型的CDN架构中,当源站使用单一IP地址托管多个HTTPS虚拟站点时,回源链路的加密握手阶段必须明确告知源站究竟要访问哪一个站点。阿里云CDN默认回源SNI取值为加速域名,这与源站上配置的真实站点域名往往不同,导致源站Web服务器返回了错误的证书。要解决源站为多个HTTPS站点时的回源异常,核心在于正确理解SNI机制并合理配置阿里云CDN的回源SNI参数。

SNI在多HTTPS源站场景下的底层原理
SNI(Server Name Indication)是TLS协议的扩展字段,允许客户端在握手初期就声明自己要连接的主机名。对于源站服务器而言,如果它在同一个IP的443端口上通过Nginx的server_name指令配置了多个HTTPS站点,那么若不依靠SNI,服务器无从得知应该返回哪张SSL证书。传统HTTP通过Host头区分站点,但TLS握手发生在HTTP请求之前,因此只能靠SNI携带域名。
当阿里云CDN节点向源站发起HTTPS回源时,它会先建立TCP连接再发起Client Hello。如果CDN没有设置回源SNI,或设置的SNI是加速域名(例如cdn.ippipp.com),而源站上只配置了www.ipipp.com的证书,源站就会因为匹配不到对应server块而返回默认证书或直接断开连接。这就表现为浏览器访问CDN加速域名时出现证书域名不匹配,或是CDN回源日志中大量记录502或SSL握手错误。
因此,在多HTTPS站点共用源站IP的架构里,必须让CDN在回源时把真实源站站点域名放进SNI。阿里云CDN支持回源SNI自定义,使得Client Hello中的SNI字段可以是与源站证书完全对应的域名,从而让源站Nginx依据SNI返回正确的证书完成握手。这一机制是虚拟主机HTTPS化的基础,也是混合站点托管时不可回避的配置点。
阿里云CDN回源SNI的控制台配置步骤
登录阿里云CDN控制台后,进入指定加速域名的配置页,在左侧导航栏选择“回源配置”,找到“回源SNI”功能项。默认状态下回源SNI是关闭的,系统采用加速域名作为SNI。点击开启后,可以手动填写希望携带到源站的SNI值,通常应填写源站上该站点对应的真实域名,如www.ipipp.com,而非CDN加速域名。
配置完成后,建议通过curl模拟回源请求来验证。可以在源站抓包观察Client Hello中的SNI扩展,或使用openssl s_client命令指定-servername参数测试源站证书返回情况。若控制台填写的SNI与源站Nginx中某个server块的server_name及证书一致,TLS握手即可顺利通过。需要注意,回源协议必须选择HTTPS,SNI才会在回源TLS握手时生效;若回源协议为HTTP则不存在该问题。
另外,当源站存在多个不同证书站点,而CDN只有一个加速域名时,不能指望同一个加速域名回源到不同SNI。此时应当为每个需要加速的源站站点分别创建CDN加速域名,并各自配置对应的回源SNI。例如a.ipipp.com和b.ipipp.com分别对应两个源站站点,它们各自的回源SNI应分别填写a.ipipp.com与b.ipipp.com,这样才能在共用源站IP时互不干扰。
源站Nginx虚拟主机与证书匹配实例
下面给出一个典型的Nginx多HTTPS站点配置片段,展示源站如何依赖SNI返回不同证书。假设源站同时托管www.ipipp.com与api.ipipp.com,两者证书不同但都监听443端口。
server {
listen 443 ssl;
server_name www.ipipp.com;
ssl_certificate /etc/nginx/cert/www.pem;
ssl_certificate_key /etc/nginx/cert/www.key;
location / {
proxy_pass http://127.0.0.1:8080;
}
}
server {
listen 443 ssl;
server_name api.ipipp.com;
ssl_certificate /etc/nginx/cert/api.pem;
ssl_certificate_key /etc/nginx/cert/api.key;
location / {
proxy_pass http://127.0.0.1:8081;
}
}
上述配置中,Nginx会根据TLS握手阶段的SNI决定进入哪一个server块。如果CDN回源SNI填写为www.ipipp.com,则命中第一个块并返回www证书;若错误地填写为加速域名,而Nginx没有对应server_name的块,就会走默认首个块或返回不匹配警告。因此源站配置与CDN回源SNI必须严格对应。
在排错时,可先在源站执行nginx -t确认配置语法,再用如下命令模拟带SNI的客户端连接:
openssl s_client -connect 127.0.0.1:443 -servername www.ipipp.com
若输出中证书主题为www.ipipp.com,说明源站按SNI路由正常。随后在阿里云CDN开启回源SNI并填入同样域名,回源链路即可打通。对于使用了CDN层级缓存且源站频繁增删站点的团队,建议将SNI配置纳入基础设施即代码流程,避免人为遗漏导致回源大面积证书错误。
常见故障与排查建议
第一类故障是回源SNI未开启,CDN使用加速域名作为SNI,源站无对应虚拟主机,返回默认证书引发浏览器不信任。此类问题在浏览器直接访问CDN域名时表现为证书域名不符,但在CDN回源日志中仅能看到SSL握手失败。解决办法即开启回源SNI并填入源站真实域名。
第二类故障是SNI填错,比如源站站点已迁移到new.ipipp.com但CDN仍填旧名,源站Nginx匹配不到server_name便会使用默认块,若默认块未配置HTTPS则返回空响应。排查时应比对CDN回源SNI值与源站nginx.conf中server_name,并保证证书文件路径有效。
第三类故障涉及源站为负载均衡或WAF设备,这些中间件本身也依赖SNI做转发。此时不仅CDN要填对SNI,中间层也要能将SNI透传至后端真实站点。建议在架构图上标出每一跳的TLS终止位置,明确哪一层需要校验证书、哪一层仅需透传SNI,才能从根本上解决多HTTPS源站回源复杂场景下的连通性问题。