nginx 1.15.3 版本说明

0x00 Feature List

主要包含如下两点:

  • Feature: now TLSv1.3 can be used with BoringSSL.

  • Feature: the “ssl_early_data” directive, currently available with BoringSSL.

  • Feature: the “keepalive_timeout” and “keepalive_requests” directives in the “upstream” block.

前两者关于BoringSSL和 TLS 相关的优化,后者是 keepalive 特性的优化,下面分别介绍。

0x01 UPSTREAM KEEPALIVE

关于Nginx Upstream 长连接池的机制可以参看之前的让nginx支持TCP长连接代理这篇文章,这次主要现在如下两个指令, 如下:

1
2
3
4
5
6
* Syntax: keepalive_timeout timeout;
* Default: keepalive_timeout 60s;
* Context: upstream
> This directive appeared in version 1.15.3.
Sets a timeout during which an idle keepalive connection to an upstream server will stay open

以及如下:

1
2
3
4
5
6
* Syntax: keepalive_requests number;
* Default: keepalive_requests 100;
* Context: upstream
> This directive appeared in version 1.15.3.
After the maximum number of requests is made, the connection is closed.

可以看到其主要作用是,当一个请求空闲一段时间(keepalive_timeout)或者处理过足够多(keepalive_requests)的请求, 则会关闭连接,以便重启;

其核心理念是希望长链接的请求能够回收重启, 原因是长连接容易造成一些边缘 case 和异常,比如implement keepalive timeout for upstreamTimeouts when proxying to Apache and using Keepalive, 提到的proxy server和 proxy 的竞争发送问题, Proxy servertime_wait过多等问题; 代码修复实现相对比较简单,不再赘述。

0x02 BoringSSL与 TLS

我们知道 OpenSSL是应用最为广泛的TLS协议的实现, 由于 TLS 的重要性以及 OpenSSL 实现的复杂性,其安全问题一直都存在着; 所以,业内也有提出其他的 OpenSSL 的实现方式,比如基于OpenSSL修改衍生的BoringSSLLibreSSL, 这一类实现和 OpenSSL 基本保持接口的兼容,也就意味着宿主程序可以以较低的成本进行迁移; 还有一类是独立实现的,比如说BearSSL (建议可以深入了解)之类,其有自己特意的针对性目标和场景,其接口和openssl也不一致, 迁移成本较大。所以, Nginx从1.7.4开始, 开始兼容BoringSSL and LibreSSL, 其兼容成本也不算特别高。

具体编译的方法可以参考Nginx替换OpenSSL为LibreSSLNginx 启用 BoringSSL, 其核心是Nginx 编译脚本依赖的两类文件(考虑类Unix环境), 包括:

  • $OPENSSL/.openssl/include/openssl/ssl.h(参考auto/lib/openssl/make文件) : 头文件的依赖
  • $CORE_LIBS $OPENSSL/.openssl/lib/libssl.a$CORE_LIBS $OPENSSL/.openssl/lib/libcrypto.a(参考参考auto/lib/openssl/conf文件) : 链接库的依赖

由于编译的脚本是死的,所以在准备LibreSSL或者BoringSSL的时候,保证上面两者的兼容性就可以了

再简单分析LibreSSL/BoringSSL和 OpenSSL 的一些差异点, 整体不同的TLS library的对比可以参考Wiki:Comparison of TLS implementations, 上面有比较详细的对比

0x03 Reference

  • LibreSSL : 比较系统的介绍LibreSSL项目初衷,目标以及如何实现(主要在代码实现方面有所取舍)的, 可以快速了解

  • BearSSL: Overview : BearSSL也是一个TLS的实现, 里面保护很多比较最新的特性,比如说时间无关的支持, 是学习TLS的一个很好入门

  • Make SSL boring again : CloudFlare的BoringSSL的迁移实践和总结, 包括其优势,比如说较早的TLS1.3的支持, X25519的支持等, 其不足之处, 比如说Slow Base64(因为保证constant-time的), missing OCSP等,可以看出和了解BoringSSL和Openssl 的异同点

  • Analysing and improving the crypto ecosystem of Rust : 我们知道OpenSSL 现在主要的核心问题实现方面的漏洞, 其和C/C++语言的内存模型有一些关系, Rust的语言设计能很大的规避这方面的问题,这篇长 paper(一百多页) 就是介绍了如果通过Rust 构建一个更健壮的密码系统