点赞
评论
收藏
分享
举报
Nginx优化之——ALPN
发表于2021-11-09 13:01

浏览 3.1k

文章标签

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"消息:

    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如下:

    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库的资源太多了,直接升级系统的版本,会出现各种不稳定的问题

已修改于2023-03-09 02:04
本作品系原创
创作不易,留下一份鼓励
李俊鹏

暂无个人介绍

关注



写下您的评论
发表评论
全部评论(0)

按点赞数排序

按时间排序

关于作者
李俊鹏
这家伙很懒还未留下介绍~
4
文章
0
问答
2
粉丝
相关文章
Netcraft公司最近公布了他们检测SSL/TLS网站的研究,并指出只有仅仅5%的用户正确执行了HTTP严格传输安全HSTS。本文介绍nginx如何配置HSTS。什么是HSTSHTTPS(SSL和TLS)确保用户和网站通讯过程中安全,使攻击者难于拦截、修改和假冒。当用户手动输入域名或http://链接,该网站的第一个请求是未加密的,使用普通的http。最安全的网站立即发送回一个重定向使用户引向到https连接,然而,中间人攻击者可能会攻击拦截初始的http请求,从而控制用户后续的回话。自然而然HSTS应运而生为了解决这一潜在的安全问题。即时用户输入域名或http连接,浏览器将严格的升级到https连接。HSTS如何工作的HSTS策略是从安全的HTTPS站点发送的HTTP响应头部发布的。1Strict-Transport-Security:max-age=31536000当浏览器从HTTPS站点看到这个头部,就知道该域名只能通过HTTPS(SSL或者TLS)访问了。并将此信息缓存到31536000,也就是1年。可选的参数includeSubDomains告诉浏览器该策略适用于当前
点赞 0
浏览 1.3k
在Nginx的并发优化中,TIME-WAIT是服务器优化必然会谈到的一个话题,而我们常见的问题就是TIME-WAIT过多怎么处理?常见的解决方法就是:1、快速回收2、链接复用而这里有个误区就是到底TIME-WAIT要优化到什么程度,有的童鞋甚至看到TIME-WAIT就觉得需要优化,今天就是想聊一下这个话题要聊明白,还是要从原理来说起TIME-WAIT是TCP链接的一种状态,之前有写文章介绍过TCP的11中链接状态,有兴趣可以再去看下这张图整个展示了所有状态的转换过程,总共分为三个部分,上半部分是建立连接的过程,下面部分分成主动关闭和被动关闭的过程可以看到TIME_WAIT只在主动关闭的过程中出现,实际上TIME_WAIT是TCP为了解决复杂的网络问题提出的一种解决方案解决什么问题呢?看下面两个场景四次挥手中,A发FIN,B响应ACK,B再发FIN,A响应ACK实现连接的关闭。而如果A响应的ACK包丢失,B会以为A没有收到自己的关闭请求,然后会重试向A再发FIN包。如果没有TIME_WAIT状态,A不再保存这个连接的信息,收到一个不存在的连
点赞 3
浏览 4k
什么是SNI?  传统的应用场景中,一台服务器对应一个IP地址,一个域名,使用一张包含了域名信息的证书。随着云计算技术的普及,在云中的虚拟机有了一个IP,对应多个域名,使用多张证书的应用场景,SNI技术应运而生。SNI(ServerNameIndication),即实现了一个服务器使用多个域名证书的TLS扩展,支持用户配置多个域名证书。SNI请求特点  HTTP请求的Host字段在请求的Header中。发起HTTPS请求时,在TLS握手阶段,还无法进行HTTP数据的解析,此时TLS协议的ClientHello字段新增了一个ServerName字段,请求的客户端可以通过这个字段填充请求的Host信息,而服务端在TLS握手阶段就可以选择请求处理的证书,实现SNI的功能。Nginx支持的配置  Nginx支持SNI,允许在同一个TLS服务端口下,配置不同的域名,用户通过请求不同的证书域名,可返回相应的upstream响应结果。  本示例配置了一个证书域名为“lwl.test.com”的单向
点赞 1
浏览 5.4k