CentOS 7 默认带的openssl是1.0.1版本,开启HTTP2则必须升级1.1左右的版本。

本文仅适用CentOS7

以下为升级全过程

升级OpenSSL

查看当前openssl版本

1
$ openssl version

查看输出版本

前往Openssl官方(戳我)查看最新的openssl版本,make本文的时候最新版本为1.1.0f

下载并解压

1
2
3
4
$ cd /home
$ wget https://www.openssl.org/source/openssl-1.1.0f.tar.gz
$ tar -zxvf openssl-1.1.0f.tar.gz
$ cd openssl-1.1.0f

动态编译Openssl,并安装

1
2
$ ./config zlib-dynamic
$ make && make install

这里要注意,如果编译的时候增加了 zlib-dynamic 这个参数代表了动态编译,编译完成后,只需要执行下文中#添加libssl.so.1.1等两个步骤,因为openssl的执行目录和文件都已经就绪。

如果用默认的安装,那么此刻openssl默认被安装到了/usr/local/目录。

查看目前运行的Openssl目录

1
$ which openssl

开始升级(如果动态编译,可以从#添加libssl.so.1.1开始)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#把旧版本的openssl备份一下,下面的目录即是上面用which查出来的目录,每个人的服务器配置不一样,请依照情况执行。
$ mv /usr/bin/openssl /usr/bin/openssl.bak
$ mv /usr/include/openssl /usr/include/openssl.bak
#拷贝刚编译好的新版本的openssl-1.1.0f
$ cp /usr/local/bin/openssl /usr/bin/openssl
$ cp -r /usr/local/ssl /usr/include/openssl
#注意,1.1.0f版本 生成的文件的位置在/usr/local/ssl
#这里没有用ln软链的原因是因为如果使用ln可能在后续安装中造成其他软件的安装错误,比较常见的就是报[install_dev]错误
#添加libssl.so.1.1
$ cp /usr/local/lib64/libssl.so.1.1 /usr/lib64/libssl.so.1.1
$ cp /usr/local/lib64/libcrypto.so.1.1 /usr/lib64/libcrypto.so.1.1
#查看openssl版本
$ openssl version
#重新加载动态链接库,这步比较重要,特别是下一步要升级nginx
$ ldconfig -v

至此,openssl已经成功升级。

升级Nginx支持HTTP2

升级

Nginx的升级相对比较简单

升级前最好检查下是否具备编译Nginx的条件,特别是以前很多采用YUM安装的懒癌晚期,可能没安装编译环境:

1
$ yum install gcc-c ++ pcre-devel zlib-devel make wget openssl-devel libxml2-devel libxslt-devel gd-devel perl-ExtUtils-Embed GeoIP-devel gperftools-devel

以上基本把所需的依赖都装好了,如果在下面的编译环境中提示Peal的相关错误,可以考虑安装cpan,用cpan按照提示安装缺少的peal库。

开始升级

1
2
3
4
5
6
7
#看一下nginx版本与配置
[root@sf3 ~]# nginx -V
nginx version: nginx/1.10.0 //这里输出的是当前版本
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC) //编译用的Gcc版本
built with OpenSSL 1.0.1e-fips 11 Feb 2013 //使用的openssl版本,我们本次升级主要针对的地方
TLS SNI support enabled //TLS支持是否打开
configure arguments: [内容略去] //编译参数

最新稳定版本是1.10.2

官网地址:http://nginx.org

升级步骤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#下载nginx最新版
$ cd /home
$wget http://nginx.org/download/nginx-1.10.2.tar.gz
#解压源码
$ tar zxvf nginx-1.10.2.tar.gz
#进入源码目录
$ cd nginx-1.10.2
#加上所需参数开始编译
$ ./configure [这里copy上文提到的内容略去部分,或者根据你自己的情况进行配置] --with-openssl=/home/openssl-1.1.0f #请注意,这条最重要,对应openssl源码解压后的路径
#执行make编译,但是不要执行make install
$ make
#重命名nginx旧版本二进制文件,即sbin目录下的nginx(期间nginx并不会停止服务)
#每个人服务器的安装不太一样,执行前记得用which nginx看一下nginx所在目录
$ mv /usr/sbin/nginx /usr/sbin/nginx.old
#然后拷贝一份新编译的二进制文件
$ cp objs/nginx /usr/sbin/sbin/
#在源码目录执行make upgrade开始升级
$ make upgrade
#完成后查看下版本
$ nginx -V

如果遇到错误,请参考本博客上篇文章,用YUM升级安装nginx到最新版本nginx,再进行编译。

配置部分

在nginx的conf文件里,对对应的站点进行配置,非常简单,只需要增加ssl http2;即可,比如说:

1
listen 443 ssl http2 default_server;

要验证http2是否生效可以安装个chrome插件HTTP/2 and SPDY indicator,如果开启了h2,那么会有一道蓝色的闪电,比如说,就像本站已经开启了:

推荐的配置

这里有个网站推荐给大家,可以生成被优化推荐的Nginx配置文件

戳我抵达

一些测试

除了上面提到的Chrome插件以外,如果服务器的openssl版本过低,可能导致chrom浏览器访问失败,原因是因为在去年google chrom51版本中google移除了NPN,只支持ALPN,所以导致协商失败。

用这条命令可以测试目前HTTP2服务是否支持ALPN

1
openssl s_client -alpn h2 -servername imququ.com -connect kanshouce.com:443 < /dev/null | grep 'ALPN'

如果提示 unknown option -alpn,说明本地的 OpenSSL 版本太低(可通过 openssl version 查看),请升级到 1.0.2+。如果不方便升级,也可以使用 Qualys SSL Labs’s SSL Server Test 这个在线工具来测试。

如果结果包含 ALPN protocol: h2,说明服务端支持 ALPN,不受 Chrome 51+ 去掉 NPN 的影响。

如果结果包含 No ALPN negotiated,说明服务端不支持 ALPN,在 Chrome 51+ 中无法协商到 HTTP/2,需要尽快升级。