活到老学到老  

记录遇到问题的点点滴滴。

为什么我们应该尽快支持 ALPN?

7年前发布  · 1156 次阅读
  openssl  NPN  ALPN 

当前所有浏览器,都只支持 HTTP/2 Over TLS。也就是说,浏览器和服务端都支持 NPN 或 ALPN 协商,是用上 HTTP/2 的大前提。本文重点讨论 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 明文发给客户端;

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

OpenSSL 1.0.2 开始支持 ALPN,当前主流服务器操作系统基本都没有内置这个版本。以下是一份粗略的统计:

操作系统内置 OpenSSL 版本
CentOS 50.9.8e
CentOS 61.0.1e
CentOS 71.0.1e
Ubuntu 14.04 LTS1.0.1f
Ubuntu 16.04 LTS1.0.2g
Debian 7 (Wheezy)1.0.1e
Debian 8 (Jessie)1.0.1k

这份表格列举的系统中,只有最近刚发布的 Ubuntu 16.04 才内置了支持 ALPN 的 OpenSSL 1.0.2。也就是说,直接使用系统 OpenSSL 库的 Web Server,极有可能不支持 ALPN 扩展。

去年,Google 在 Chrome 47 中移除了对 NPN 的支持,只支持 ALPN,但很快就引发一大批 HTTP/2 网站的抱怨。最终,Google 不得不在接下来的版本中又 重新启用了 NPN

半年后的今天,Google 又一次决定在 Chrome 51 中移除 NPN,预计 5 月底发布。这一次恐怕不会再反悔了。

本文开头那篇文章的作者悲观地认为:现在 OpenSSL 1.0.2 的普及程度仍然太低,Chrome 现在去掉对 NPN 的支持,仍然会导致一大批不支持 ALPN 的 HTTP/2 网站最终无法协商到 HTTP/2,只能降级使用 HTTP/1.1。

对此,我的观点是,该来的总会来,既然不能改变结果,不如早做准备。

通过 OpenSSL 命令行工具,可以快速查看自己的 HTTP/2 服务是否支持 ALPN 扩展:

openssl s_client -alpn h2 -servername imququ.com -connect imququ.com:443 < /dev/null | grep 'ALPN'

如果提示 unknown option -alpn ,说明本地的 OpenSSL 版本太低(可通过openssl version 查看),请升级到 1.0.2+。如果不方便升级,也可以使用 Qualys SSL Labs's SSL Server Test 这个在线工具来测试。

如果结果包含 ALPN protocol: h2 ,说明服务端支持 ALPN,不受 Chrome 51 去掉 NPN 的影响。

如果结果包含 No ALPN negotiated ,说明服务端不支持 ALPN,在 Chrome 51 中无法协商到 HTTP/2,需要尽快升级。

由于 OpenSSL 是系统基础库,大量其他软件都对它有依赖,如果直接升级系统自带的 OpenSSL,很容易引发各种问题。更为稳妥的做法是在编译 Web Server 时自己指定 OpenSSL 的位置。例如,我在《 本博客 Nginx 配置之完整篇 》这篇文章中提供的 Nginx 编译步骤中,就通过 --with-openssl 指定了新版 OpenSSL 源码路径,这样编译出来的 Nginx 就会用上最新的 OpenSSL 库。

如果你在用 LibreSSL 做为 Web Server 的 SSL 库,需要升级到 2.1.3+ 才支持 ALPN。

另外 Chrome 51 也会 彻底移除对 SPDY 的支持 ,如果你的网站还只支持 SPDY,趁这个机会直接升级到 HTTP/2 + ALPN 吧。