Cloudflare 利用自家平台分析過去一年 HTTP/3 的使用率:「Examining HTTP/3 usage one year on」。
首先是整體的使用率,看起來反而沒有什麼太大的變化?一上線就已經是巔峰的感覺?

然後各種 bot (像是搜尋引擎的 bot 或是 social media 的 bot) 看起來幾乎都沒有用 HTTP/3,少數的量應該都是實驗性質居多,唯一的例外是 LinkedIn 有試著在導入,可以看到慢慢的爬升:

看起來不算太順?
幹壞事是進步最大的原動力
Cloudflare 利用自家平台分析過去一年 HTTP/3 的使用率:「Examining HTTP/3 usage one year on」。
首先是整體的使用率,看起來反而沒有什麼太大的變化?一上線就已經是巔峰的感覺?
然後各種 bot (像是搜尋引擎的 bot 或是 social media 的 bot) 看起來幾乎都沒有用 HTTP/3,少數的量應該都是實驗性質居多,唯一的例外是 LinkedIn 有試著在導入,可以看到慢慢的爬升:
看起來不算太順?
Hacker News 上看到「Nginx 1.25.0: experimental HTTP/3 support (nginx.org)」這則消息,從 nginx 1.25.0 開始可以用 HTTP/3。
與 HTTP/2 最大的差異就是從以往的 TCP 改到 UDP 上了,這是基於 QUIC 的經驗弄出來的東西...
nginx 的支援算是等了一陣子了,不過沒有當初 HTTP/1.1 到 SPDY 的進步這麼明顯,我自己就沒有跟的那麼緊了。
這樣以後 office firewall 預設應該會再開 443/udp?
Hacker News 上看到「Why your website should be under 14kB in size」這篇,對應的討論在「A 14kb page can load much faster than a 15kb page (endtimes.dev)」,在講網頁大小 14KB/15KB 的速度差異比 15KB/16KB 大很多的問題:
What is surprising is that a 14kB page can load much faster than a 15kB page — maybe 612ms faster — while the difference between a 15kB and a 16kB page is trivial.
原因是 TCP slow start 造成的:
This is because of the TCP slow start algorithm.
而網頁這邊 TCP slow start 目前大多數的實做都是 10 packets 後發動:
Most web servers TCP slow start algorithm starts by sending 10 TCP packets.
然後再組合 1500 bytes/packet 以及 overhead,就差不多是 14KB 了:
The maximum size of a TCP packet is 1500 bytes.
This this maximum is not set by the TCP specification, it comes from the ethernet standard
Each TCP packet uses 40 bytes in its header — 16 bytes for IP and an additional 24 bytes for TCP
That leaves 1460 bytes per TCP packet. 10 x 1460 = 14600 bytes or roughly 14kB!
然後 HTTP/3 也可以看到類似的設計 (出自「QUIC Loss Detection and Congestion Control」:
Sending multiple packets into the network without any delay between them creates a packet burst that might cause short-term congestion and losses. Implementations MUST either use pacing or limit such bursts to the initial congestion window, which is recommended to be the minimum of 10 * max_datagram_size and max(2* max_datagram_size, 14720)), where max_datagram_size is the current maximum size of a datagram for the connection, not including UDP or IP overhead.
算是一個小知識... 但對於現在肥滋滋的網頁效果來說就沒辦法了,而且考慮到大一點的網站會在一個 TCP 連線裡面可能會傳很多 request,其實早就超過 TCP slow start 的門檻了。
雖然 HTTP/3 還沒有進到 Standard Track,但看到 CloudFront 宣佈支援 HTTP/3 了:「New – HTTP/3 Support for Amazon CloudFront」。
只要在 CloudFront 的 console 上勾選起來就可以了:
看了看 RFC 9114: HTTP/3 文件裡的描述,client 可以試著建立 UDP 版本的 QUIC 連線,但要有機制在失敗時回去用 TCP 的 HTTP/2 或是 HTTP/1.1:
A client MAY attempt access to a resource with an "https" URI by resolving the host identifier to an IP address, establishing a QUIC connection to that address on the indicated port (including validation of the server certificate as described above), and sending an HTTP/3 request message targeting the URI to the server over that secured connection. Unless some other mechanism is used to select HTTP/3, the token "h3" is used in the Application-Layer Protocol Negotiation (ALPN; see [RFC7301]) extension during the TLS handshake.
Connectivity problems (e.g., blocking UDP) can result in a failure to establish a QUIC connection; clients SHOULD attempt to use TCP-based versions of HTTP in this case.
另外一條路是在 TCP 連線時透過 HTTP header 告訴瀏覽器升級:
An HTTP origin can advertise the availability of an equivalent HTTP/3 endpoint via the Alt-Svc HTTP response header field or the HTTP/2 ALTSVC frame ([ALTSVC]) using the "h3" ALPN token.
像是這樣:
Alt-Svc: h3=":50781"
然後 client 就可以跑上 HTTP/3:
On receipt of an Alt-Svc record indicating HTTP/3 support, a client MAY attempt to establish a QUIC connection to the indicated host and port; if this connection is successful, the client can send HTTP requests using the mapping described in this document.
另外在 FAQ 裡面有提到啟用 HTTP/3 是不另外計費的,就照著本來的 request 費用算:
Q. Is there a separate charge for enabling HTTP/3?
No, there is no separate charge for enabling HTTP/3 on Amazon CloudFront distributions. HTTP/3 requests will be charged at the request pricing rates as per your pricing plan.
先開起來玩看看...
HTTP 的標準之前都是用新的 RFC 補充與修正舊的標準,所以整體讀起來會比較累,對於開始了解 HTTP 的人會需要交叉讀才能理解。
而這次 RFC 9110~9114 算是一次性的把文件全部重新整理出來,可以看到蠻多人 (以及團體) 都有丟出來對應的看法,這邊丟這兩篇:「A New Definition of HTTP」與「HTTP RFCs have evolved: A Cloudflare view of HTTP usage trends」。
而這五個 RFC,從名稱列出來就可以看出來命名簡單粗暴,把核心概念先拆出來講,然後再講不同 protocol 的部份:
而 Cloudflare 這邊提供了一些資料,可以看到三個 protocol 使用率都算高,而目前最高的是 HTTP/2:
另外比較特別的是 Safari 在 HTTP/3 的趨勢居然有倒縮的情況:
然後 bot 的部份幾乎大家都支援 HTTP/2 了,目前還沒看到太多 HTTP/3 的蹤跡,倒是 LinkedIn 的 bot 有個奇怪的 adoption 然後全部 rollback 的情況,而最近又開始少量導入了:
這次看起來淘汰了 (obsolete) 很多之前的文件,以後要引用得往這五份來引...
作者家裡拉了 25Gbps 的 Internet 後 (可以參考先前寫的「25Gbps 的家用 Internet」這篇),然後發現 Internet 上好像拉不動 25Gbps 的量,所以自己在家裡先測試了現在 HTTPS 的極限速度:「25 Gbit/s HTTP and HTTPS download speeds」。
Client 是 AMD 的 5600X,算是目前最新的世代;Server 則是 Intel 的 9900K,目前最新應該是 12 代;測試用 35GB 的檔案來測,然後使用 TCP BBR (這邊沒有特別講,目前 kernel 內建的還是 v1)。
在單條 HTTP 的情況下 curl + nginx 與 curl + caddy 都可以直接跑滿 (23.4Gbps),Go 的 net/http 會卡在 20Gbps 左右。
如果是多條 HTTP 的話都可以跑滿 23.4Gbps。
但到了 HTTPS 的情況下最快的是 Go + net/http,可以跑到 12Gbps;curl + nginx 剩下 8Gbps;接下來 curl + caddy 的部份只有 7.5Gbps,而 go + caddy 只有 7.2Gbps。
上到多條 HTTPS 的情況大家都可以跑滿 23.4Gbps,除了 go + caddy 只能跑到 21.6Gbps。
另外作者試著用 kTLS 把 TLS 的工作丟進 kernel,就不需要全部在 nginx 內處理,速度基本上沒有太大變化,主要是降低了 CPU loading:
In terms of download speeds, there is no difference with or without KTLS. But, enabling KTLS noticeably reduces CPU usage, from ≈10% to a steady 2%.
算是一個有趣的發現,如果目前的 HTTPS 想要在 25Gbps 上面單線直接跑滿,還需要再 tune 不少東西...
在 Hacker News Daily 上看到「Static torrent website with peer-to-peer queries over BitTorrent on 2M records (boredcaveman.xyz)」這個討論,作者試著在網頁上跑 SQLite + VFS + WebTorrent。
這好像是這陣子一連串的 combo 技累積出來的東西:
接下來就是文章作者把 HTTP Range 換掉,改用 BitTorrent 的 pieces 來處理,在網頁端的話就順勢拿 WebTorrent 來用,對於很熱門的網站來說還蠻有趣的設計,但也可以預期網頁的反應速度應該不會太快,偏 PoC...
看到 Cloudflare 宣佈支援 Discovery of Designated Resolvers (DDR):「Announcing experimental DDR in 1.1.1.1」。
看了一下這以後會是新的標準 (現在還在 draft),可以自動偵測現在用的 DNS resolver 是否支援 DNS over HTTPS 或是 DNS over TLS,如果有的話就 upgrade 到 DoH 或 DoT:
This document defines Discovery of Designated Resolvers (DDR), a mechanism for DNS clients to use DNS records to discover a resolver's encrypted DNS configuration.
目前的 spec 是去查 _dns.resolver.arpa
,下面第一個是支援 DoH 的回應,第二個則是支援 DoT 的回應:
_dns.resolver.arpa 7200 IN SVCB 1 doh.example.net ( alpn=h2 dohpath=/dns-query{?dns} )
_dns.example.net 7200 IN SVCB 1 dot.example.net ( alpn=dot port=8530 )
實際上拿 1.1.1.1 測試,在 Ubuntu 20.04 下用 dig 可以看到一堆亂碼 XDDD
;; ANSWER SECTION: _dns.resolver.arpa. 300 IN TYPE64 \# 104 0001036F6E65036F6E65036F6E65036F6E6500000100060268320268 330003000201BB000400080101010101000001000600202606470047 00000000000000000011112606470047000000000000000000100100 0700112F646E732D71756572797B3F6E616D657D _dns.resolver.arpa. 300 IN TYPE64 \# 81 0002036F6E65036F6E65036F6E65036F6E65000001000403646F7400 03000203550004000801010101010000010006002026064700470000 00000000000000111126064700470000000000000000001001
改用 Docker 開了 Ubuntu 22.04 (jammy) 的 image 後,裡面的 dig 可以用 SVCB
查詢 (本來的 type64 也還是會動),另外也把內容解出來了:
;; ANSWER SECTION: _dns.resolver.arpa. 300 IN SVCB 1 one.one.one.one. alpn="h2,h3" port=443 ipv4hint=1.1.1.1,1.0.0.1 ipv6hint=2606:4700:4700::1111,2606:4700:4700::1001 key7="/dns-query{?name}" _dns.resolver.arpa. 300 IN SVCB 2 one.one.one.one. alpn="dot" port=853 ipv4hint=1.1.1.1,1.0.0.1 ipv6hint=2606:4700:4700::1111,2606:4700:4700::1001
這樣就不需要寫死在系統內,但要注意這樣還是會有 attacker 擋住讓你 upgrade 的問題...
看到 AWS 公告提供 CloudFront 的 origin subnet 資訊 (AWS-managed prefix list) 讓管理者可以用:「Amazon VPC now supports an AWS-managed prefix list for Amazon CloudFront」。
以往會自己去「AWS IP address ranges」這邊提供的 JSON 檔案定時撈出來再丟到 managed prefix list 裡面,這次的功能等於是 AWS 自己管理這個 prefix list 讓管理者使用。
馬上想的到的用途就是 HTTP/HTTPS port 了,只開放給 CloudFront 的伺服器存取:
Starting today, you can use the AWS managed prefix list for Amazon CloudFront to limit the inbound HTTP/HTTPS traffic to your origins from only the IP addresses that belong to CloudFront’s origin-facing servers. CloudFront keeps the managed prefix list up-to-date with the IP addresses of CloudFront’s origin-facing servers, so you no longer have to maintain a prefix list yourself.
要注意的是這不應該當作唯一的 ACL 手段,因為其他人也可以建立 CloudFront distribution 來穿透打進你的 origin server。
另外有個比較特別的地方,這個 prefix list 的權重很重,使用他會算 55 條 rule 的量,在 security group 內很容易撞到 60 條的限制,在 route table 裡面則是直接撞到 50 條的限制;不過這兩個限制都可以跟 AWS 申請調昇:
The Amazon CloudFront managed prefix list weight is unique in how it affects Amazon VPC quotas:
- It counts as 55 rules in a security group. The default quota is 60 rules, leaving room for only 5 additional rules in a security group. You can request a quota increase for this quota.
- It counts as 55 routes in a route table. The default quota is 50 routes, so you must request a quota increase before you can add the prefix list to a route table.
如果 HTTP 一條,HTTPS 也一條,那就會算 110 rules 了,有暴力的感覺...
在 Hacker News 首頁上看到 Mitmproxy 7 的消息:「Mitmproxy 7」。
比較重要的功能應該就是可以針對任意的 TLS 連線攔截分析了:
不過像是 STARTTLS
這類先在 plaintext 溝通,然後送出指令進入 TLS 的方式,目前就還沒支援:
Opportunistic TLS (STARTTLS) is not supported yet, but regular TCP-over-TLS just works!
另外是可以分析 WebSocket 內的傳輸資料:
應該是跑個 pip install -U mitmproxy
就可以升級了... (如果先前是用 pip 安裝的話)