摘要: 从 2015 年 5 月 14 日 HTTP/2 协议正式版的发布到现在已经快有一年了,越来越多的网站部署了 HTTP2,HTTP2 的广泛应用带来了更好的浏览体验,只要是 Modern 浏览器都支持,所以部署 HTTP2 并不会带来太多困扰。最近本人也在不断的研究HTTP2,发现相比http1.1确实是质的飞越
从 2015 年 5 月 14 日 HTTP/2 协议正式版的发布到现在已经快有一年了,越来越多的网站部署了 HTTP2,HTTP2 的广泛应用带来了更好的浏览体验,只要是 Modern 浏览器都支持,所以部署 HTTP2 并不会带来太多困扰。
虽然 h2 有 h2c (HTTP/2 Cleartext) 可以通过非加密通道传输,但是支持的浏览器初期还是比较少的,所以目前部署 h2 还是需要走加密的,不过由于 Let’s Encrypt 大力推行免费证书和证书的廉价化,部署 h2 的成本并不高。
HTTP 2.0即超文本传输协议 2.0,是下一代HTTP协议。是由互联网工程任务组(IETF)的Hypertext Transfer Protocol Bis (httpbis)工作小组进行开发。是自1999年http1.1发布后的首个更新。
HTTP/2 协议是从 SPDY 演变而来,SPDY 已经完成了使命并很快就会退出历史舞台(例如 Chrome 将在「2016 年初结束对 SPDY 的支持」;Nginx、Apache 也已经全面支持 HTTP/2 ,并也不再支持 SPDY)。
一般的大家把 HTTP2 简称为 h2,尽管有些朋友可能不怎么愿意,但是这个简称已经默认化了,特别是体现在浏览器对 HTTP2 都是这个简写的。
普通的 HTTPS 网站浏览会比 HTTP 网站稍微慢一些,因为需要处理加密任务,而配置了 h2 的 HTTPS,在低延时的情况下速度会比 HTTP 更快更稳定!
现在电信劫持事件频发,网站部署了 HTTPS 加密后可以杜绝大部分劫持,但不是完全。像电子商务行业对 HTTPS 加密可是标配啊,因此部署 h2 更是势在必行。
这里是 免费和便宜 SSL 证书介绍 ,大家可以从这里购买或者申请免费的 SSL 证书,免得 Chrome 弹出红色的页面令人不悦,从而拒绝了大多数访客。
默认编译的 Nginx 并不包含 h2 模块,我们需要加入参数来编译,**截止发文**,Nginx 1.9 开发版及以上版本源码需要自己加入编译参数,从软件源仓库下载的则默认编译。 Tengine 可以同时部署 h2 和 SPDY 保证兼容性,Nginx 从1.9.5则是一刀切不再支持 SPDY原因是跟新版本存在不兼容,1.10.X目前是默认带有HTTP2功能所以不必再重新编译
如果你编译的 Nginx 不支持,那么在 ./configure
中加入:--with-http_v2_module
,如果没有 SSL 支持,还需要加入--with-http_ssl_module
然后 make && make install
即可。
主要是配置 Nginx 的 server
块, 。
修改相关虚拟机的 .conf
文件,一般在 /usr/local/nginx/conf/vhost/
或者 /etc/nginx/conf/
,具体参考你的环境指导,不懂请回复。
server {
listen 443 ssl http2 default_server;
server_name www.mf8.biz;
ssl_certificate /path/to/public.crt;
ssl_certificate_key /path/to/private.key;
注:将 server_name www.mf8.biz;
中的 www.mf8.biz
替换为你的域名。
然后通过 /usr/local/nginx/sbin/nginx -t
或者 nginx -t
来检测是否配置正确,然后重启 Nginx ,即可。
在 Chrome 浏览器上可以通过,HTTP/2 and SPDY indicator 来检验,如果地址栏出现蓝色的闪电就是 h2
也可以在 chrome://net-internals/#http2 中检查。注意版本要新,姿势要帅!
大家都知道去年的心血漏洞将 SSL 推到了风口浪尖,所以单单支持了 h2 ,我们任然需要对 SSL 做一些安全的优化!
配置赫尔曼密钥
openssl dhparam -out dhparam.pem 2048 // 在 ssh 运行, openssl 生成 2048 位的密钥而不是当作参数写入 nginx.conf 文件。
ssl_dhparam /path/to/dhparam.pem; //在 .conf 中配置
禁止不安全的 SSL 协议,使用安全协议
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
禁止已经不安全的加密算法
ssl_ciphers 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4';
缓解 BEAST 攻击
add_header Strict-Transport-Security "max-age=31536000";
用于通知浏览器强制使用 https 通信,这样下次用户在直接输入域名访问时,浏览器会自动使用 https 请求,避免一次跳转。此举直接跳过 301 跳转,还降低了中间人攻击的风险!配置在 .conf 中即可`add_header Strict-Transport-Security max-age=15768000;`**301 跳转**80 端口跳转到 443 端口```nginxserver { listen 80; add_header Strict-Transport-Security max-age=15768000; return 301 https://www.yourwebsite.com$request_uri;}
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
第一条设置一10M大小的缓存池,因为 Nginx 使用本地内存,所以这在分布式系统中作用就不大了。第二条缓存时间,单位分钟
OCSP 缝合:
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/cert/trustchain.crt;
resolver 233.5.5.5 233.6.6.6 valid=300s;
在这里引用一个题外话介绍一下OCSP到底是一个什么东东:
OCSP(Online Certificate Status Protocol,在线证书状态协议)是用来检验证书合法性的在线查询服务,一般由证书所属 CA 提供。某些客户端会在 TLS 握手阶段进一步协商时,实时查询 OCSP 接口,并在获得结果前阻塞后续流程。OCSP 查询本质是一次完整的 HTTP 请求 - 响应,这中间 DNS 查询、建立 TCP、服务端处理等环节都可能耗费很长时间,导致最终建立 TLS 连接时间变得更长。
而OCSP Stapling(OCSP 封套),是指服务端主动获取 OCSP 查询结果并随着证书一起发送给客户端,从而让客户端跳过自己去验证的过程,提高 TLS 握手效率。
问题回顾:
之前有人问过我这个问题:Nginx 版本为 1.11.1 , http_v2 和 http_ssl 这两个模块都有,然后配置文件写了 llisten 443 ssl http2;重启无数次了 但是就是无法启动 http2 这是为什么总是开启http2失败呢?
这个主要是你服务器上自带的openssl版本太低导致的可以升级到openssl1.0.2或者更高版本
接下来谈谈http/2的新特性以及简单的实现原理
SPDY 系列协议由谷歌开发,于 2009 年公开。它的设计目标是降低 50% 的页面加载时间。当下很多著名的互联网公司都在自己的网站或 APP 中采用了 SPDY 系列协议(当前最新版本是 SPDY/3.1),因为它对性能的提升是显而易见的。主流的浏览器(谷歌、火狐、Opera)也都早已经支持 SPDY,它已经成为了工业标准,HTTP Working-Group 最终决定以 SPDY/2 为基础,开发 HTTP/2。
但是,HTTP/2 跟 SPDY 仍有不同的地方,主要是以下两点:
相比 HTTP/1.x,HTTP/2 在底层传输做了很大的改动和优化:
HTTP/2 主要是 HTTP/1.x 在底层传输机制上的完全重构,HTTP/2 是基本兼容 HTTP/1.x 的语义的(详细兼容性说明请戳 这里 )。 Content-Type
仍然是 Content-Type
,只不过它不再是文本传输了。
第三方性能测试spdy http http/2
整个性能测试包含4个场景,使用的软件为Firefox和HttpWatch,测试网页为Google UK首页,比较的协议包括原生HTTPS、SPDY/3.1和HTTP/2协议,同时每一个测试都是在没有浏览器缓存的Firefox实例上执行的,虽然这些测试非常简单,页面也不复杂,但是这并不影响三种不同协议之间重大差异的比较。
虽然大部分网站都已经在下载文本内容的时候使用压缩提升性能,但是HTTP/1.1并不支持HTTP头压缩,为此SPDY和HTTP/2应运而生, SPDY使用了通用的DEFLATE算法,而HTTP/2则使用了专门为压缩头信息而设计的HPACK算法。
第一个测试通过一个没有内容的请求生成的头信息的大小来查看三种协议的不同:
其中,“Sent”列表示请求头的大小,“Received”列表示响应头的大小,结果显示,使用HPACK算法的HTTP/2协议头信息最小。
Web服务器的响应由响应头和编码的响应内容两部分组成。对于图片的请求,测试结果如下:
对于文本资源的请求,结果如下:
结果显示,对于图片HTTP/2协议的请求和响应信息都最小,而对于文本资源,虽然HTTP/2的请求信息依然最小,但是响应信息却比SPDY协议稍大一点。究其原因,这可能是由添加到HTTP/2数据帧中的可选内边距字节造成的,而图片资源并不会使用内边距。
HTTP/1.1通过增加到每个主机的最大连接数来提高性能,而SPDY和HTTP/2则是通过使用多路复用技术在一个单独的TCP和SSL连接上支持并发,通过在一个连接上一次性发送多个请求来发送或接收数据。该场景的测试结果如下:
SPDY结果
HTTP/2结果
HTTPS结果
结果显示,SPDY和HTTP/2通过多路复用技术降低了页面下载时的连接数,而原生的HTTPS协议则需要创建更多的连接。
页面加载时间是一个比较重要的性能指标,该测试使用了HttpWatch中的“页面加载”事件来查看每种协议所需的时间,结果如下:
结果显示,由于不支持头信息压缩,并且缺少所需的额外TCP连接和SSL握手,原生HTTPS所需的时间最长,如果页面更复杂,那么差距会更明显。同时,虽然HTTP/2的响应消息比SPDY大,但是加载时间要比SPDY短。
通过 www.ssllabs.com 即可检验 HTTPS 配置的安全性和实用性!