MENU

nginx启用TLSv1.3遇到的一些问题

2018 年 10 月 19 日 • 杂乱文章

昨日深夜,猫叔&快活表示我的主页Blog崩了,打不开了,难不成服务器凉凉了?还是docker崩了,然后我让他们发了一下截图,大概是这样子。。。

抛得并不是什么连接失败的错,而是ERR_SSL_VERSION_INTERFERENCEChrome版本70,我也用手机访问了一下,没有问题,想到Chrome70好像是昨天才升的,而且我的全部网站都启用了TLS1.3,会不会是这里出问题了,然后我叫他们把ChromeTLS1.3支持开了,再试试,果然开启了TLS1.3之后就能正常访问,默认状态就会抛ERR_SSL_VERSION_INTERFERENCE,然后手机连到了服务器,把TLS1.3暂时关掉了,大概看了一眼错误日志,和SSL有关系,握手失败,然后就睡了,找个时间解决一下。

然后时间来到了现在,先看了一下服务器错误日志,如下。

2018/10/18 23:22:55 [crit] 2764#0: *25297 SSL_do_handshake() failed (SSL: error:1408F1BB:SSL routines:ssl3_get_record:bad record type) while SSL handshaking, client: 123.245.0.0, server: 0.0.0.0:443

又查了一下ERR_SSL_VERSION_INTERFERENCE这个错误,解决办法都是在Chrome中禁用TLS1.3的支持,经过测试禁用或开启TLS1.3都能打开我的博客,使用TLS1.2,但是默认就无法访问了,根据昨天的反馈,除了Chrome70别的浏览器都能正常访问,像是QQ浏览器,Win10的edge,然后开始排错。

已知问题

问题就是Chrome70无法正常访问我的站点,服务端抛得什么错上面也贴了,估计是还是nginx或openssl哪里的配置出现了问题,错误日志提示的很明显了,我现在用的环境如下,nginx版本1.14.0openssl版本1.1.1-pre1,编译参数如下。

[root@nginx /]# nginx -V
nginx version: rj-bai
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC)
built with OpenSSL 1.1.1-pre1 (alpha) 13 Feb 2018
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --without-http_memcached_module --user=www --group=www --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-http_v2_module --with-openssl=/usr/local/src/openssl-1.1.1-pre1 --with-openssl-opt='enable-tls1_3 enable-weak-ssl-ciphers' --with-zlib=/usr/local/src/zlib-1.2.11 --with-pcre=/usr/local/src/pcre-8.42

nginx估计没啥问题,然后在openssl官网深扒了一下,发现了点东西,主要内容

TLSv1.3标准的当前状态

TLSv1.3标准现已发布为 [RFC 8446 ]。在制定标准期间,TLS工作组发布了各种草案版本。标准草案版本的实现确定了他们正在使用的特定草案版本。这意味着基于不同草案版本以及最终RFC版本的实现不会相互操作。

OpenSSL git master分支(和1.1.1-pre9 beta版本)包含我们的开发TLSv1.3代码,该代码基于RFC8446的最终版本,可用于测试目的(即它不用于生产用途)。早期的OpenSSL 1.1.1测试版实现了该标准的草案版本。这些版本在tls1.h头文件中包含宏TLS1_3_VERSION_DRAFT_TXT,该文件标识了已实现的特定草稿版本。此宏已从1.1.1-pre9和当前主分支中删除。

默认情况下,在最新的开发版本中启用TLSv1.3(无需显式启用它)。要在编译时禁用它,必须使用“no-tls1_3”选项“config”或“Configure”。

虽然最新的1.1.1版本支持最终的标准版本,但支持TLSv1.3的其他应用程序可能仍在使用较旧的草稿版本。这是互操作性问题的常见来源。如果支持不同TLSv1.3草案版本的两个对等体尝试通信,那么它们将回退到TLSv1.2。

密码套件

OpenSSL已经实现了对五个TLSv1.3密码套件的支持,如下所示:

  • TLS_AES_256_GCM_SHA384
  • TLS_CHACHA20_POLY1305_SHA256
  • TLS_AES_128_GCM_SHA256
  • TLS_AES_128_CCM_8_SHA256
  • TLS_AES_128_CCM_SHA256

我现在用的1.1.1-pre1版本,也就是测试版本,可用于测试目的(即它不用于生产用途),既然现在最终的标准版本已经有了,就升级一下,下面要做的就是升级openssl到正式版本,顺便把nginx也升级到最新版本,开撸。

升级openssl到正式版本

敬告

编译安装nginx和启用Tlsv1.3的方法请参考这篇文章,下面的方法已过时,不在更新

编译安装阶段

现在我要使用最新版本的nginx-1.15.5,正式版本的openssl-1.1.1,还需要给openssl打一下补丁

[root@nginx /usr/local/src]# wget http://nginx.org/download/nginx-1.15.5.tar.gz
[root@nginx /usr/local/src]# wget https://www.openssl.org/source/openssl-1.1.1.tar.gz
[root@nginx /usr/local/src]# git clone https://github.com/hakasenyang/openssl-patch.git
[root@nginx /usr/local/src]# tar zxf openssl-1.1.1.tar.gz && cd openssl-1.1.1
[root@nginx /usr/local/src/openssl-1.1.1]# patch -p1 < ../openssl-patch/openssl-equal-1.1.1_ciphers.patch && cd ../
[root@nginx /usr/local/src]# tar zxf nginx-1.15.5.tar.gz
[root@nginx /usr/local/src]# cd nginx-1.15.5/
[root@nginx /usr/local/src/nginx-1.15.5]# ./configure --prefix=/usr/local/nginx --without-http_memcached_module --user=www --group=www --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-http_v2_module --with-openssl=/usr/local/src/openssl-1.1.1 --with-zlib=/usr/local/src/zlib-1.2.11 --with-pcre=/usr/local/src/pcre-8.42
[root@nginx /usr/local/src/nginx-1.15.5]# make && make install

我关闭了对3DES和RC4密码套件的支持,如果想开启,编译参数请添加--with-openssl-opt='enable-weak-ssl-ciphers',现在新版本不用加enable-tls1_3,默认开启,大概就是这样,然后修改ssl_protocolsssl_ciphers

修改配置文件

配置一下协议和密码套件

[root@nginx vhost]# vi extend/ssl
        ssl_stapling on;
        ssl_stapling_verify on;
        ssl_session_timeout 1d;
        ssl_session_tickets off;
        ssl_session_cache shared:SSL:10m;

        ssl_prefer_server_ciphers on;
        ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_ciphers [TLS13+AESGCM+AES128|TLS13+AESGCM+AES256|TLS13+CHACHA20]:[EECDH+ECDSA+AESGCM+AES128|EECDH+ECDSA+CHACHA20]:EECDH+ECDSA+AESGCM+AES256:EECDH+ECDSA+AES128+SHA:EECDH+ECDSA+AES256+SHA:[EECDH+aRSA+AESGCM+AES128|EECDH+aRSA+CHACHA20]:EECDH+aRSA+AESGCM+AES256:EECDH+aRSA+AES128+SHA:EECDH+aRSA+AES256+SHA:RSA+AES128+SHA:RSA+AES256+SHA:RSA+3DES;
[root@nginx vhost]# nginx -s reload

有一个需要注意的地方,想启用tls1.3,服务器所有https域名都要启用tls1.3,包括443端口的default_server。建议把所有域名的SSL配置放到一起,然后域名配置文件去include就好。

最终结果

在myssl.com检测了一下,大概是酱紫。

我这样干IE11以下浏览器全部残废,除非手动开启了IE的tls1.1&tls1.2的支持,考虑兼容性的同学可以在ssl_protocols加上TLSv1即可,别的就没什么了。

最后编辑于: 2019 年 01 月 02 日
返回文章列表 文章二维码 打赏
本页链接的二维码
打赏二维码