/
460.txt
357 lines (254 loc) · 17 KB
/
460.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
[7] [DFN[[[ALPN]]]] は、[[アプリケーション層プロトコル]]の[[折衝]]を行う
[[TLS拡張]]です。 [[TLS]] 上で利用する[[アプリケーション層プロトコル]]を選択するために使うことができます。
[9] [[サーバー]]が同じ [[TCP]] [[ポート]]上で [[TLS]] を介して複数の[[アプリケーション層プロトコル]]の通信を受け付けている場合に、
そのいずれを用いるかを決定するために使います。
[EG[
[70] [[HTTP/2]] に対応した[[クライアント]]や[[サーバー]]は、 [[HTTP/1.1]] と [[HTTP/2]]
のどちらを使うか決定するために [[ALPN]] を使っています。
]EG]
* 仕様書
[REFS[
- [4] '''[CITE@en[RFC 7301 - Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension]] ( ([TIME[2014-07-12 02:05:37 +09:00]] 版)) <http://tools.ietf.org/html/rfc7301>'''
- [5] [CITE[Transport Layer Security (TLS) Extensions]] ([TIME[2014-12-12 17:25:31 +09:00]] 版) <http://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids>
- [53] [CITE@en[RFC 7639 - The ALPN HTTP Header Field]] ([TIME[2015-08-27 14:11:50 +09:00]] 版) <https://tools.ietf.org/html/rfc7639>
- [81] [CITE@en[RFC 7838 - HTTP Alternative Services]] ([TIME[2016-04-17 23:25:39 +09:00]] 版) <https://tools.ietf.org/html/rfc7838#section-2>
]REFS]
* 意味
[71] [[ALPN]] は、 [[TLS]] 上で使う[[プロトコル]]について[[クライアント]]が候補を提示し、
[[サーバー]]がその中のいずれかを選ぶことにより、[[折衝]]するものです。
[72] [[ALPN]] は、対応が必須ではない[[TLS拡張]]です。従って [[TLS]]
の実装は必ずしも [[ALPN]] に対応する必要はありません。しかし [[HTTP/2]]
のように [[TLS]] 上で使う[[プロトコル]]によっては [[ALPN]]
への対応が必要となることがあります。従って実用上汎用的な [[TLS]]
の実装は [[ALPN]] にも対応する必要があります。
* 構文
[18] [[TLS]] の[[拡張型]]は、
[DFN[[CODE[[[application_layer_protocol_negotiation]]]]]] ([CODE[[[16]]]])
です [SRC[>>4]]。
[20] [CODE(TLS)@en[[[ClientHello]]]] および [CODE[[[ServerHello]]]] における[[拡張データ]]は、
[CODE[[[ProtocolNameList]]]] でなければ[['''なりません''']] [SRC[>>4]]。
[21] [DFN[[CODE[[[ProtocolNameList]]]]]] は、 2[[バイト]][[以上]]2[SUP[16]]-1[[バイト]][[以下]]で構成される欄
[DFN[[CODE[[[protocol_name_list]]]]]] であり、 [CODE[[[ProtocolName]]]]
のリストです。 [SRC[>>4]]
[FIG(packet)[
:width:16
=2 長さ
=14... [CODE[[[ProtocolName]]]] の列
]FIG]
[23] [[クライアント]]の [CODE[[[ProtocolNameList]]]] は、[[クライアント]]が[[広告]]する[[プロトコル]]のリストを、
優先度の[[降順]]で示したものです。 [SRC[>>4]]
[29] [[サーバー]]の [CODE[[[ProtocolNameList]]]] は、[[プロトコル]]を1つだけ含まなければ[['''なりません''']] [SRC[>>4]]。
[22] [DFN[[CODE[[[ProtocolName]]]]]] は、1[[バイト]][[以上]]2[SUP[8]]-1[[バイト]][[以下]]の[[バイト列]]です [SRC[>>4]]。
[FIG(packet)[
:width:16
= 1 長さ
= 15... プロトコル名
]FIG]
[24] [CODE[[[ProtocolName]]]] は、 [[IANA]] に登録された不透明の[[バイト列]]です [SRC[>>4]]。
;; [45] 現実には登録されていない値も使われています。
* 文脈
[19] [[TLS]] の[[クライアント]]は、 [CODE(TLS)@en[[[ClientHello]]]]
で本 [[TLS拡張]]を使うことができます [SRC[>>4]]。
[35] [[TLS]] の[[サーバー]]は、 [CODE(TLS)@en[[[ClientHello]]]] での指定に対して
[CODE(TLS)@en[[[ServerHello]]]] で本 [[TLS拡張]]を使うことができます [SRC[>>4]]。
;; [36] [CODE[[[ClientHello]]]] で [[ALPN]] が使われなかった場合に使って良いのかは謎です。
[38] なお [[ALPN]] は[[折衝]]時に使われるので、[[プロトコル]]は[[平文]]でやりとりされます。
[[プロトコル]]を隠す必要があるなら、[[接続]]確立後に[[再折衝]]するなど対策が必要です [SRC[>>4]]。
[39] [[ALPN]] は、 [[HTTP/2]] を利用する際に使われています。
;; [[HTTPS]] を参照。
[40] [[ALPN]] により[[クライアント]]が指定する[[プロトコル]]のリストは、
[[fingerprinting vector]] です。
* 処理
[25] [[サーバー]]は、 [CODE[[[ClientHello]]]] で [[ALPN]] を受信したら、
適当な[[プロトコル]]を選択して、 [CODE[[[ServerHello]]]] に [[ALPN]]
[[TLS拡張]]によって含めて構いません。 [SRC[>>4]]
;; [30] [[ALPN]] は [[TLSセッション]]ではなく[[接続]]の特性であり、
[[セッション再開]]や[[セッションチケット]]を使う場合でも、
以前の [[ALPN]] 折衝結果は影響しません [SRC[>>4]]。
[31] [[サーバー]]は、対応する[[プロトコル]]の一覧を保持しておき、
その中で[[クライアント]]が対応している[[プロトコル]]のみを選ぶことが期待されています。
その場合には、[[クライアント]]が[[広告]]した[[プロトコル]]の中で[[サーバー]]が最も好ましいと考えるものを選ぶ[['''べき''']]です。 [SRC[>>4]]
[26] [[サーバー]]は、認識しないプロトコル名は無視します。 [SRC[>>4]]
[34] [[サーバー]]が [CODE[[[ServerHello]]]] の [[ALPN]] 拡張で示したプロトコルは
([[再折衝]]まで) 当該[[接続]]で
[[definitive]] なものでなければ[['''なりません''']]。[[サーバー]]は示したプロトコルと異なるものを使っては[['''なりません''']]。 [SRC[>>4]]
[37] [[サーバー]]でプロトコル選択を行うため、[[サーバー]]は[[証明書]]の選択や[[接続]]の
[[rerouting]] を必要に応じて行えます [SRC[>>4]]。
[32] [[サーバー]]は、[[クライアント]]が[[広告]]した[[プロトコル]]のいずれも対応していない場合は、
[DFN[[CODE[[[no_application_protocol]]]]]] [[fatal alert]]
を返す[['''べきです''']] [SRC[>>4]]。
;; [33] [[alert]] の [[IANA登録簿]]にはなぜかこの値は掲載されていません。 [TIME[2015-05-28T09:41:53.400Z]]
[78] [[サーバー]]は、[[クライアント]]が指定した[[プロトコル]]の中から自身が対応しているものを1つ選択することが期待されています。
しかし[[クライアント]]が指定しなかった[[プロトコル]]を指定することも、
できなくはありません。[[クライアント]]はそれをエラーとして扱うべきと思われますが、
実際には対処方法は色々なようです。
[EG[
[79] [[Webブラウザー]]によっては、
[CODE[[[http/1.1]]]] のみを指定したにも関わらず[[サーバー]]が [CODE[[[h2]]]]
を返してきた時、 [[HTTP/2]] を使うことがあります。
]EG]
[73] なお、 [[ALPN]] に対応していない[[サーバー]]は、[[クライアント]]が [[ALPN]]
を指定したとしても無視します。その場合[[クライアント]]がどうするべきかは、
[[プロトコル]]に依存します。
[EG[
[74] 旧来の [[HTTPS]] の[[サーバー]]は [[ALPN]] に対応していませんでした。
[[ALPN]] 対応の [[HTTPS]] [[クライアント]]は常に [CODE[[[http/1.1]]]] と
[CODE[[[http/2]]]] を [[ALPN]] で指定するので、 [[ALPN]] 対応の[[サーバー]]はどちらかを選ぶことになります。
[[ALPN]] 未対応の[[サーバー]]は、 [[ALPN]] の有無に関わらず昔ながらの動作、すなわち
[CODE[[[http/1.1]]]] 相当の動作をすることになります。
]EG]
* プロトコル名
[10] [[プロトコル名]]としては、通常は名前を [[UTF-8]] で[[符号化]]した[[バイト列]]を使うこととなっています。
[11] [[IANA登録簿]] (>>5) があります。
[12] 次の値が使われています。
[FIG(short list)[
- [CODE@en[[[http/1.1]]]]
- [CODE@en[[[spdy/1]]]]
- [CODE@en[[[spdy/2]]]]
- [CODE@en[[[spdy/3]]]]
- [CODE@en[[[spdy/3.1]]]]
- [CODE@en[[[stun.turn]]]]
- [CODE@en[[[stun.nat-discovery]]]]
- [CODE@en[[[h2]]]]
- [CODE@en[[[h2c]]]]
- [CODE@en[[[h2-11]]]]
- [CODE@en[[[h2-12]]]]
- [CODE@en[[[h2-13]]]]
- [CODE@en[[[h2-14]]]]
- [CODE@en[[[h2-15]]]]
- [CODE@en[[[h2-16]]]]
]FIG]
;; [28] >>27 に [[JSON]] 形式の一覧データファイルがあります。
[REFS[
- [27] [CITE@en[data-web-defs/tls.txt at master · manakai/data-web-defs]] ([TIME[2015-05-28 13:20:43 +09:00]] 版) <https://github.com/manakai/data-web-defs/blob/master/doc/tls.txt>
]REFS]
[80] [[ALPNプロトコル名]]は、次の場面で使われます。
[FIG(short list)[
- [[TLS]] [[ALPN]]
- [CODE(HTTP)@en[ALPN:]]
- [[代替サービス]]
]FIG]
[82] [[代替サービス]]では、特に規定がない限り、当該[[プロトコル]]を [[TLS]]
上で利用することを意味する [SRC[>>81]] とされています。
* [CODE(HTTP)@en[ALPN:]] ヘッダー (HTTP)
[54] [[HTTP]] の [DFN[[CODE(HTTP)@en[[[ALPN:]]]]]] [[ヘッダー]]は、
[CODE(HTTP)@en[[[CONNECT]]]] [[トンネル]]内の[[プロトコル]]の[[ヒント]]を示すものです。
** 意味
[55] [[クライアント]]が [CODE(HTTP)@en[[[CONNECT]]]] [[要求]]により確立する[[トンネル]]内で使う[[プロトコル]](群)を示すものです
[SRC[>>53]]。
[57] 複数あり得る時は、すべてを示します [SRC[>>53]]。
[58] この[[ヘッダー]]は[[クライアント]]の意思を示すためだけのものであり、
[[折衝]]に使うことを目的とはしていません [SRC[>>53]]。
[75] ヘッダー名から分かる通り [[TLS拡張]]の [[ALPN]] の強い影響下にあり、
併用するものとして設計されてはいますが、両者が連動するわけではありません。
** 構文
[61] [CODE(HTTP)@en[[[ALPN:]]]] [[ヘッダー]]の値は、
1つ以上の値の[[リスト]] ([CODE(HTTP)[#]]) です [SRC[>>53]]。
[FIG(railroad)[
= 値
= *
== [[OWS]]
== [CODE(HTTP)[[[,]]]]
== [[OWS]]
== 値
]FIG]
[60] 値は、 [[ALPN]] の[[プロトコル]]識別子を使います [SRC[>>53]]。
ただし [[HTTP]] の[[字句]]で表せない[[オクテット]]および [CODE(HTTP)[[[%]]]]
は、 [[RFC 3986]] [[パーセント符号化]]しなければ[['''なりません''']] [SRC[>>53]]。
それ以外の[[字句]]で表せる[[オクテット]]は、[[パーセント符号化]]しては[['''なりません''']]
[SRC[>>53]]。[[パーセント符号化]]の[[十六進数]]は、[[大文字]]でなければ[['''なりません''']]
[SRC[>>53]]。
;; [62] 値の大文字と小文字は、区別されます。
[56] [[トンネル]]内で [[TLS]] を使う時は、 [[TLS handshake]] の [CODE@en[[[ClientHello]]]]
で [[ALPN]] によって示す[[プロトコル]]のリストと同じものとします [SRC[>>53]]。
[63] [[TLS]] を使わない場合など[[折衝]]しないと思われる場合は、
利用するプロトコルを1つ指定します。その他何らかの方法で折衝できる場合は、
折衝対象のプロトコルを指定します。 [SRC[>>53]]
** 文脈
[66] [CODE(HTTP)@en[[[CONNECT]]]] [[要求]]で指定できます。
この[[ヘッダー]]は必須ではありません [SRC[>>53]]。
[68] この[[ヘッダー]]は、[[fingerprinting vector]] です。
機密や繊細な情報を晒してしまうことになるときは、
送信する[['''べきではありません''']] [SRC[>>53]]。
[76] [CODE[[[CONNECT]]]] 以外での利用について何の規定もありませんが (それが [[IETF]]
クオリティー)、 [CODE(HTTP)@en[[[CONNECT]]]] 以外では意味をなしません。
** 処理
[59] [[プロキシ]]は、示された[[プロトコル]]を見て[[トンネル]]の拒絶や優先度制御、
その他の決定を行うことができます [SRC[>>53]]。
;; [64] しかし [CODE(HTTP)@en[[[ALPN:]]]] [[ヘッダー]]の値が正しいとは限らないので、
アクセス制御に直ちに用いられるわけではありません [SRC[>>53]]。
[65] [[プロキシ]]は、[[トンネル]]のプロトコルを認識できなかったというだけの理由で[[トンネル]]を切断する[['''べきではありません''']]
[SRC[>>53]]。
* 関連
[17] [[HTTPS]] も参照。
* 歴史
** NPN
[42] [DFN[[CODE[[[13172]]]]]] ([DFN[[CODE[[[next_protocol_negotiation]]]]]])
[1] [CITE@en[draft-agl-tls-nextprotoneg-00 - Transport Layer Security (TLS) Next Protocol Negotiation Extension]]
([TIME[2010-07-24 08:19:18 +09:00]] 版)
<http://tools.ietf.org/html/draft-agl-tls-nextprotoneg>
[2] [CITE@en[HTML5 Revision Tracker]]
([TIME[2010-08-13 22:20:59 +09:00]] 版)
<http://html5.org/tools/web-apps-tracker?from=5287&to=5288>
[3] [CITE@en[HTML5 Revision Tracker]]
([TIME[2010-08-14 10:48:51 +09:00]] 版)
<http://html5.org/tools/web-apps-tracker?from=5288&to=5289>
[6] >>2, >>3 この [[Web Socket]] の [[NPN]] 対応、[[IETF]] に移管された後いつの間にか消えてなくなったようですね。。。
[[Web Socket]] は [[HTTP]] から移行するモードで独立したプロトコルではない、
というのが [[IETF]] の主張だからなのでしょうか。
[43] [[Firefox]] も [[Chrome]] も、まだ [CODE[[[ClientHello]]]] に [[NPN]]
を含めています。 [TIME[2015-08-15T03:15:28.100Z]]
[44] 廃案になったためか、実際に使われている値であるにも関わらず、
[[IANA登録簿]]には掲載されていません。 [TIME[2015-08-15T03:16:14.400Z]]
** ALPN
[8] [[ALPN]] は [[HTTP/2]] のために [[IETF]] [[HTTPbis WG]] からの要求で開発されました [SRC[>>4]]。
[13] [CITE[SPDY - OpenSSL の ALPN/NPN API の使い方 - Qiita]]
( ([TIME[2014-12-13 20:30:42 +09:00]] 版))
<http://qiita.com/tatsuhiro-t/items/dea3fb279ad265681049>
[14] [CITE@en[1047698 – ALPN advertisment order may be wrong]] ([TIME[2014-12-13 20:32:49 +09:00]] 版) <https://bugzilla.mozilla.org/show_bug.cgi?id=1047698>
[15] [CITE@en[Chromium Blog: Hello HTTP/2, Goodbye SPDY]]
( ([TIME[2015-02-10 03:03:41 +09:00]] 版))
<http://blog.chromium.org/2015/02/hello-http2-goodbye-spdy-http-is_9.html>
[16] [CITE@en[RFC 7443 - Application-Layer Protocol Negotiation (ALPN) Labels for Session Traversal Utilities for NAT (STUN) Usages]]
([TIME[2015-01-23 14:56:59 +09:00]] 版)
<https://tools.ietf.org/html/rfc7443>
[46] [CITE@en[861266 – Implement TLS 1.2 (RFC 5246) in Gecko (Firefox, Thunderbird), on by default]]
([TIME[2015-08-28 11:49:39 +09:00]] 版)
<https://bugzilla.mozilla.org/show_bug.cgi?id=861266>
[47] [CITE@en[996238 – ALPN identifiers for WebRTC]]
([TIME[2015-08-28 11:51:56 +09:00]] 版)
<https://bugzilla.mozilla.org/show_bug.cgi?id=996238>
[48] [CITE@en[959664 – Add ALPN (RFC 7301) support to NSS]]
([TIME[2015-08-28 11:57:54 +09:00]] 版)
<https://bugzilla.mozilla.org/show_bug.cgi?id=959664>
[49] [CITE@en[1047698 – ALPN advertisment order may be wrong]]
([TIME[2015-08-28 11:58:39 +09:00]] 版)
<https://bugzilla.mozilla.org/show_bug.cgi?id=1047698>
[51] [CITE[Issue 497770 - chromium - BoringSSL ALPN callback cannot send SSL ALERT 120 (no application protocol found) - An open-source project to help move the web forward. - Google Project Hosting]]
([TIME[2015-09-24 20:45:48 +09:00]] 版)
<https://code.google.com/p/chromium/issues/detail?id=497770>
[FIG(quote)[
[FIGCAPTION[
[52] [CITE@en[ALPN Status · http2/http2-spec Wiki]]
([TIME[2015-09-24 20:58:32 +09:00]] 版)
<https://github.com/http2/http2-spec/wiki/ALPN-Status>
]FIGCAPTION]
> Note that some client implementations deal very poorly if a server sends both ALPN and NPN in the ServerHello. When a server responds negotiating a protocol via ALPN in the ServerHello, it must not also send a list of protocols for NPN negotiation as well.
]FIG]
** [CODE(HTTP)@en[ALPN:]] ヘッダー
[41] [CITE@en[draft-ietf-httpbis-tunnel-protocol-05 - The ALPN HTTP Header Field]]
([TIME[2015-07-09 12:21:49 +09:00]] 版)
<https://tools.ietf.org/html/draft-ietf-httpbis-tunnel-protocol-05>
[50] [CITE@en[1125292 – Support Tunnel-Protocol for WebRTC]]
([TIME[2015-09-24 20:36:41 +09:00]] 版)
<https://bugzilla.mozilla.org/show_bug.cgi?id=1125292>
* 実装
[67] [[HTTPS]] において [[Chrome]] も [[Firefox]] も [[ALPN]]
を使って [[HTTP/1]] と [[HTTP/2]] を選択しています。
;; [[HTTPS]] も参照。
[69] [[HTTPS]] のための [CODE(HTTP)@en[[[CONNECT]]]] [[要求]]には、
[[Firefox]] も [[Chrome]] も [CODE(HTTP)@en[[[ALPN:]]]]
[[ヘッダー]]を使わないようです。 [TIME[2015-09-24T13:53:06.500Z]]
[77] 古い [[OpenSSL]] では [[ALPN]] が使えません。少し古めの [[OS]]
の標準 [[OpenSSL]] [[パッケージ]]は古い [[OpenSSL]] (にパッチを当てたもの)
しか提供していないことがあるので、しばらくは注意が必要です。 [TIME[2015-10-17T04:46:45.200Z]]