為什麼我們應該盡快支持ALPN?

昨天有位朋友在微信上發過來一個鏈接:The day Google Chrome disables HTTP/2 for nearly everyone: May 31st, 2016(中文翻譯)。看標題這篇文章說的是Google Chrome即將大面積禁用HTTP/2,這究竟是怎麼回事呢?本文為你揭曉答案。

先來回顧一下,瀏覽器在訪問HTTPS網站時,如何得知服務端是否支持HTTP/2?答案是藉助HTTP/2的協議協商機制:在HTTP/2 Over HTTP中,可以使用HTTP的Upgrade機制進行協商;而對於HTTP/2 Over TLS,可以使用TLS的NPN或ALPN擴展來完成協商。HTTP/2的這兩種協商方式,不了解的同學請看《談談HTTP/2的協議協商機制》,這裡不再贅述。
當前所有瀏覽器,都只支持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,當前主流服務器操作系統基本都沒有內置這個版本。以下是一份粗略的統計(via):

操作系統 內置OpenSSL 版本
CentOS 5 0.9.8e
CentOS 6 1.0.1e
CentOS 7 1.0.1e
Ubuntu 14.04 LTS 1.0.1f
Ubuntu 16.04 LTS 1.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 Google Chrome 很快要大面积禁用 HTTP/2,这究竟是怎么一回事呢?本文为你揭晓答案。

來源: 为什么我们应该尽快支持 ALPN? | JerryQu 的小站