Nginx优化之-ALPN

2022-09-21 11:09:54 浏览数 (1)

Nginx主线新版本在11月2号又更新了,看了下这次的更新日志

其中第一个Change是,http2中,移除了NPN,目前HTTP/2只支持ALPN了,我们今天来说下什么是NPN与ALPN?移除对我们有什么影响?

NPN与ALPN

自从HTTP从1.1升级到了2,一切都变得不同了。虽然HTTP2没有强制说必须使用加密协议进行传输,但是业界的标准包括各大流行的浏览器都只支持HTTPS情况下的HTTP2协议

那么浏览器在访问 HTTPS 网站时,如何得知服务端是否支持 HTTP/2?答案是借助 HTTP/2 的协议协商机制:在 HTTP/2 Over HTTP 中,可以使用 HTTP 的 Upgrade 机制进行协商;而对于 HTTP/2 Over TLS,可以使用 TLS 的 NPN 或 ALPN 扩展来完成协商

NPN(Next Protocol Negotiation,下一代协议协商),是一个 TLS 扩展,由 Google 在开发 SPDY 协议时提出。随着 SPDY 被 HTTP/2 取代,NPN 也被修订为 ALPN(Application Layer Protocol Negotiation,应用层协议协商)。二者目标一致,但实现细节不一样,相互不兼容。以下是它们主要差别:

  • NPN 是服务端发送所支持的 HTTP 协议列表,由客户端选择;而 ALPN 是客户端发送所支持的 HTTP 协议列表,由服务端选择
  • NPN 的协商结果是在 Change Cipher Spec 之后加密发送给服务端;而 ALPN 的协商结果是通过 Server Hello 明文发给客户端

相较于NPN来说,ALPN在client hello消息中已经列出了客户端支持的应用层协议,服务器端只需要从中选择出它支持的协议即可。比NPN少了一个交互的步骤,所以ALPN是推荐的协议

所以,使用ALPN相对于NPN来说,在SSL/TLS交互握手的过程中,减少了一个TTL来回,性能相对有一定的提升

ALPN如何交互?

在了解NPN和ALPN协商的相关知识前,最好先去看一下之前写的一篇HTTPS完整的交互过程,这里就不多赘述

首先客户端发送"Client Hello"消息:

代码语言:javascript复制
    Handshake Type: Client Hello (1)
    Length: 141
    Version: TLS 1.2 (0x0303)
    Random: dd67b5943e5efd0740519f38071008b59efbd68ab3114587...
    Session ID Length: 0
    Cipher Suites Length: 10
    Cipher Suites (5 suites)
    Compression Methods Length: 1
    Compression Methods (1 method)
    Extensions Length: 90
    [other extensions omitted]
    Extension: application_layer_protocol_negotiation (len=14)
        Type: application_layer_protocol_negotiation (16)
        Length: 14
        ALPN Extension Length: 12
        ALPN Protocol
            ALPN string length: 2
            ALPN Next Protocol: h2
            ALPN string length: 8
            ALPN Next Protocol: http/1.1

可以看到在client hello消息中的Extension字段中,使用了ALPN,并且列出了可以选择使用的两种ALPN Protocol:h2和http/1.1

对应的“server hello” 消息会选择出具体使用的ALPN protocol如下:

代码语言:javascript复制
    Handshake Type: Server Hello (2)
    Length: 94
    Version: TLS 1.2 (0x0303)
    Random: 44e447964d7e8a7d3b404c4748423f02345241dcc9c7e332...
    Session ID Length: 32
    Session ID: 7667476d1d698d0a90caa1d9a449be814b89a0b52f470e2d...
    Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
    Compression Method: null (0)
    Extensions Length: 22
    [other extensions omitted]
    Extension: application_layer_protocol_negotiation (len=5)
        Type: application_layer_protocol_negotiation (16)
        Length: 5
        ALPN Extension Length: 3
        ALPN Protocol
            ALPN string length: 2
            ALPN Next Protocol: h2

如上所示,服务器端选择了h2,最终当客户端和服务器端TLS握手结束之后,会选择使用HTTP2作为后续的应用层数据协议

如何使用ALPN?

大部分 Web Server 都依赖 OpenSSL 库提供 HTTPS 服务,对于它们来说,是否支持 NPN 或 ALPN 完全取决于使用的 OpenSSL 版本。通常,如果在编译时不特意指定 OpenSSL 目录,Web Server 会使用操作系统内置的 OpenSSL 库

OpenSSL 1.0.2 才开始支持 ALPN,当前主流服务器操作系统基本CentOS7,在7.6之后才开始自带OpenSSL 1.0.2,如果是旧版本的系统,需要手动编译安装OpenSSL 1.0.2以上版本并重新编译Nginx,指定新安装的OpenSSL进行编译

另外,很多人喜欢直接升级系统的OpenSSL版本,这里强烈不建议直接升级,后面会找机会写一篇关于动态编译和静态编译的相关文章,依赖OpenSSL库的资源太多了,直接升级系统的版本,会出现各种不稳定的问题

好了,今天就这些内容,欢迎有兴趣的运维大佬们,进群交流

最近群里组织学习交流,形式是通过腾讯会议的形式,每周末进行一个一小时左右的分享交流,欢迎有兴趣的大佬来宣讲,也欢迎想交流的小伙伴进群交流

感谢交流群大佬们的长期支持、关注和分享

0 人点赞