Easy HTTPs 安全证书, SSL安全证书, Let's Encrypt, Let's Encrypt怎么使用, 如何从Let's Encrypt获得证书 Easy HTTPs 安全证书, SSL安全证书, Let's Encrypt, Let's Encrypt怎么使用, 如何从Let's Encrypt获得证书 images/s3eshare.jpg

前言

HTTPS是互联网发展的必然趋势,目前各知名网站均已加入HTTPS行列。

Let's encrypt签发的证书已被个浏览器认可,通过Let's encrypt证书实现HTTPS已然是行业发展之必然。然而,Let's encrypt证书签发过程操作复杂、配置繁琐、90天有效期到期后要重新申请延时,这些过程给很多网站实现HTTPS带来了不便。

上海哲涛科技推出的Easy HTTPs服务,完美解决了以上问题,只需要填写域名即可一键式获得Let's encrypt证书,一键式安装部署,90天到期后Easy HTTPs会自动下载更新证书。

更多详情可登录上海哲涛科技官网查看:https://easy.zhetao.com


点击图片可快速申请
Let's encrypt证书

Bug 复现
复现这个 Bug 需要同时满足以下几个条件:
使用 Nginx 特定版本(1.9.15~1.10.x)部署 HTTP/2 服务;
使用特定的 HTTP/2 客户端,例如 OSX/iOS Safari、iOS 客户端、OkHttp 等(Chrome 没问题,MS IE/Edge 据说也有问题,但我没测试);
只有 POST 场景才有问题(也就是说必须存在 DATA 帧);
需要在建立 HTTP/2 连接后立即 POST(例如打开表单页面,再断网重连或重启 Nginx,不刷新页面直接提交);
我用 OSX 10.11.6 自带的 Safari 9.1.2 可以稳定复现这个 Bug。触发 Bug 后,Safari 会提示无法连接到服务器。如下图:
nginx http/2 post bug
如果事先开启了 Nginx 的 debug 日志,可以找到类似这样的记录:
client sent stream with data before settings were acknowledged while processing HTTP/2 connection
产生原因
为了减少网络时延,不少 HTTP/2 客户端会在建立 HTTP/2 连接时同时发送其它帧,包括用来 POST 数据的 DATA 帧。而 Nginx 在客户端接受到 SETTINGS 帧之前,一直将初始窗口大小(initial window size)设置为 0。也就是说,客户端收到 SETTINGS 帧之前发送的 DATA 帧,会被 Nginx 以 REFUSED_STREAM 帧拒绝。而部分客户端在收到 REFUSED_STREAM 帧之后,会提示连接失败,而不是发起重试,这就是产生 Bug 的原因。
那么,Nginx 这个逻辑合理吗,客户端提前发送 DATA 帧符合 HTTP/2 协议规定吗?HTTP/2 协议中的「HTTP/2 Connection Preface」章节有以下描述:
To avoid unnecessary latency, clients are permitted to send additional frames to the server immediately after sending the client connection preface, without waiting to receive the server connection preface. It is important to note, however, that the server connection preface SETTINGS frame might include parameters that necessarily alter how a client is expected to communicate with the server. Upon receiving the SETTINGS frame, the client is expected to honor any parameters established. In some configurations, it is possible for the server to transmit SETTINGS before the client sends additional frames, providing an opportunity to avoid this issue. via
出于减少时延的目的,HTTP/2 协议允许客户端在发送连接序言(connection preface)之后,立即发送其它帧,无需等待来自服务端的 SETTTINGS 帧。
而 Nginx 能够正常处理客户端提前发送的其它帧,唯独 DATA 帧不行。因为客户端尚未收到 SETTINGS 帧之前,Nginx 将初始窗口大小设置为 0。
那么 Nginx 的初始窗口大小应该设置为多少才合理呢?以下这段内容来自于 HTTP/2 协议的「Initial Flow-Control Window Size」章节:
Prior to receiving a SETTINGS frame that sets a value for SETTINGS_INITIAL_WINDOW_SIZE, an endpoint can only use the default initial window size when sending flow-controlled frames. Similarly, the connection flow-control window is set to the default initial window size until a WINDOW_UPDATE frame is received. via
也就是说 Nginx 应该将默认的初始窗口大小设置为 64KB。
如何解决
我猜测 Nginx 这么做是为了减少被攻击的风险,但无论如何这不符合 HTTP/2 协议规定,也造成了特定场景下 POST 请求不可用。Nginx 在 1.11.0 中解决了这一问题,并增加了一个配置项:
Syntax: http2_body_preread_size size; 
Default: http2_body_preread_size 64k; 
Context: http, server 
This directive appeared in version 1.11.0. 

Sets the size of the buffer per each request in which the request body may be saved before it is started to be processed. via
http2_body_preread_size 用来定义 Nginx 在客户端收到 SETTINGS 帧之前可以接受多大的 DATA 帧,默认为 64KB。如果将这个值设置为 0,那就跟之前版本的 Nginx 变得一样。
需要特别注意的是,这个 Bug 由 Nginx 1.9.15 引入,而官方表示修复方案不会被移植到当前稳定版中,也就是对于 Nginx 1.9.15~1.10.x,这个问题将始终存在。对此,Nginx 有如下解释:
We don't backport features to the stable branch (that's what we call stable, no enhancements). It receives only critical bug fixes. If you use such new, very complicated and actively developing protocol as HTTP/2 then it's naturally that you have to stay with the mainline branch. via
简而言之,Nginx 认为 HTTP/2 功能本身尚未稳定,要部署 HTTP/2 就应该使用 Nginx 主线版,而不是稳定版。从更新日志来看,Nginx 最近几个主线版本也一直在修复与 HTTP/2 有关的问题,印证了这一说法。
HTTP/2 是一项年轻的技术,也是 HTTP 历史上最大的一次革新。在实践 HTTP/2 过程中,一定要有时刻踩坑的心理准备,更要时刻关注 HTTP/2 协议和实现者的最新动态。对于重要业务,一定要在充分测试和评估之后再推进 HTTP/2。

哲涛SEP服务器事件的管理平台、服务器监控软件
ico、网站favicon图标生成工具
苹果ios app图标、logo生成工具
安卓 app 图标、logo生成工具
苹果app 倍数图标缩放
自定图标缩放、转换、jpg/png互转
邮箱帐号:
发验证码
全名:
密码:
重复密码:
《阅读 Easy HTTPs 服务条款》《阅读 Let's Encrypt 服务条款》
提 交 注 册
X
邮箱帐号:
密码:
登 录
还没有帐号,点击注册
忘记密码?点击此找回!
X
帐号:
提交找回密码
X
X
确 定
X