0x01 前言
TLSv1.3在很久以前就已经起草,直至最近,IETF已经确认了正式版草案,根据计划,将在4月5日发布正式版。
在此之前,Firefox与Chrome已经使用支持Openssl draft 23的中间件启用TLSv1.3。所以在一周以前,我重新编译nginx,提前启用TLSv1.3。
其实nginx从1.13.0开始就已经支持TLSv1.3,但是主流的浏览器还不能自动启用TLSv1.3,所以我一直都没有把这个协议加上,直至上周,我终于动手了。
0x02 准备
因为我应用环境的需要,所以我需要下载以下源码:
- lua-nginx-module:用于支持lua模块
- nginx-ct:启用证书透明度
- openssl-1.1.1-pre2:用于启用TLSv1.3
- ModSecurity:用于编译ModSecurity
- ModSecurity-nginx:用于连接ModSecurity与nignx
这里有个要注意的点,目前最新的openssl版本为: openssl-1.1.1-pre3,这个版本的openssl对应draft 26,而我们需要draft 23,对应的openssl版本为 openssl-1.1.1-pre2。旧版本的openssl可以从以下地址下载:
首先建立临时文件夹并下载相关文件:
#新建文件夹 [root@web-dev ~]# mkdir -p /root/codex/nginx #进入文件夹 [root@web-dev ~]# cd codex/nginx/ #下载lua-nginx-module [root@web-dev nginx]# git clone https://github.com/openresty/lua-nginx-module.git #下载nginx-ct [root@web-dev nginx]# git clone https://github.com/grahamedgecombe/nginx-ct.git #下载openssl [root@web-dev nginx]# wget https://www.openssl.org/source/old/1.1.1/openssl-1.1.1-pre2.tar.gz #下载ModSecurity [root@web-dev nginx]# git clone --depth 1 -b v3/master --single-branch https://github.com/SpiderLabs/ModSecurity #下载ModSecurity-nginx [root@web-dev nginx]# git clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git
然后,还得下载nginx:
[root@web-dev nginx]# wget https://nginx.org/download/nginx-1.13.10.tar.gz
最后解压被压缩的软件:
#解压并删除nginx压缩包 [root@web-dev nginx]# tar zxvf nginx-1.13.10.tar.gz && rm -f nginx-1.13.10.tar.gz #解压并删除openssl压缩包 [root@web-dev nginx]# tar zxvf openssl-1.1.1-pre2.tar.gz && rm -f openssl-1.1.1-pre2.tar.gz
最终,该目录下会有这些文件夹:
[root@web-dev nginx]# ll 总用量 20 drwxr-xr-x 11 root root 4096 4月 1 17:18 lua-nginx-module drwxr-xr-x 12 root root 4096 4月 1 17:14 ModSecurity drwxr-xr-x 5 root root 4096 4月 1 17:14 ModSecurity-nginx drwxr-xr-x 8 1001 1001 147 3月 20 23:58 nginx-1.13.10 drwxr-xr-x 3 root root 4096 4月 1 17:11 nginx-ct drwxr-xr-x 19 root root 4096 2月 27 21:40 openssl-1.1.1-pre2
0x03 编译安装
如果不需要ModSecurity,那么可以跳过ModSecurity的部分,如果需要一起编译,那么请参考以下文章中“0x03.1 Modsecurity Lib”的部分,先准备好ModSecurity,再编译nignx:
如果不想看那么长的文章,也可以直接运行以下命令:
#进入相关目录 [root@web-dev ModSecurity]# cd /root/codex/nginx/ModSecurity #初始化submodule [root@web-dev ModSecurity]# git submodule init #更新submodule [root@web-dev ModSecurity]# git submodule update #运行build.sh [root@web-dev ModSecurity]# ./build.sh #configure [root@web-dev ModSecurity]# ./configure #编译 [root@web-dev ModSecurity]# make #安装 [root@web-dev ModSecurity]# make install
完成ModSecurity的编译安装后就可以准备nignx的编译参数了:
./configure --prefix=/usr/local/nginx --sbin-path=/usr/sbin/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/var/run/nginx.pid --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --lock-path=/var/lock/nginx.lock --with-http_gunzip_module --with-pcre --with-pcre-jit --with-http_perl_module --with-ld-opt="-Wl,-E" --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-http_addition_module --with-http_xslt_module --with-http_image_filter_module --with-http_geoip_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-select_module --with-poll_module --with-file-aio --with-http_degradation_module --with-libatomic --http-client-body-temp-path=/var/tmp/nginx/client_body --http-proxy-temp-path=/var/tmp/nginx/proxy --http-fastcgi-temp-path=/var/tmp/nginx/fastcgi --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi --http-scgi-temp-path=/var/tmp/nginx/scgi --add-dynamic-module=../ModSecurity-nginx/ --add-module=../lua-nginx-module --add-module=../nginx-ct/ --with-openssl=../openssl-1.1.1-pre2/
在开始编译之前,需要修改OpenSSL的一个文件,这是一个已知的BUG,而且在新版的OpenSSL中已经修复。打开以下文件并修改:
#打开文件 [root@web-dev nginx-1.13.10]# vim /root/codex/nginx/openssl-1.1.1-pre2/crypto/ec/asm/x25519-x86_64.pl #删除最后一行中的变量符号 close STDOUT;
然后进入nginx源码的文件夹进行编译操作:
#进入文件夹 [root@web-dev ~]# cd /root/codex/nginx/nginx-1.13.10/ #configure [root@web-dev nginx-1.13.10]# ./configure --prefix=/usr/local/nginx --sbin-path=/usr/sbin/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/var/run/nginx.pid --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --lock-path=/var/lock/nginx.lock --with-http_gunzip_module --with-pcre --with-pcre-jit --with-http_perl_module --with-ld-opt="-Wl,-E" --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-http_addition_module --with-http_xslt_module --with-http_image_filter_module --with-http_geoip_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-select_module --with-poll_module --with-file-aio --with-http_degradation_module --with-libatomic --http-client-body-temp-path=/var/tmp/nginx/client_body --http-proxy-temp-path=/var/tmp/nginx/proxy --http-fastcgi-temp-path=/var/tmp/nginx/fastcgi --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi --http-scgi-temp-path=/var/tmp/nginx/scgi --add-dynamic-module=../ModSecurity-nginx/ --add-module=../lua-nginx-module --add-module=../nginx-ct/ --with-openssl=../openssl-1.1.1-pre2/ #编译 [root@web-dev nginx-1.13.10]# make #安装 [root@web-dev nginx-1.13.10]# make install
因为自定义了OpenSSL版本,所以编译的时间会比较长,需耐心等待。
完成后即可通过以下命令查看nginx的相关信息:
[root@web-dev nginx-1.13.10]# nginx -V nginx version: nginx/1.13.10 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC) built with OpenSSL 1.1.1-pre2 (alpha) 27 Feb 2018 TLS SNI support enabled configure arguments: --prefix=/usr/local/nginx --sbin-path=/usr/sbin/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/var/run/nginx.pid --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --lock-path=/var/lock/nginx.lock --with-http_gunzip_module --with-pcre --with-pcre-jit --with-http_perl_module --with-ld-opt=-Wl,-E --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-http_addition_module --with-http_xslt_module --with-http_image_filter_module --with-http_geoip_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-select_module --with-poll_module --with-file-aio --with-http_degradation_module --with-libatomic --http-client-body-temp-path=/var/tmp/nginx/client_body --http-proxy-temp-path=/var/tmp/nginx/proxy --http-fastcgi-temp-path=/var/tmp/nginx/fastcgi --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi --http-scgi-temp-path=/var/tmp/nginx/scgi --add-dynamic-module=../ModSecurity-nginx/ --add-module=../lua-nginx-module --add-module=../nginx-ct/ --with-openssl=../openssl-1.1.1-pre2/
0x04 配置
在启动nginx之前我们需要对站点的配置文件稍作改动。
因为TLSv1.3新加入了几个算法,所以需要添加到nginx的配置文件中:
- TLS13-AES-256-GCM-SHA384
- TLS13-CHACHA20-POLY1305-SHA256
- TLS13-AES-128-GCM-SHA256
- TLS13-AES-128-CCM-8-SHA256
- TLS13-AES-128-CCM-SHA256
因为我的站点不计划支持旧设备,所以目前只支持TLSv1.2与TLSv1.3。如果你的业务需要支持旧的设备,那么请注意选择加密算法,以下为我站点所使用的算法:
TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
然后配置协议:
ssl_protocols TLSv1.2 TLSv1.3;
其他的配置信息可以参考以下文章:
0x05 测试
在我写这篇文章的时候,最新版本的chrome与Firefox已经默认启用对OpenSSL draft 23的支持,所以并不需要手动修改浏览器的配置。
打开chrome的控制台,选择security标签,再打开测试用的站点,就可以看到所使用的协议:
至于Firefox,打开站点后点击地址栏上的小锁,然后点击“显示连接细节”,最后单击“更多信息”即可看到所使用的协议:
因为能力所限,我并没有测试其他浏览器,如果有需要,请自行测试。
0x06 结语
还有几天,正式版的OpenSSL就要发布了,同时各主流的浏览器也将逐步更新,加入对TLSv1.3的支持。不过对于终端用户来说并没有什么感觉,但我们需要特别关注浏览器对这个协议的兼容性。