- ウェブサイトが HTTPS DNSレコード に HTTP/3 対応を公開すると、ブラウザは最初の接続から QUIC/HTTP/3 を使用でき、接続の往復を 1 回減らせる
- ブラウザはまず HTTP/1 または HTTP/2 で接続して
Alt-Svc ヘッダーを読むか、DNS 参照の段階で HTTPS レコードを読んで HTTP/3 対応 を見つける
- Firefox Nightly の測定では、接続の 31.4% が
Alt-Svc ヘッダーだけで HTTP/3 を告知しており、この場合 HTTP/3 は以後の接続でしか使われない {p:31}
- HTTPS レコードには
alpn, ech, ipv4hint, ipv6hint を含められ、最初の接続のプロトコル選択、ECH、アドレスヒントの提供を DNS 応答内で処理できる
- HTTPS レコードは既存クライアントの動作に追加される形で機能し、
Alt-Svc はレコードを受け取れなかったクライアント向けの フォールバック として維持すべき
主要な概念
- ブラウザがサイトの HTTP/3 対応を見つける方法は 2 つある
- まず HTTP/1 または HTTP/2 で接続した後、
Alt-Svc HTTP ヘッダーを読む方法
- 接続を開く前に HTTPS DNSレコード の参照で直接確認する方法
- HTTPS DNSレコードを使う場合に限り、ブラウザは最初の接続から HTTP/3 を使え、QUIC によって往復を 1 回減らせる
- Firefox Nightly の最近のビルド平均推定では、接続の 31.4% は DNS ではなく
Alt-Svc ヘッダーだけで HTTP/3 を告知していた
- 現在このサーバーまでの 1 往復は約 28ms と測定されている
ドメイン確認
- savearoundtrip.com は h3、IP ヒント、ECH を含む HTTPS レコードを自前で公開している
- 入力したドメインの HTTPS レコードは、ブラウザ上で Cloudflare の DNS-over-HTTPS エンドポイント経由で参照される
Alt-Svc ヘッダーと実際の HTTP/3 ハンドシェイクはブラウザから直接確認できない
- CORS がクロスオリジンのヘッダーを隠す
- ブラウザがコールドな QUIC 接続を強制的に作れない
- 入力したドメインは小さな オープンソースのバックエンド に送られ、そのバックエンドは
Alt-Svc の確認と実際の HTTP/3 ハンドシェイク確認だけを行う
- データは保存されず、実際の HTTP/3 ハンドシェイクは quic-go で行われる
1回の往復のコスト
- 1 回の往復とは、サーバーへメッセージを送り、再び受け取るまでの過程であり、光の速度に制約される
- おおよその往復時間は、都市内で 5〜20ms、国をまたぐと 40〜80ms、大洋を越えるかモバイルネットワークでは 150ms 以上になる
- Cloudflare Radar はリアルタイムの数値を提供する
- 約 100ms 未満のインタラクションは即時に感じられ、それを超えると待たされている感覚が出る
- このページは接続開始から初回ペイントまで約 41ms かかり、このサーバーまでのリアルタイムの 1 往復は約 28ms である
- 公開された HTTPS レコードにより、ブラウザは最初の接続で TCP の代わりに QUIC を使えるため、その往復時間を削減できる
- このページは静的で小さいため全体の時間予算も小さいが、実際のアプリでも 1 回の往復は最前段で支払う固定コストであり、複数のオリジンに対して繰り返し発生しうる
無駄になる往復
Alt-Svc は RFC 7838 の HTTP レスポンスヘッダーである
- クライアントが
Alt-Svc を読むには、すでに TCP 接続を開き、TLS ハンドシェイクを完了し、HTTP/1.1 または HTTP/2 でリクエストを終えていなければならない
- この方法では、サーバーが HTTP/3 もサポートしていることを前回の接続の後でしか知れないため、HTTP/3 へのアップグレードは次回の接続で行われる
- RFC 9460 の HTTPS レコード は、同じ HTTP/3 対応シグナルを DNS に載せる
- クライアントはもともと行う名前解決の途中でこのレコードを読むため、接続を開く前に HTTP/3 対応を知ることができる
- HTTPS DNSレコードを使えば、最初の接続から QUIC/HTTP/3 を使え、先に HTTP/1 または HTTP/2 の接続を消費する必要がない
HTTPS レコードが優れている理由
-
最初のバイトより前に HTTP/3 を発見
alpn SvcParam は、エンドポイントが対応する ALPN プロトコル ID を列挙する
- 例として
h3 の HTTP/3 と h2 がある
- この情報は名前解決の間に届くため、クライアントは以前の HTTP/1 または HTTP/2 接続の後で h3 を知るのではなく、最初の接続から QUIC を選べる
-
ECH: Encrypted Client Hello
ech SvcParam は、エンドポイントの ECHConfigList 公開鍵を含む
- ECH は、SNI サーバー名を含む TLS ClientHello を暗号化し、ネットワーク観測者から訪問先サイトが見えないようにする
- この問題は最初の ClientHello を送る前に公開鍵が必要なため、HTTP ヘッダーでは解決できない
- まだ接続が存在しない時点で鍵が必要なので、DNS の HTTPS レコードのような帯域外チャネルだけが ECH をブートストラップできる
- HTTPS RR がなければ ECH も使えない
-
IP ヒントでより速く接続開始
- Happy Eyeballs v3 は A、AAAA、HTTPS の問い合わせを並列に行う
- HTTPS 応答内の
ipv4hint と ipv6hint は、A/AAAA レコードより先に届いた場合、接続候補アドレスを提供する
- クライアントは A/AAAA 応答を待つ代わりに、ヒントアドレスへ接続を開始できる
- A/AAAA レコードはその後も到着し、到着後はヒントを置き換える
Alt-Svc にはこれに相当する機能がない
-
単一の権威ソースとキャッシュ
- 到達性情報は通常の TTL を持つ DNS 内に保持できる
Alt-Svc 方式では、情報がオリジンごとの HTTP ヘッダーキャッシュに分散し、max-age のジレンマが生じる
max-age が長すぎるとクライアントは古い代替先を使い続け、短すぎると以前のプロトコルへ戻る頻度が増える
- ブラウザはいずれにせよ DNS 参照を行うため、HTTPS レコードならその参照が最適な接続情報も一緒に渡せる
-
機能比較
- | 機能 |
Alt-Svc HTTP ヘッダー (RFC 7838) | HTTPS RR (RFC 9460) |
- | --- | --- | --- |
- | 学習タイミング | 接続全体の後 | DNS 確認中 |
- | 最初の接続で h3 | 不可 | 可能 |
- | IP ヒント | なし |
ipv4hint / ipv6hint |
- | ECH 鍵 | 不可能 |
ech パラメータ |
- | 真実の供給源 | HTTP ヘッダーと脆弱なキャッシュ | TTL 付き DNS |
実際のブラウザ測定
- Firefox Nightly の測定では、ブラウザは HTTP/3 対応を
Alt-Svc HTTP レスポンスヘッダーまたは HTTPS DNSレコードで知ることができる
Alt-Svc はすでに接続した後でしか見えず、HTTPS DNSレコードは接続前に見える
- すべての接続は 4 つのグループのいずれかに属する
- Neither は HTTP/3 がまったく告知されていない接続
- Alt-Svc only はヘッダーだけで告知され、最初の接続で HTTP/3 を使えなかった接続
- HTTPS record only は DNS で告知され、最初の接続から HTTP/3 に行けた接続
- Both は DNS とヘッダーの両方で告知された接続
- 測定された接続比率は Neither 59.8%、Alt-Svc only 31.4%、HTTPS record only 2.8%、Both 6% である {b:60,31,3,6}
- この 4 グループで全接続を完全に網羅するため、合計は 100% になる
- HTTPS record only と Both は利用可能な HTTPS レコードがあり、Alt-Svc only はレコードがあれば削減できた空白である
- 数値は Firefox Nightly の GLAM ヒストグラムから再構成した接続ごとの推定値であり、最近のビルド平均なので近似値である
HTTPS レコードの公開
- h3 とアドレスヒントを告知する ServiceMode の HTTPS レコードは 1 行で公開できる
; zone file (BIND-style)
example.com. 3600 IN HTTPS 1 . alpn="h3,h2" ipv4hint=203.0.113.10 ipv6hint=2001:db8::10
example.com. はレコードを公開する名前で、末尾のドットは完全修飾ドメイン名を意味する
3600 はリゾルバがレコードをキャッシュできる秒単位の TTL である
IN はすべてのウェブレコードと同じインターネット DNS クラスである
HTTPS は RFC 9460 のレコードタイプである
1 は優先度で、1 以上はパラメータを含む ServiceMode を示す
0 は別の対象だけを指す AliasMode である
. は対象ホストであり、所有者名そのものである example.com を意味する
alpn="h3,h2" はサーバーが対応するプロトコルを望ましい順で列挙し、h3 は HTTP/3、h2 は HTTP/2 である
ipv4hint と ipv6hint は、クライアントが A/AAAA 参照と並行して即座に接続開始できるアドレスである
- Cloudflare、Route 53 など大半のマネージド DNS プロバイダは HTTPS レコードタイプを直接提供している
- ドメインが対応しているかは checker で確認できる
実際の HTTPS レコードに含まれる機能
- Firefox Nightly では、HTTPS レコードを見た接続のうち各機能を含む比率が測定された
- ALPN の h3 は 80.3% で、IPv4 ヒントは 52.9% だった
- IPv6 ヒントは 49.4% で、ECH は 12.8% だった {b:80,53,49,13}
- これらの数値は GLAM ヒストグラムから再構成した接続ごとの推定値であり、近似値である
FAQ
-
CDN が自動で公開するか
- 一部の CDN は HTTPS レコードを自動公開する
- Cloudflare はプロキシされたゾーンに対して
alpn="h3" を含む HTTPS レコードを自動提供する
- 他の CDN ではユーザーが手動で設定する必要がある
- 最も手早い確認方法は上の ドメイン確認 を使うこと
-
HTTPS レコードは古いクライアントを壊すか
- HTTPS レコードを理解できないクライアントはそのレコードを無視し、通常の A/AAAA 参照に戻る
- それでも
Alt-Svc ヘッダーを送っていれば、そのようなクライアントはそのヘッダーも利用できる
- HTTPS レコードの公開は既存動作に追加する方式である
-
再訪時はどうなるか
- クライアントが一度 HTTP/3 で通信した後は、再訪時に QUIC 接続を 0-RTT で再開できる
- 0-RTT ではハンドシェイクの往復なしで最初のリクエストをすぐ送れる
- HTTPS レコード自体も他の DNS 応答と同様に TTL の間キャッシュされるため、再訪時は通常参照自体も省略される
-
どのブラウザが HTTPS レコードを使うか
- 主要エンジンは HTTPS レコードをデフォルト有効でサポートしている
- 訪問者が DNS-over-HTTPS を有効にしているかどうかに関係なくレコードを読む
- Safari は OS のリゾルバを使う
- Chrome は内蔵リゾルバを使い、DoH または通常の DNS 経由で動作する
- Firefox は両方の方式を使える
-
Alt-Svc ヘッダーを削除すべきか
Alt-Svc ヘッダーは削除すべきではない
- 古いクライアントや HTTPS レコードを渡さないリゾルバまたはネットワーク向けのフォールバックとして送り続ける必要がある
- HTTPS レコードを読むブラウザは DNS から HTTP/3 を知るため、HTTP/3 発見のために 1 回の往復を使わずに済む
1件のコメント
Lobste.rsのコメント
終わったら HTTPS DNSレコード を設定する予定
digは 9.10.6 なので、このレコードタイプより古いバージョンのようだAppleはもっと新しい
digを提供すべきだと思うが、macOSでDNSを引くときに好んで使うツールがあるのか気になる複数のプラットフォームで doggo をよく使っている
完璧ではないが、全体的にかなりうまく動いていて、必要な機能をかなり満たしてくれる
Homebrewで入れた
ldnsのdrillを使っているQUICをサポートしていなくても同じだ
CSSがLLMから出てきたように見えるかもしれない、という程度がほぼすべてだ
それに文章が冗長だ。繰り返しや役に立たない内容、妙な可視化が多くて、約1700語でページ全幅の長さが7300pxを超えている
500語、図2つ、全体の長さ2000px未満くらいに削れば、ずっと良くなると思う