最近准备给博客上CDN,因为博客本身是部署在阿里的ESC上,于是选择了阿里的CDN服务。因为博客已经全站Https了,所以在配置CDN的时候也选择了上传证书,进行了各种配置。只是当配置完成后,发现域名无法访问,网站打不开了。

当时选择的加速的域名是 www.shangyexin.com ,源站是ESC的IP,配置的回源host是加速域名。

这里解释一下几个概念,摘自阿里云官方文档。
源站: 源站决定了回源时,请求到哪个IP
回源host:回源host决定回源请求访问到该IP上的哪个站点

例子1:源站是域名
源站为 www.a.com 回源host为 www.b.com
那么实际回源是请求到 www.a.com 解析到的IP,对应的主机上的站点 www.b.com

例子2:源站是IP
源站为1.1.1.1 回源host为www.b.com
那么实际回源的是1.1.1.1对应的主机上的 站点www.b.com

自定义在CDN节点回源时所需访问的具体域名(如果您一个IP源站绑定了多个域名/站点的时候,就需设置回源Host 指定回到具体哪个域名,否则会回源失败)。
回源host 为可选配置项,默认值为:
– 如果源站是 IP类型,回源host默认加速域名。
– 如果源站是 OSS源站类型,回源host默认是源站域名。
– 可选项分别是:加速域名、源站域名、自定义域名。

注意:目前不支持sni 回源。

别看最后一句不起眼的:目前不支持sni 回源。
我后面所有的折腾其实就是因为没有意识到这句话的含义,想着这个应该和我没关系。

好了,我们继续。
这里画了一个简单的流程图说明一下我对阿里这个配置的理解。
CDN流程:
CDN流程

对应名词在图中的位置:
对应名词位置

这个流程用文字再说一遍就是,当我想要访问加速的域名 www.shangyexin.com 的时候,我们会被解析到设置的CNAME域名上,也就是阿里的CDN服务器上,加入这时候CDN服务器上没有我们想要的资源,这时候他会去我们的源站上取,但是怎么知道源站在哪呢?当然是我们配置的啦!这时候如果源站配置的是IP,嗯,好了,CDN服务器直奔这个IP;如果我们源站配置的是域名的话,嗯,这个也简单,先解析出这个域名的IP是啥,然后我们再直奔这个IP。就这样,CDN服务器找到了源站所在服务器的IP,但是,这时候问题又来了,假如这个IP上有不止一个域名,服务器如何知道你想要哪个域名的资源呢?当然你CDN服务器去取时就要告诉这个它,我要的是 www.shangyexin.com 这个域名的资源,这就是是回源host的意义。

至于源站端口设置,就是告诉CDN服务器,你从80还是443端口来取数据,一般http对应80端口,https对应443端口。

而https设置决定了CDN服务器和用户之间是用http还是https进行数据传输,如果不设置的默认用http,设置的话就是https。

所以回到最初的起点,我本来的初衷就是阿里云CDN开启https加速。而且用户和CDN服务器之间的交互是阿里的事,我也上传了证书,所以问题肯定是出在了CDN服务器和源站交互之间。
因为我无论是通过80还是443端口访问源站,均会失败!查找问题的原因很辛苦,耗费了我很多时间,防火墙啊各种等等,这里暂且不表。我只想说最后的原因。
这里的原因还不一样。

通过80端口访问失败的原因是:

wordpress设置了全站https,所有http访问会进行301跳转。

301跳转
所以CDN服务器没办法通过80端口获取到源站的数据。

通过443端口访问失败的原因是:

目前不支持sni 回源。

是的,就是前面那个不起眼的注意。

究竟为何导致服务器屡屡访问失败,是人性的扭曲?还是道德的沦丧?欢迎收看今天的《走近科学》之SNI。

下面一段摘自网络:

早期的SSLv2根据经典的公钥基础设施PKI(Public Key Infrastructure)设计,它默认认为:一台服务器(或者说一个IP)只会提供一个服务,所以在SSL握手时,服务器端可以确信客户端申请的是哪张证书。
但是让人万万没有想到的是,虚拟主机大力发展起来了,这就造成了一个IP会对应多个域名的情况。解决办法有一些,例如申请泛域名证书,对所有*.yourdomain.com的域名都可以认证,但如果你还有一个yourdomain.net的域名,那就不行了。
在HTTP协议中,请求的域名作为主机头(Host)放在HTTP Header中,所以服务器端知道应该把请求引向哪个域名,但是早期的SSL做不到这一点,因为在SSL握手的过程中,根本不会有Host的信息,所以服务器端通常返回的是配置中的第一个可beian用证书。因而一些较老的环境,可能会产生多域名分别配好了证书,但返回的始终是同一个。
既然问题的原因是在SSL握手时缺少主机头信息,那么补上就是了。
SNI(Server Name Indication)定义在RFC 4366,是一项用于改善SSL/TLS的技术,在SSLv3/TLSv1中被启用。它允许客户端在发起SSL握手请求时(具体说来,是客户端发出SSL请求中的ClientHello阶段),就提交请求的Host信息,使得服务器能够切换到正确的域并返回相应的证书。

所以CDN服务器访问源站时,因为没有不支持SNI,而我的服务器也正好是通过LANMP配置的,上面跑了不止一个域名,而且另外几个域名也配置了https,导致CDN服务器一直无法访问源站,取到想要的信息,所以就出现了开头的502错误。

最后我想说的是如果我想在阿里云CDN开启https加速,唯一可行的做法是CDN与源站直接采用http协议,且不说我本来就想实现全程https加密,而且如果这样配置的话,还需要将wordpress配置为同时支持http和https,颇为麻烦,所以只能就此作罢,因为暂时实在不想折腾了。

2018/11/11更新
现在阿里已经支持sni配置了,不过不是默认的,需要提交工单。
一个主机配置了多个https域名的用户,提交工单申请开通sni回源即可。

阿里云CDN开启https加速后出现502无法访问原因
Tagged on:

2 thoughts on “阿里云CDN开启https加速后出现502无法访问原因

  • 2019年5月23日 at 下午5:40
    Permalink

    其实直接在 “回源HOST”的配置里面选择自定义域名不就可以解决443回源的问题了吗?
    还是我的理解上有问题,请教一下。

    Reply
    • 2019年5月31日 at 下午2:19
      Permalink

      没用的,一样问题,不开启sni即便是回源到自定域名也是502,发了工单开了sni现在正常了。
      还有个坑,这个全站加速https要生效的话,必须自己服务器就安装好有证书,空证书或者ssloff或者用别的域名的证书都不行,等于是源站和cdn都要有证书才可以。自己服务器装证书每年还要自己更新。

      Reply

发表评论

电子邮件地址不会被公开。 必填项已用*标注