HTTP/3 + QUIC 的效率問題

前天看到討論蠻熱烈問題,提到了 HTTP/3 + UDP-based 的 QUIC 的效率比起 HTTP/2 + TCP-based 的 TLS 慢很多的問題:「QUIC is not quick enough over fast internet (acm.org)」,原文在「QUIC is not Quick Enough over Fast Internet」,如果要看 PDF 的話可以看預印本上的「QUIC is not Quick Enough over Fast Internet」。

之所以會有這麼多討論,是因為這篇文章說 HTTP/3 + QUIC 得到的效果與當初宣稱的完全相反,在所有的測試下都比 HTTP/2 + TLS 慢很多。

包括了在高速的網路下差了 45.2% (而且是網路愈快差距愈大):

We find that over fast Internet, the UDP+QUIC+HTTP/3 stack suffers a data rate reduction of up to 45.2% compared to the TCP+TLS+HTTP/2 counterpart. Moreover, the performance gap between QUIC and HTTP/2 grows as the underlying bandwidth increases.

以及在輕量的使用下也是 HTTP/2 + TLS 比較快,這邊提到包括各種桌機與手機環境,以及各種瀏覽器:

We observe this issue on lightweight data transfer clients and major web browsers (Chrome, Edge, Firefox, Opera), on different hosts (desktop, mobile), and over diverse networks (wired broadband, cellular).

讀完 PDF 的分析後,看起來是因為 TCP 大家花了很多精力在上面最佳化 50 年了,這邊累積的資產不只是軟體層級上面的最佳化,OS 與硬體上面也是有很多 offload 幫助。

而自己幹輪子的結果就是軟體層也還缺很多東西,硬體層也不支援新的協定...

Chrome 停止信任 Entrust 憑證的計畫

Hacker News 上看到「Entrust Certificate Distrust (googleblog.com)」這個討論,Google 決定要停止信任 Entrust 頒發的憑證:「Sustaining Digital Certificate Security - Entrust Certificate Distrust」。

快速翻了一下 Google 列出來在 Mozilla Bug List 上面的記錄 (在這裡),應該是出太多包,而且有些包給的解釋又不能說明出包的理由?

我拉了一下 Let's Encrypt 的情況,可以看到是兩種不同的情境:「這邊」,或是 GlobalSign:「這邊」。

目前的計畫是在下個 stable 版開始設限 (現在 stable 是 126,目前公告 127 開始擋),但給了四個月的期限,仍然會認 Entrust 在 2024/10/31 前發的憑證:

TLS server authentication certificates validating to the following Entrust roots whose earliest Signed Certificate Timestamp (SCT) is dated after October 31, 2024, will no longer be trusted by default.

因為有 Certificate Transparency (CT) 的關係,所有的簽署資料都會是公開可以查的,所以 Hacker News 上面有人整理出來有受到影響的網站... 看起來是把抓回來的資料丟到 ClickHouse 上分析:「SELECT rank, domain, certificate_issuer FROM minicrawl_processed WHERE startsWith(certificate_issuer, 'Entrust') AND date = today() ORDER BY rank::UInt32」。

裡面可以看到許多知名的網站 (畢竟還是 Entrust),這點從「Market share trends for SSL certificate authorities」這邊可以看得出來,雖然跟前面幾家比起來算小,但至少還是在榜上。

來等看看 MozillaApple 的動作,會不會有更嚴格的 distrust 的行為 (提前?),畢竟讓他再做四個月的生意也是很危險?

API 不該自動 HTTP 轉到 HTTPS

在「API Shouldn't Redirect HTTP to HTTPS (jviide.iki.fi)」這邊看到的,原始文章在「Your API Shouldn't Redirect HTTP to HTTPS」這邊。

仔細想一下沒錯,API 應該要一開始就被正確設定,所以要 fail fast。

另外在 id=40505525 這邊還提到了透過 HTTP 的 token 會自動被 revoke 掉,這個作法也很漂亮:

The Stack Exchange API used to revoke API keys sent over HTTP (and return an error message), which is my favorite way to handle this.

另外一個想法是直接不聽 port 80,不過這點在 Endpoint 的 IP 不是自己專用的情況下不一定能做到 (像是大多數的 CDN 環境)。

的確有戳中我手上預先準備好的 nginx config,來想看看怎麼改會比較好... 也許改成整個傳回 403,只開 /.well-known/acme-challenge/ACME (Let's Encrypt) 的 HTTP-01 認證可以過。

OpenSSL 決定把 release site 改到 GitHub 上

OpenSSL 宣佈了之後會以 GitHub 為主要發佈平台:「Releases Distribution Changes」。

舊的 ftp & rsync 以及 git protocol (9418/tcp 的協定) 都打算淘汰掉:

We’re no longer using our old ftp, rsync, and git links for distributing OpenSSL. These were great in their day, but it’s time to move on to something better and safer.

其中 FTP 與 rsync 都已經停掉了,接下來是今年六月要停掉 ftp.openssl.org 的 HTTPS 介面以及 git.openssl.org 的 git protocol:

ftp://ftp.openssl.org and rsync://rsync.openssl.org are not available anymore. As of June 1, 2024, we’re also going to shut down https://ftp.openssl.org and git://git.openssl.org/openssl.git mirrors.

然後主力轉戰到 GitHub 上面:

GitHub is becoming the main distributor of the OpenSSL releases.

算是省事的作法,畢竟自己弄 infrastructure 不算太輕鬆

另外 OpenSSL 畢竟是個歷史頗久的軟體了,有「遵循古法」所以 release 都會有 PGP/GPG sign,這部分如果還是獨立於 GitHub 平台的話就沒什麼問題,代表還是有非 HTTPS 的 integrity 方法可以確認檔案沒被抽換過。

(但如果綁進 CI/CD 流程的話就廢了?)

Common Media Client Data (CMCD)

Amazon CloudFront 的公告看到的東西:「Amazon CloudFront now supports Common Media Client Data (CMCD) fields in real-time logs」。

CMCD (Common Media Client Data) 是一個私有的 log format,可以讓 client 透過 HTTP(S) header 回報狀態,所以 AWS 這邊有提到你可以設定讓 CloudFront 記錄下來,然後透過其他軟體分析:

Previously, CloudFront logged CMCD parameters as part of the full query string log field, or the HTTP headers log field. Now, you can simply select to include specific CMCD parameters in your real-time logs and save on compute needed to search and extract the CMCD key-value pairs, and reduce the data set for your log analysis.

現在 CloudFront 則是支援判讀做一些處理:

Starting today, you can enable Common Media Client Data (CMCD) fields in your CloudFront real-time logs. You can select key client-side performance parameters and CloudFront delivery performance parameters in the same log record. This can help you correlate variations in Quality of Experience (QoE) for your viewers to CloudFront performance at the granularity of single viewer sessions, simplifying the troubleshooting of QoE issues that impact your viewers engagement.

看了一下就是定義一些欄位,用 JSON 包起來後讓 client 打回伺服器端,可以利用這些資訊動態從伺服器端調整策略,而不像以前主要的調整策略都放在 client 端。

Chrome 124 啟用了 X25519Kyber768

在「Google Chrome's new post-quantum cryptography may break TLS connections」這邊看到的,出自「Q1 2024 Summary from Chrome Security」這邊的公告。

Chrome 124 預設啟用 X25519Kyber768 了:

After several months of experimentation for compatibility and performance impacts, we’re launching a hybrid postquantum TLS key exchange to desktop platforms in Chrome 124. This protects users’ traffic from so-called “store now decrypt later” attacks, in which a future quantum computer could decrypt encrypted traffic recorded today.

如果遇到問題的話可以在 chrome://flags 裡面的 #enable-tls13-kyber 關閉後重開瀏覽器... 不過應該是還好,大多數的 HTTPS server 應該都沒有實作 X25519Kyber768,就算是 Cloudflare 應該預設也是關的。

測 IPv4 NAT VPS,以及架設 HTTPS Proxy

因為 AWS 開始收 Public IPv4 address 費用的關係 (而且頗貴,參考「AWS 將開始收取 IPv4 的 Public IP 費用」),我把其中一台主機改成只有 IPv6 address 後遇到不少問題 (在「把 AWS 上的 EC2 instance 改成 IPv6-only」這邊)。

由於有 proxy 的需求,剛好找機會玩一下 IPv4 NAT VPS... 這種 VPS 最基本的大概就是會給一個 IPv4 address 上 non-standard port 當作 SSH port,讓你可以連進去管理;另外通常會給 port forwarding 的功能,而且是固定不能換的,讓你可以開一些 port 出來用。

我的用途是 IPv6 address 的 proxy,所以要找有給固定的 IPv6 address 的,另外希望跑在日本,這樣其他用途也比較方便。

過年期間翻了一下找到 NAT VPS,有 256MB 跑個 proxy 類的應用應該還 OK,實際上是 256MB RAM + 64MB swap 的 OpenVZ 類環境,kernel 有到 5.2.0 還算堪用,上面可以選 Ubuntu 22.04 安裝。

費用的部分 US$7/year 還行,網路上是有看到 128MB RAM 的 機器,但這樣連裝東西都綁手綁腳的,太容易 OOM。

(剛拿到機器的時候還試著裝 Percona Server for MySQL,結果就 OOM 跑不完 setup 的流程,看起來得自己改設定混過去,但只是想確認 256MB RAM + 64MB swap 可以弄到什麼程度,就反安裝了...)

在上面把想測的東西測試完後,實際的 proxy 設定比較簡單... 先設定一個只有 IPv6 address 的 domain 申請 Let's Encrypt 的 SSL certificate,然後掛給 Squid 用。

然後在 IPv6-only 的機器上用 curl -v --proxy https://username:password@proxy-jp.example.com:12345/ https://home.gslin.org/robots.txt 確認沒問題後就可以把服務都掛過去。

有些服務會吃環境變數 HTTP_PROXYHTTPS_PROXY,有些是在設定檔內設定,基本上都是照著文件設就可以了。

我遇到的 application & library 都可以吃 HTTPS Proxy 協定,就沒什麼大問題... 如果有遇到不行的,也可以考慮在 Squid 裡面直接放行特定的 IPv6 address。

Firefox 與 Chrome 處理 Intermediate CA 的不同方式

Fediverse 上看到「The recording of my "Browsers biggest TLS Mistake" lightning talk at #37C3」這個,這是出自 37C3 的 lightning talk,影片不長,只有五分鐘,可以在「Browsers biggest TLS mistake」這邊看到。

正常的 HTTPS server 會送出 Intermediate CA certificate 與自己的 TLS certificate:

當伺服器端沒有設定好,通常是只送出自己的 TLS certificate:

這種情況在 Firefox 裡有處理,軟體本身會預載所有的 Intermediate CA 避免這種問題 (當然會需要跟著軟體更新),這點在三年前有提到過:「Firefox 試著透過預載 Intermediate CA 降低連線錯誤發生的機率?」,也就是這張投影片提到的情況:

Chrome 則是去看目前的 cache 資料,找看看是不是在其他地方有看到適合的 Intermediate CA 可以接起來:

這好像可以解釋為什麼之前遇到類似的問題的時候,在 Chrome 上面會需要進 chrome:// 裡面清東西才能重製...

穿越 Firewall 的作法

先看到「SSH over HTTPS (trofi.github.io)」這篇,原文「SSH over HTTPS」講怎麼利用 HTTPS 加上 CONNECT 指令穿過去。

作者有先介紹背景,他需要在醫院待個幾天,而醫院有免費的 WiFi 可以上網,但限制很多,基本上 TCP 的部分只有 80/tcp 與 443/tcp 會通,另外他有行動網路可以用 (但應該不是吃到飽的?),可以當作在現場直接設定 bypass 機制的工具:

I planned to spend 1-2 days in the hospital and did not plan to use the laptop.But now I am stuck here for the past two weeks and would like to tinker on small stuff remotely. The hospital has free Wi-fi access.

The caveat is that hospital blocks most connection types. It allows you only to do HTTP (TCP port 80) and HTTPS (TCP port 443) connections for most hosts. DNS (UDP port 53) and DoT (TCP port 853) seem to work as well at least for well-known DNS providers.

But SSH (TCP port 22 or most other custom ports) is blocked completely.

I wondered how hard would it be to pass SSH through HTTP or HTTPS. I had a GSM fallback so I could reconfigure remote server and try various solutions.

作者的方法就是在 TLS/SSL connection 上面跑 SSH,以前幹過,但就如同 comment 裡面提到的,Cisco 的 AnyConnect (主要是用 open-source client 的 OpenConnect 以及 open-source server 的 ocserv) 比較彈性,而且 AnyConnect 的協定會自動嘗試 UDP-based 的 DTLS,傳輸效率會比 TCP-based 的協定好,另外在 iOS 上可以直接裝 app store 裡面 Cisco 官方的 client 來用。

但從作者的其他文章看起來應該也是熟門熟路了,會這樣做應該是手上有 HTTPS 的 apache server 可以設定來用。

另外作者雖然沒寫出來,但想法應該是有 SSH 就可以在 command line 透過 -D 生出 SOCKS 服務當 proxy 讓其他程式使用,常見的應用程式大多都支援。

應該就是臨時要在醫院裡面待個一兩天時的暫時性方案,如果常態會遇到的話應該是會架 ocserv 來繞...