ALTSVC

代替サービス (HTTP)

[103] HTTP代替サービス (alternative service) は、 QUIC への切り替えなどに用いられています。

仕様書

代替サービス

[27] 普通 HTTP資源へのアクセスは URL で指定された起源サーバーに接続して行いますが、 それとは異なるアクセス方法を起源サーバーが提供したい場合があり、 それを代替サービス (alternative service) と言っています。 より正確には、ある起源資源群に、 本来とは異なるプロトコルホストポートの組み合わせでアクセスできるとき、 起源代替サービスが利用可能であるといいます >>10

[31] 起源サーバーは、負荷が大きい時や、 クライアントにより近いサーバーがあるときに、 他のサーバーを使うようクライアントに求めたいことがあります。 >>10

[28] 起源サーバーは、 HTTP/2 など新しいプロトコルや、 TLS などセキュリティーを向上させたプロトコルを使ったアクセスを提供したいことがあります。 >>10

[29] 起源サーバーは、運用上、例えば SNI に対応しているかどうかなどで、 クライアント群を分類したいことがあるかもしれません。 >>10

[36] 代替サービスは、 (ALPNプロトコル名, RFC 3986 ホスト, RFC 3986 ポート) の組で表します。 >>10

[30] 代替サービス起源全体に適用されるものですから、 一部の資源のみに適用することはできません >>10

発見

[58] サーバーは、次の方法を使って代替サービス広告できます。

[59] 元々 Alternate-Protocol: ヘッダーが使われていましたが、 例によって IETF標準化された際に改称・非互換変更され、 Alt-Svc: となりました。

[111] クライアントは、サーバーからこれらを受信したら、 その情報を保持して代替サービスとして使います。

[42] 起源サーバー代替サービスも、 代替サービスを更新したり、消去したり、 新鮮寿命を伸ばしたりできます。 >>10

代替サービスキャッシュ

[45] クライアントは、キャッシュに、起源ごとの代替サービス群を保持します。

[37] 代替サービスは、次の状態を持ちます。

新鮮寿命 (freshness lifetime)
単位の時間 >>10
persist
代替サービスネットワーク設定を超えて有効かどうかのフラグ。

[44] クライアントは、ネットワーク設定が変化した時、 persist フラグの値が 1 であるものを除き、 代替サービスの情報をキャッシュから削除するべきです。 これは、代替サービスによってクライアントを最適なサーバーに向けていた場合に、 ネットワーク設定の変化で最適性が変化する可能性があるからです。 >>10

[105] クライアントは、代替サービスから 421 応答を受信したら、 当該代替サービスの情報をキャッシュから削除しなければなりません >>10

[110] 起源ごとにクライアントが保持する情報を消去する際には、 代替サービスキャッシュも消去しなければなりません >>109

利用

[50] クライアントは、 代替サービスの情報が利用可能となったら、 それが新鮮であり、既存の接続よりセキュリティー的に好ましいものである限りにおいて、 当該起源のすべての要求で、その代替サービスを使うべきです代替サービスを使う義務はありませんが、 サーバー負荷分散などのために代替サービスを使っているかもしれませんから、 代替サービスを使った方が好ましいとされています。 >>10

[46] しかし、代替サービスの利用は fingerprinting vector です >>109。 悪意あるサーバーは、クライアントの識別のために代替サービス情報を提供するかもしれません。

[129] クライアントは、クッキーなどの削除の際に、 代替サービスの情報も消去しなければなりません >>118

[130] これは Opportunistic Security for HTTP/2 の独自の規定ですが、本来代替サービス一般に適用するべきものと思われます。

[40] クライアントは、代替サービス新鮮である間、 いつでも当該代替サービスを使うことができます。 >>10

[51] クライアントは、複数の代替サービスがある場合、 自身の適切な方法でいずれかを選択できます。 >>10

[52] プロキシを使う設定のクライアントは、 代替サービスに直接接続するのではなく、 プロキシ経由で接続するべきです >>10

[54] クライアントは、代替サービスを使うことにした場合でも、 代替サービス接続の確立を待たずに既存の接続を使い続けても構いません。 しかし、セキュリティー上の理由から、代替サービス接続の確立を待った方が良いこともあります。 >>10

Opportunistic HTTP/2 Security もこれを明示的に認めています。

[41] クライアントは、既にある接続については、 新鮮寿命を過ぎてもそのまま使い続けることができます。 >>10

[55] クライアントは、 代替サービスへの接続が失敗したり、応答しなくなったりした場合には、 起源サーバーや他の代替サービスへの接続にフォールバックして構いません。 >>10

[56] ただし、これは downgrade attack かもしれないので注意が必要です。 特に代替サービスへの接続でプロトコルの折衝に失敗した場合には、 代替サービスへの接続の失敗とみなしてはなりません>>10

[57] 例えば h2 を使おうとしたのに ALPNh2 が選べなかった場合は、フォールバックしてはなりません。

[32] 代替サービスURL起源に影響せず、 接続先の決定とプロトコルの選択のみに関わるものです。 HTTPリダイレクトとは異なります。 特に、

[35] もちろん、開発者コンソールの類には実際に使った代替サービスの情報を表示できます >>10

[123] Opportunistic HTTP/2 Security により http: 要求HTTPS で送信される場合、 :scheme の値は http となります。

[53] 代替サービスへのHTTP要求には、 Alt-Used: ヘッダーを含めることができます >>10

必須ではないようです。

[43] 代替サービスは当該起源について完全に authoritative とみなされます >>10代替サービスに関する制御はもちろん、 キャッシュその他あらゆる面で、起源サーバーと等価に扱われるようです。

この点、プロキシミラーサーバーとは異なります。

[38] クライアントは、代替サービスが当該起源全体の制御下にあり、妥当であることの十分な保証 (reasonable assurances) を有しなければなりません。 ここでいう「十分な保証」は、 HTTPSサーバー認証で確立できます。クライアントは更に他の要件を加えても構いません。 >>10

[39] 起源ホストwww.example.com のとき、 代替サービスホストother.example.comプロトコルh2 (= HTTP/2 over TLS) なら、証明書www.example.com で有効かどうかを検証することで、 十分な保証があるとみなすことができます。しかしプロトコルh2c (= HTTP/2 over TCP) では、同様の検査ができないので、 十分な保証が得られないと判断せざるを得ません。 >>10

[127] Opportunistic HTTP/2 SecurityHTTPSサーバー認証を 「十分な保証」としていますが、その上で追加の検査も規定しています。

[48] 代替サービスプロトコルTLS を使う場合、 クライアントSNI に対応していなければ、 その代替サービスを使ってはなりません >>10

[49] なぜか SNI を使わなければならないとはされていませんが、 普通に考えれば、ホストドメイン名の場合、使わなければならないはずです (そうでなければWeb互換ではありません)。ホストIPアドレスなら、 SNI は使えません。

プロトコル

[104] 次のものが代替サービスで利用されています。

Alt-Svc: ヘッダー

意味

[60] Alt-Svc: ヘッダーは、 代替サービスが利用可能であるとクライアント広告するものです >>61

構文

[63] Alt-Svc: ヘッダーの値は、 clear (小文字) または1つ以上の値のリストです。 >>61

[71] 複数の値がある場合、サーバー優先度 (preference) を表しており、 最初の値が最も好ましいものです。 >>61

  1. |
    1. clear
    2. =
      1. *
        1. OWS
        2. ,
        3. OWS

[64] 値は、ALPNプロトコル名=ホストおよびポートの後に、 0個以上引数を並べたものです。 >>61

  1. プロトコル名
  2. =
  3. ホストおよびポート
  4. 引数群

[67] ALPNプロトコル名は、字句として表します。 字句で表せないオクテットおよび % は、 RFC 3986 パーセント符号化しなければなりませんパーセント符号化には大文字を使わなければなりません。 それ以外はパーセント符号化してはなりません>>61

これは、単純な文字列としての比較を行うためです。 >>61
[70] 大文字小文字は区別されます。

[65] ホストおよびポートは、引用文字列です。その値は、 RFC 3986 ホスト:RFC 3986 ポートを並べたものですが、 ホストは省略可能です。省略すると、起源ホストを表します。 >>61

  1. ?
    1. ホスト
  2. :
  3. ポート
[133] これは URL でよく見かけるホストとポートの構文とは省略できる部分が違っています。

[66] 引数は、字句=字句または引用文字列を並べたものです。 引数の前には区切りの ; が必要です。 ; の前後には、 OWS を置けます。 >>61

  1. *
    1. OWS
    2. ;
    3. OWS
    4. 字句
    5. =
    6. |
      1. 字句
      2. 引用文字列

引数

[73]

[74] 未知の引数は、無視しなければなりません >>61

[75] 引数名大文字小文字の区別の有無は不明です。

[76] 同名の引数が複数ある場合の扱いは不明です。

[77] 引数の順序は意味を持たないと思われますが、明記されていません。

[108] IANA登録簿があります >>107。 登録と適合性の関係は不明です。

文脈

[62] 任意の応答で使えます >>61。 ただし 421 応答では無視されます。

[72] HTTP/2 でも使えますが、 ALTSVC フレームを使うべきです >>61。 なお本ヘッダーの値の部分は、 ALTSVC フレームAlt-Svc欄値の値としても用いられます。

[131] サーバー全体に適用されるものですから、 利用者コンテンツが設定できないようにするべきです >>132

clear

[68] clear は、代替サービスをすべて無効化することを表します。 >>61

[69] 同じ応答に他の代替サービスが含まれる場合 (これは非妥当ですが、 あり得ます。)、それもまた無効化されます。 >>61

ma 引数

[78] Alt-Svc により記述された代替サービス新鮮寿命は、 メッセージ生成から24時間です >>61ma 引数の指定がある場合は、生成からその数です >>61

[79] ma 引数の値は、デルタ秒です >>61

[80] 応答自体の新鮮寿命とは関係しません。従って応答腐敗したかどうかに関わらず、 代替サービスはその新鮮寿命まで有効です。

persist 引数

[83] persist 引数の値 1 は、 ネットワーク設定が変更された後でも代替サービスが有効であろうとのヒントを表します。 >>61

[84] この指定がなければ、代替サービスは、 ネットワーク設定が変更された時に消去されるべきです。 >>61

[85] 他の値は指定されても無視しなければなりません >>61

v 引数

[113] GoogleQUIC 対応に当たり v 引数を使っています。

処理

[106] 421 応答では、無視しなければなりません >>10

[81] Alt-Svc: ヘッダーを受信したら、 当該起源の既存のすべての代替サービスを無効化します >>61

[82] 明記されていませんが、同じ応答で複数の代替サービスが指定されていれば、 それらは同時に有効になると思われます。

ALTSVC フレーム (HTTP/2)

[87] ALTSVC フレームは、 クライアント代替サービス広告するものです。

意味

[89] ストリーム識別子0 以外なら、 当該ストリーム起源に関連付けられた代替サービスを表します >>86

[90] ストリーム識別子0 なら、 起源欄の起源に関連付けられた代替サービスを表します >>86

構文

[92] フレーム型は、 10 (0xA) です >>86

[94] フラグはありません >>86。 0 でなければなりません >>95受信者は無視しなければなりません >>95

width
8
  1. 1 0
  2. 1 0
  3. 1 0
  4. 1 0
  5. 1 0
  6. 1 0
  7. 1 0
  8. 1 0

[93] payload は、次ので構成されます。

起源長 (Origin-Len)
起源欄の長さを、オクテット数の符号無し16ビット整数で表したものです。 >>86
起源 (Origin)
代替サービスの適用対象の起源ASCII直列化です。 >>86
Alt-Svc欄値 (Alt-Svc-Field-Value)
Alt-Svc: ヘッダーの値相当のオクテット列です。 本欄の長さは、 payload のうち起源長起源を除外した長さです。 >>86

width
32
  1. 16 起源長
  2. 16... 起源
  3. 32... Alt-Svc欄値

文脈

[102] サーバークライアントに送ることができます。

[101] ALTSVCAlt-Svc: の混用は、 結果が予測困難となるので、好ましくありません。 >>86

処理

[88] ALTSVC に対応しないエンドポイントは、 無視します >>86

[96] サーバーは、受信しても無視しなければなりません >>86

[97] ストリーム識別子0 で、 起源が空なら、無視しなければなりません >>86

[98] ストリーム識別子0 以外で、 起源が空でなければ、無視しなければなりません >>86

[91] クライアントは、示された起源が現在の接続において authoritative でないと判断するなら、 当該代替サービスを無視しなければなりません >>86

[125] 起源欄の値が正しい ASCII直列化でない場合にどう処理するべきなのかは明らかではありません。 authoritative でないと判断して無視するのが適切でしょうか。

[100] ALTSVC の受信は、意味的には、 Alt-Svc: ヘッダーの受信と等価です >>86

[99] ALTSVC フレームホップ毎に処理されるものですから、 中間器転送してはなりません。 ただし、受信した ALTSVC をもとに新たに ALTSVC を送信することは構いません。 >>86

用法

QUIC

[112] Chrome は、 QUIC 対応のために代替サービスを使っています。

[115] 代替サービスとしてALPNプロトコル名 quic を指定することで、 QUIC を使うための接続先を指定できます。

[116] HTTP/1SPDY/HTTP/2 との使い分けはどちらも TLS over TCP ベースなので TLS ALPN で可能でしたが、 QUICTCP すら使わないので、 一旦従来の HTTP/1 または HTTP/2 で接続してから、 利用可能であることを代替サービスとして明示する必要があります。
[117] Google 以外が QUIC を実装するのかどうか、実装するとしたらいつになるのかは、 現時点では不透明です。

日和見暗号化

[128] Opportunistic HTTP/2 Security では、 本来素のHTTPを使う http: URL へのアクセスであっても、 HTTPS を使って接続できることを代替サービスとして示すことができます。

[114] Firefox が実装しています。

[119] 本来の HTTPS ほど安全ではない中途半端な解法であるにも関わらず HTTPS への移行を阻害するおそれがあるとしてあまり支持されていません。 Mozilla 以外は実装しないとみられています。

その他

[120] RFC は任意のプロトコルの組み合わせで利用できると汎用的に規定しています。

[121] 特に、負荷分散などサーバーの判断で他のサーバーにアクセスさせたいときに使えることを主要な用途の1つに挙げています。 しかし、クライアントが対応しているかもしていないかもしれない本手法が既存の手法に対して特に優位といえる点があるかどうかは謎です。

[122] 理論上は HTTP/1 から HTTP/2 への切り替えなど他の手法が既に確立している場面でも本手法を利用できますが、 その必要はなさそうですし、実装が新たにそうした形で対応することもないかもしれません。

[124] いずれにせよ、 RFC は一般的な事項の規定しか含んでいませんから、 より詳細を定めた個別の仕様書が出版されない限り、 相互運用性に問題があり、実質的には使うことはできない状態です。

歴史

Alternate-Protocol: ヘッダー

[1] SPDY Protocol - Draft 2 - The Chromium Projects ( ( 版)) <http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft2#TOC-Server-Advertisement-of-SPDY-through-the-HTTP-Alternate-Protocol-header>

[2] Re: Add QUIC to Alternate-Protocol support. (issue 12156005) - Google グループ ( ( 版)) <https://groups.google.com/a/chromium.org/forum/#!topic/chromium-reviews/NhzeGXtLCOA>

[3] Actually enable Alternate-Protocol support for QUIC. (issue 17410014) - Google グループ ( ( 版)) <https://groups.google.com/a/chromium.org/forum/#!topic/chromium-reviews/y2RjueIsQbM>

[4]

HTTP/1.1 304 Not Modified
X-GData-User-Country: JP
Date: Sun, 20 Oct 2013 06:20:16 GMT
Server: GSE
Alternate-Protocol: 80:quic

[5] SPDY Protocol - Draft 2 - The Chromium Projects ( ( 版)) <http://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft2#TOC-Server-Advertisement-of-SPDY-through-the-HTTP-Alternate-Protocol-header>

[6]

Alternate-Protocol: 80:quic,p=0.01

[7] QUIC FAQ - The Chromium Projects ( 版) <https://www.chromium.org/quic/quic-faq>

How do I aim Chrome at the test server?

If you have an HTTP server, you'll need it to emit a response header that looks like:

Alternate-Protocol: quic:<QUIC server port>

[8] Issue 1720163002: When Alt-Svc header processing is enabled, do not process Alternate-Protocol - Code Review ( 版) <https://codereview.chromium.org/1720163002/>

[9] 698362 – Decide what to do regarding Alternate-Protocol vs redirects ( 版) <https://bugzilla.mozilla.org/show_bug.cgi?id=698362>

Alt-Svc: ヘッダー

[16] HTTP Alternative Services ( ( 版)) <https://httpwg.github.io/http-extensions/alt-svc.html>

[17] Certificate verification bypass through the HTTP/2 Alt-Svc header — Mozilla ( 版) <https://www.mozilla.org/en-US/security/advisories/mfsa2015-44/>

[18] Bits Up!: Opportunistic Encryption For Firefox ( 版) <http://bitsup.blogspot.jp/2015/03/opportunistic-encryption-for-firefox.html>

[19] Mozilla Dials Back on Firefox Opportunistic Encryption ( 版) <http://www.eweek.com/security/mozilla-dials-back-on-firefox-opportunistic-encryption.html>

[20] Certificate verification bypass through the HTTP/2 Alt-Svc header — Mozilla ( 版) <https://www.mozilla.org/en-US/security/advisories/mfsa2015-44/>

[21] draft-ietf-httpbis-alt-svc-07 - HTTP Alternative Services ( 版) <https://tools.ietf.org/html/draft-ietf-httpbis-alt-svc-07>

[22] 1003448 – http/2 alt-svc support ( 版) <https://bugzilla.mozilla.org/show_bug.cgi?id=1003448>

[23] 1113790 – pref change to true for network.http.altsvc.enabled and altsvc.oe ( 版) <https://bugzilla.mozilla.org/show_bug.cgi?id=1113790>

[24] HTTP Alternative Services ( 版) <http://http2.github.io/http2-spec/alt-svc.html>

[25] Issue 438263 - chromium - Update HTTP/2 AltSvc frame wire format - An open-source project to help move the web forward. - Google Project Hosting ( 版) <https://code.google.com/p/chromium/issues/detail?id=438263>

[11] Issue 392575 - chromium - Implement the Alt-Svc spec - An open-source project to help move the web forward. - Google Project Hosting ( 版) <https://code.google.com/p/chromium/issues/detail?id=392575>

[12] Issue 585876 - chromium - QUIC connections to "remote" Alt-Svcs should use the origin hostname in the SNI field - Monorail ( 版) <https://bugs.chromium.org/p/chromium/issues/detail?id=585876>

[13] Issue 1720163002: When Alt-Svc header processing is enabled, do not process Alternate-Protocol - Code Review ( 版) <https://codereview.chromium.org/1720163002/>

[14] YouTube ( 版) <https://www.youtube.com/>

alt-svc:quic=":443"; ma=2592000; v="32,31,30,29,28,27,26,25"

alternate-protocol:443:quic

[15] Google ( 版) <https://www.google.co.jp/>

alt-svc:quic=":443"; ma=2592000; v="32,31,30,29,28,27,26,25"

alternate-protocol:443:quic

[26] Implement ALT-SVC · Issue #535 · nghttp2/nghttp2 ( 版) <https://github.com/nghttp2/nghttp2/issues/535>

[126] mozilla-central: changeset 313435:7078c20114e2 () <https://hg.mozilla.org/mozilla-central/rev/7078c20114e2>