今天在访问自己公司网站的时候,发现在firefox浏览器经常会出现如下错误:
连接 www.icvio.com:80 时发生错误。 对等端报告其遇到一个内部错误。 错误代码: SSL_ERROR_INTERNAL_ERROR_ALERT
这个错误目前测试只是在firefox浏览器出现,强制刷新,有时候又显示正常。
百思不得解,我没有使用SSL或HTTPS啊!
仔细研究发现浏览器发出的请求header里面有一个奇怪的代码:
Alt-Used: www.icvio.com:443
在服务器端的响应header里面(正常的显示的资源):
Alt-Svc 'h2=":443"; ma=60';
还有一条 CF-Cache-Status: HIT 的记录--- 这个很像clouldflare的节点返回记录
原因分析:
由于使用了的是百度云加速,发现cdn节点是美国IP,也就是clouldflare的节点,CF是默认支持SSL的,它免费送SSL,但百度云加速免费版本是不支持的。也就是说是和百度与合作的CF的服务器配置问题。
解决办法:
如果网站只是国内访问加速,那就无所谓了。如果有国外客户,那只能不用加速,或者国外IP使用另外的ip访问,不用百度云加速。完善的解决方案暂无,待定
我想随着百度云和CLOUDFLARE合作的深入,他们应很快会发现和解决这个问题的。等待吧!
科普一下,什么是Alt-Used?
大型 Web 系统经常会出现某个机房流量过大,需要尽快分流给其它机房这种场景。这时候依靠修改 DNS 解析有点力不从心:一方面由于 DNS 缓存的存在,新的解析不能马上生效;另一方面由于 HTTP 的 keep-alive 机制,已连接的浏览器还会继续使用之前解析到的 IP。
而 HTTP Alternative Services 可以很好地解决这个问题:服务端可以将自己的替代服务地址以协议规定的方式告诉浏览器,对于支持这个协议的浏览器来说,后续请求都会使用新地址。
协议规定的替代服务地址由三部分组成:协议、主机名和端口。也就是说一个网站的替代服务,可以部署在不同 IP、不同端口,甚至使用不同协议。
不同于使用 30x 状态码进行重定向分流,HTTP Alternative Services 只改变浏览器获取资源的网络方式,上层应用不会感觉到任何变化。以下是两个示例:
(截图一:Firefox 48.0.1)
在截图一中,浏览器通过 TLS 加密通道发起了 HTTP/2 请求,但上层拿到的 Request URL 仍然是 http:// 开头的地址,浏览器地址栏也仍然显示为 http://。
(截图二:Chrome 54.0.2835.0 canary)
在截图二中,浏览器将请求发送给了服务器 444 端口,而上层拿到的 Request URL 没有任何变化。
如何使用
对于 HTTP/1,协议新增了一个响应头部 Alt-Svc,用来指定替代服务地址,它的基本格式如下:
Alt-Svc: h2="alt.example.com:8000", h2=":443"; ma=2592000; persist=1
h2="alt.example.com:8000" 这部分内容定义了替代服务使用的协议、主机名和端口,其中主机名和端口可选。多个替代服务之间用英文逗号分隔。
ma 是 max-age 的缩写,单位为秒。显然,它表示浏览器在指定时间内,可以直接使用替代服务地址。
协议还规定,当网络发生变化时(例如从 WIFI 切到 3G),浏览器必须弃用当前所有替代服务,除非定义了 persist=1。
对于 HTTP/2,协议新增了一个 ALTSVC 帧,具体定义这里略过。
可以看到,对于 HTTP/1 来说,Alt-Svc 头部必须依附于首次响应,只有从第二个请求开始浏览器才会使用替代服务地址;而在 HTTP/2 中,ALTSVC 帧可以独立发送,浏览器从首次请求开始就能用上新地址。
目前只有 Firefox 完整支持了 HTTP Alternative Services 协议,以下是在 Firefox 中的测试。
首次访问指定地址时,服务端返回了一个 Alt-Svc 头部,指定了替代服务地址:
再次访问时,浏览器就会使用替代服务地址中指定的协议、主机名和端口发起请求。这一切对上层应用透明,但发往替代服务的请求头部,会多出一个 Alt-Used 字段: