建站系列之 Nginx 开启 TLSv1.3 支持

小助手读文章 00:00 / 00:00

几个月前曾尝试将资源站开启 TLSv1.3,奈何当时资料比较少,没有成功开启,这两天重新拾起研究了以下,终于可以了,下面介绍一下操作步骤。

要求

  • 需要下载支持 TLS1.3 的 Nginx 源码,并重新编译;
  • 需要下载版本大于 1.1.1 的 OpenSSL 源码,并重新编译,或不重新编译在 Nginx 编译时动态加载;
  • 需要浏览器也支持 TLSv1.3(否则最高也只支持到 TLSv1.2,最新版 Chrome 和 Firefox 已支持优先 TLSv1.3 连接)。

依赖

编译所需的一些组件先 安装/更新 下:

#centos
yum -y install redhat-lsb make gcc gcc-c++ wget crontabs zlib zlib-devel openssl openssl-devel perl patch
#Ubuntu
apt-get --no-install-recommends install -y lsb-release debian-keyring debian-archive-keyring build-essential gcc g++ make autoconf automake wget cron openssl libssl-dev zlib1g zlib1g-dev

pcre 库也要安装(更新)下:

wget -c --progress=bar:force --prefer-family=IPv4 --no-check-certificate https://soft.vpser.net/web/pcre/pcre-8.42.tar.bz2 pcre-8.42.tar.bz2 && tar jxf pcre-8.42.tar.bz2 && cd pcre-8.42 && ./configure
make && make install && cd .. && rm -rf pcre-8.42*

启用库:

echo "/usr/local/lib" >> /etc/ld.so.conf
ldconfig

Nginx 1.13 开始支持 TLSv1.3,所以需要下载版本号大于 1.13 的 Nginx 源码:

wget -c --progress=bar:force --prefer-family=IPv4 --no-check-certificate https://nginx.org/download/nginx-1.15.7.tar.gz && tar zxf nginx-1.15.7.tar.gz && rm nginx-1.15.7.tar.gz && cd nginx-1.15.7/src/

要启用 TLSv1.3,自然少不了 OpenSSL1.1.1a:

wget -c --progress=bar:force --prefer-family=IPv4 --no-check-certificate https://www.openssl.org/source/openssl-1.1.1a.tar.gz && tar zxf openssl-1.1.1a.tar.gz && rm -rf openssl-1.1.1a.tar.gz && cd ..

编译

情况一:版本升级

如果是已经安装过了 Nginx 要升级,那么先通过 nginx -V 获得之前的编译参数,然后加上 --with-openssl=src/openssl-1.1.1a 进行 make 编译,如果要支持 TLSv1.0(新版默认不支持了),那么应该再加上 --with-openssl-opt='enable-weak-ssl-ciphers',编译好后直接将 objs/nginx 替换已安装的 nginx 命令文件。

如果要隐藏 Nginx 特定信息,可以参考《建站系列之隐藏 Nginx/Apahe 服务器响应的 server/X-Powered-By 等信息》。

情况二:首次安装

如果是第一次安装,那么可以直接执行下列命令:

groupadd www # 添加组
useradd -s /sbin/nologin -g www www #添加用户
./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_v2_module --with-http_gzip_static_module --with-http_sub_module --with-stream --with-stream_ssl_module --with-openssl=$(pwd)/src/openssl-1.1.1a --with-openssl-opt='enable-weak-ssl-ciphers'

然后执行:

make && make install

配置

现在 Nginx 已经支持 TLSv1.3 了,但站点还需要配置一下才行,找到站点配置文件,参照下面的配置进行修改(特别注意 ssl_ciphers ):

ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
 
ssl_ciphers '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-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';

配置好可以通过 service nginx reload 命令重载配置。

验证

现在站点不出意外已经可以使用 TLSv1.3 进行连接了,可以通过 Chrome F12 开发模式中的安全查看:

tls3.png

拓展:升级 OpenSSL

上面讲到,我们启用 TLSv1.3 支持时,并没有直接升级 OpenSSL,而是采用动态加载的方式进行的,我们当然也可以直接升级 OpenSSL 版本来使 Nginx 支持 TLSv1.3。

可以先看下旧版本确认是否需要升级:

# openssl --version
OpenSSL 1.0.2k-fips  26 Jan 2017

如果 openssl 版本小于 1.1.1(wiki),那么就需要升级 OpenSSL 了,像现系统默认是 1.0.2k-fips 就需要升级,而像 Debian sid 默认就是 1.1.1a 就不需要再做单独的升级操作了。

下载并解压缩源代码:

wget https://www.openssl.org/source/openssl-1.1.1b.tar.gz
tar xf openssl-1.1.1b.tar.gz && rm --rf openssl-1.1.1b.tar.gz
cd openssl-1.1.1b

配置、编译与安装:

./config zlib enable-shared
make && make install

备份原来版本的 openssl:

mv /usr/bin/openssl /usr/bin/openssl1.0.2k 
mv /usr/include/openssl /usr/include/openssl1.0.2k

链接新版本:

ln -s /usr/local/bin/openssl /usr/bin/
ln -s /usr/local/include/openssl /usr/include/openssl
ln -s /usr/local/lib64/libssl.so.1.1 /usr/lib64/libssl.so.1.1
ln -s /usr/local/lib64/libcrypto.so.1.1 /usr/lib64/libcrypto.so.1.1
ldconfig

确认下是否安装成功:

# openssl version
OpenSSL 1.1.1b  26 Feb 2019

问答

1、已经按步骤操作,但是 443 端口还是无法启用 TLSv1.3,但是换个端口却可以。
答:确认 ssl_ciphers 是否配置正确,确认正确的话,再参考问题 2。

2、可以使用 TLSv1.2 和 TLSv1.3 连接了,但无法使用 TLSv1.0 和 TLSv1.1 连接。
答:Nginx SSL 版本有个不知道算不算问题的问题,即同 IP 所有站点下(即该问题只会出现在多站点的情况),只能支持相同版本的 SSL,即 ssl_protocols 配置必须相同,不同的话仅支持交集,不配置的话默认只支持 TLSv1.2

举个例子:
同 IP 下配置了 vircloud.netwww.vircloud.net 两个站点,都开启了 HTTPS,Nginx 也已配置支持了 TLSv1.3,此为背景。
现在 vircloud.netssl_protocolsTLSv1 TLSv1.1 TLSv1.2 TLSv1.3www.vircloud.netssl_protocolsTLSv1.2 TLSv1.3,通过 nginx -t 测试配置没有任何错误,我们的目的是希望 www.vircloud.net 只接受更安全的 TLSv1.2 TLSv1.3vircloud.net 则不限制。

以 TLSv1.3 版本测试 vircloud.net 连接:

# openssl s_client -servername vircloud.net -connect vircloud.net:443 -tls1_3`
CONNECTED(00000003)
......
verify return:1
Certificate chain
......
Protocol  : TLSv1.3
Cipher    : TLS_AES_256_GCM_SHA384
......

可以看到已经成功连接,再以 TLSv1.1 版本测试:

# openssl s_client -servername vircloud.net -connect vircloud.net:443 -tls1_1`
CONNECTED(00000003)
......
no peer certificate available
No client certificate CA names sent
......
Protocol  : TLSv1.1
Cipher    : 0000
......

发现无法以 TLSv1.1 版本连接服务器,虽然我们在 vircloud.net 已经启用了 TLSv1.1。参照 vircloud.net 配置,我们修改 www.vircloud.netssl_protocols,把 TLSv1 TLSv1.1 也添加进来,再次以 TLSv1.1 版本去测试连接:

# openssl s_client -servername vircloud.net -connect vircloud.net:443 -tls1_1`
CONNECTED(00000003)
......
verify return:1
Certificate chain
......
Protocol  : TLSv1.1
Cipher    : ECDHE-RSA-AES128-SHA
......

可以发现 Nginx 已经可以以 TLSv1.1 连接了,所以结论就是 同 IP 所有站点,ssl_protocols 配置必须相同,而无法实现希望的同 IP 下某站点支持所有 TLS 版本,某站点支持特定 TLS 版本。


参考文章:

1、《为 Nginx 开启 tls 1.3 支持,顺便编译 openssl1.1.1a
2、《使用宝塔面板开启TLSv1.3


ArmxMod for Typecho
个性化、自适应、功能强大的响应式主题

推广

 继续浏览关于 nginx升级SSLtlsv1.3建站系列 的文章

 本文最后更新于 2019/03/29 09:07:50,可能因经年累月而与现状有所差异

 引用转载请注明:VirCloud's Blog > 运维 > 建站系列之 Nginx 开启 TLSv1.3 支持