互联网工程任务组 (IETF) M. Nottingham
请求评注: 7838 Akamai
类别: 标准轨道 P. McManus
ISSN: 2070-1721 Mozilla
J. Reschke
greenbytes
2016年4月

HTTP 替代服务


摘要

本文档定义了 HTTP 的“替代服务”,允许某个源的资源在另一个经过授权的网络位置提供,可能使用不同的协议配置进行访问。

本备忘录状态

这是一个互联网标准轨道文档。

本文档是互联网工程任务组 (IETF) 的产物,代表了 IETF 社区的共识。它已接受公开审查并已获得互联网工程指导组 (IESG) 批准发布。关于互联网标准的更多信息,请参阅 RFC 5741 的第 2 节

有关本文档当前状态、任何勘误以及如何提供反馈的信息,可在 http://www.rfc-editor.org/info/rfc7838 获取。

Copyright Notice

Copyright (c) 2016 IETF Trust and the persons identified as the document authors. All rights reserved.

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.

1. 介绍

HTTP [RFC7230] 将资源的标识与其位置合并。换句话说,“http://” 和 “https://” 的 URI 同时用于命名和查找要交互的对象。

在某些情况下,将 HTTP 中的标识和位置分离是可取的;保留资源的相同标识符,但在网络上的不同位置与其交互。

例如:

  • 当源服务器负载较高时,可能希望将客户端重定向到不同的服务器,或找到一个更接近客户端位置的服务器。
  • 源服务器可能希望使用一种新的协议提供对其资源的访问,例如 HTTP/2 [RFC7540],或使用改进的安全性(例如传输层安全 TLS [RFC5246])。
  • 出于运营目的,源服务器可能希望将其客户端划分为具有不同能力的组,例如支持服务器名称指示 (SNI) 的客户端(参见 [RFC6066] 第 3 节)。

本规范在 HTTP 中定义了一个新概念“替代服务”(Alternative Services),允许源服务器指定在网络上与其交互的额外方式。它在 第 2 节 中定义了一个通用框架,以及使用 HTTP 头字段(第 3 节)或 HTTP/2 帧(第 4 节)来通告其存在的具体机制,并提供了一种指示已使用替代服务的方法(第 5 节)。

它还认可状态码 421(错误定向请求)(第 6 节),源服务器或其指定的替代服务器可在使用了错误位置的情况下用来表明它们并非对某个源具有权威性。

1.1. 表示约定

本文档中的关键词 "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", 和 "OPTIONAL" 应按 RFC2119 的描述来解释。

本文档使用 [RFC5234] 中定义并由 [RFC7405] 更新的扩展 BNF(ABNF),以及在 [RFC7230] 第 7 节中定义的 "#rule" 扩展。下面的规则在 [RFC5234][RFC7230][RFC7234] 中定义:

OWS           = <OWS, see [RFC7230], Section 3.2.3>
delta-seconds = <delta-seconds; see [RFC7234], Section 1.2.1>
port          = <port, see [RFC7230], Section 2.7>
quoted-string = <quoted-string, see [RFC7230], Section 3.2.6>
token         = <token, see [RFC7230], Section 3.2.6>
uri-host      = <uri-host, see [RFC7230], Section 2.7>

2. 替代服务概念

本规范定义了 HTTP 中的一个新概念“替代服务”("Alternative Service")。当一个源(origin)[RFC6454] 的资源可通过不同的协议/主机/端口组合访问时,就称该源有可用的替代服务。

替代服务可用于在网络上的不同位置与源服务器的资源进行交互,可能使用不同的协议配置。替代服务在权威性上被视为对源资源具有权威性,按照 [RFC7230] 中的定义(参见 第 9.1 节)。

例如,一个源:

("http", "www.example.com", "80")

可能声明其资源也可通过以下替代服务访问:

("h2", "new.example.com", "81")

按其性质,替代服务明确以源为粒度;不能选择性地只对源内的某些资源应用替代服务。

替代服务并不替换或改变任何给定资源的源;通常,它们对位于访问机制“上层”的软件不可见。替代服务本质上是可用于到达源的替代路由信息,就像 DNS 的 CNAME 或 SRV 记录在名称解析级别定义路由信息一样。每个源映射到一组这些路由 —— 默认路由由源本身导出,其他路由则基于替代服务信息引入。

此外,重要的是要注意,替代服务元组的第一个成员不同于源的 "scheme" 组件;它更具体,不仅标识所使用协议的主要版本,还可能标识该协议的通信选项。

这意味着使用替代服务的客户端可以更改用于获取资源的主机、端口和协议,但这些更改 MUST NOT 被传播到使用 HTTP 的应用程序;从该角度来看,被访问的 URI 及从中派生的所有信息(scheme、host 和 port)与之前相同。

重要的是,这也包括它的安全上下文;特别是,当使用 TLS [RFC5246] 进行认证时,替代服务需要为源的主机名出示证书,而不是替代主机的证书。同样,Host 头字段([RFC7230])仍然从源派生,而不是从替代服务派生(就像使用 CNAME 时一样)。

这些更改 MAY 在调试工具、控制台等中显示出来。

形式上,替代服务由以下组合标识:

  • 应用层协议协商(ALPN)协议名称,参见 [RFC7301]
  • 主机,参见 [RFC3986] 第 3.2.2 节
  • 端口,参见 [RFC3986] 第 3.2.3 节

ALPN 协议名称用于标识替代服务所使用的应用协议或协议套件。注意,对于本规范的目的,ALPN 协议名称隐含地在其所标识的协议套件中包含 TLS,除非在其定义中另有说明。特别地,ALPN 名称 "http/1.1"(在 [RFC7301] 第 6 节注册)标识在 TLS 之上的 HTTP/1.1。

此外,每个替代服务 MUST 具有以秒为单位表示的有效期(见 第 2.2 节)。

客户端可以通过多种方式发现与某个源关联的替代服务。本文档描述了两种此类机制:在响应中使用 Alt-Svc HTTP 头字段(第 3 节)和使用 ALTSVC HTTP/2 帧类型(第 4 节)。

本节其余部分描述了与替代服务相关的通用要求,无论这些替代服务如何被发现。

2.1. 主机认证

客户端 MUST 对替代服务受控并对整个源有效有合理的保证。这可以缓解在 第 9.2 节 描述的攻击。

为本文档目的,“合理的保证”可以通过使用基于 TLS 的协议并执行 [RFC2818] 中定义的证书检查来建立。客户端 MAY 强加额外的标准来建立合理的保证。

例如,如果源的主机是 "www.example.com",且在 "other.example.com" 上提供了使用 "h2" 协议的替代服务,并且该替代服务出示的证书对 "www.example.com" 有效,则客户端可以使用该替代服务。然而,如果任何一方使用的是 "h2c" 协议,则客户端不能使用它,因为在该协议中(在本规范发布时)没有机制来建立源与替代之间的关系。

2.2. 替代服务缓存

用于发现替代服务的机制也会为其关联一个有效期;例如,Alt-Svc 头字段使用 "ma" 参数。

当替代服务被认为是新鲜的时,客户端可以随时选择使用替代服务而不是源;有关具体建议,请参见 第 2.4 节

已经与替代服务建立连接的客户端在其有效期结束时不需要停止使用它;该缓存机制旨在限制替代服务用于建立新连接的时长,而不是限制已有连接的使用。

替代服务对相关源完全具有权威性,包括清除或更新已缓存的替代服务条目、延长有效期,以及源服务器拥有的任何其他权限。

当替代服务用于将客户端发送到最优服务器时,网络配置的变化可能导致缓存值变得不再最优。因此,当可用网络状态信息表明网络已改变时,客户端 SHOULD 从缓存中移除所有没有带有值 "1" 的 "persist" 标志的替代服务。

2.3. 要求服务器名称指示

客户端 MUST NOT 使用基于 TLS 的替代服务,除非客户端支持 TLS 服务器名称指示(SNI)。这有助于节约替代服务主机上的 IP 地址。

注意,客户端在 TLS 中提供的 SNI 信息将是源的主机名,而不是替代主机名(Host HTTP 头字段的值亦是如此)。

2.4. 使用替代服务

按其性质,替代服务是 可选的:客户端并不必须使用它们。然而,当服务器使用替代服务时,客户端以可预测的方式进行处理是有利的,这有助于负载均衡等目的。

因此,如果支持本规范的客户端获知了某个替代服务,并且该替代服务信息是新鲜的(见 第 2.2 节),且替代服务协议的安全特性相比现有连接是可取的,则客户端 SHOULD 在可用时立即对所有发往关联源的请求使用该替代服务。可行的替代服务在各方面都被视为源;这包括有能力公布替代服务。

如果客户端获知多个替代服务,它应根据自身标准选择最合适的,并考虑安全特性。例如,源可能会公布多个替代服务以通知客户端对多个 HTTP 版本的支持。

被配置为为给定请求使用代理的客户端 SHOULD NOT 直接为该请求连接到替代服务,而应通过该代理路由请求。

当客户端为请求使用替代服务时,它可以使用 Alt-Used 头字段(第 5 节)向服务器指示这一点。

客户端不需要阻塞对任何现有连接的请求;可以继续使用该连接,直到替代连接建立为止。然而,如果现有连接的安全性较弱(例如明文的 HTTP/1.1),则可能有必要阻塞直到新连接完全可用以避免信息泄露。

此外,如果与替代服务的连接失败或无响应,客户端 MAY 回退到使用源或另一个替代服务。但请注意,这可能成为降级攻击的基础,从而失去替代服务提供的任何增强安全属性。如果与替代服务的连接未协商出预期的协议(例如 ALPN 未协商出 h2,或对 h2c 的 Upgrade 请求未被接受),则该替代服务连接 MUST 被视为失败。

3. Alt-Svc HTTP 头部字段

HTTP(S) 源服务器可以通过在响应中添加 Alt-Svc 头字段来向客户端通告替代服务的可用性。

Alt-Svc       = clear / 1#alt-value
clear         = %s"clear"; "clear", case-sensitive
alt-value     = alternative *( OWS ";" OWS parameter )
alternative   = protocol-id "=" alt-authority
protocol-id   = <a href="#imported.abnf" class="smpl">token</a> ; percent-encoded ALPN protocol name
alt-authority = <a href="#imported.abnf" class="smpl">quoted-string</a> ; containing [ <a href="#imported.abnf" class="smpl">uri-host</a> ] ":" <a href="#imported.abnf" class="smpl">port</a>
parameter     = <a href="#imported.abnf" class="smpl">token</a> "=" ( <a href="#imported.abnf" class="smpl">token</a> / <a href="#imported.abnf" class="smpl">quoted-string</a> )

字段值要么由一组值组成,每个值表示一个替代服务,要么为关键字 "clear"。

字段值包含特殊值 "clear" 表示源请求使得该源的所有替代项失效(包括在同一响应中同时包含 "clear" 和替代服务时,以防回复无效)。

ALPN 协议名称是八位字节序列,对格式没有额外约束。对于 tokens 中不允许的八位字节(参见 [RFC7230] 第 3.2.6 节),MUST 按照 [RFC3986] 第 2.1 节进行百分号编码。因此,表示百分号字符 "%"(十六进制 25)的八位字节也 MUST 进行百分号编码。

为确保任何 ALPN 协议名称只有一种表示方式,适用以下附加约束:

  1. 如果某个八位字节是有效的 token 字符(除了 "%" 之外),则该八位字节 MUST NOT 被百分号编码;
  2. 在使用百分号编码时,MUST 使用大写十六进制数字。

在这些约束下,接收方可以使用简单的字符串比较来匹配协议标识符。

"alt-authority" 组件由一个 可选的 uri-host(参见 [RFC3986] 第 3.2.2 节)、一个冒号 ":" 和一个端口号组成。

例如:

Alt-Svc: h2=":8000"

这表示在相同主机上使用 8000 端口的 "h2" 协议([RFC7540])。

涉及更换主机的示例:

Alt-Svc: h2="new.example.org:80"

这表示在主机 "new.example.org" 上的 "h2" 协议,运行在端口 80。注意需要使用 "quoted-string" 语法,因为 ":" 在 "token" 中不是允许的字符。

协议名称转义示例:

ALPN 协议名称 protocol-id 说明
h2 h2 无需转义
w=x:y#z w%3Dx%3Ay#z "=" 与 ":" 已转义
x%y x%25y "%" 需要转义

Alt-Svc MAY 出现在任何 HTTP 响应消息中,无论状态码如何。注意 Alt-Svc 的接收者可以忽略该头字段(在某些情况下必须忽略;参见 第 2.1 节第 6 节)。

Alt-Svc 字段值可以包含多个值:

Alt-Svc: h2="alt.example.com:8000", h2=":443"

当存在多个值时,值的顺序反映服务器的偏好(第一个值为最优先的替代项)。

Alt-Svc 所通告的值可被客户端用于打开到替代服务的新连接。后续请求可以立即开始使用该新连接,或者在创建新连接的同时继续使用现有连接。

在使用 HTTP/2 时([RFC7540]),服务器 SHOULD 改为发送 ALTSVC 帧(见 第 4 节)。单个 ALTSVC 帧可为一个连接发送;不需要为每个请求都发送新的帧。尽管有此建议,通过 HTTP/2 传递的响应中仍然可以包含 Alt-Svc 头字段。

每个 "alt-value" 后面可跟一个可选的以分号分隔的参数列表,每个 "parameter" 由一个名称和一个值组成。

本规范定义了两个参数:"ma" 与 "persist",其定义见 第 3.1 节。未知参数 MUST 被忽略。也就是说,出现未知参数的 alt-value 的处理 MUST 当作该未知参数不存在。

新参数可以在扩展规范中定义(有关注册详情见 第 7.3 节)。

注意,所有允许使用 "quoted-string" 语法的字段元素 MUST 按照 [RFC7230] 第 3.2.6 节处理。

3.1. 缓存 Alt-Svc 头部字段值

当使用 Alt-Svc 通告替代服务时,该服务自消息生成之日起在默认情况下被认为在 24 小时内是新鲜的。可以使用 "ma"(最大年龄)参数修改此值。

语法:

ma = <a href="#imported.abnf" class="smpl">delta-seconds</a>; see [RFC7234], Section 1.2.1

delta-seconds 值表示自响应生成起替代服务被视为新鲜的秒数。

Alt-Svc: h2=":443"; ma=3600

关于确定响应年龄的详细信息,请参见 [RFC7234] 第 4.2.3 节。

例如,某个响应:

HTTP/1.1 200 OK
Content-Type: text/html
Cache-Control: max-age=600
Age: 30
Alt-Svc: h2=":8000"; ma=60

表示一个替代服务可用并在接下来的 60 秒内可用。然而,该响应已被缓存 30 秒(根据 Age 头字段值);因此,该替代服务自接收响应时起仅新鲜 30 秒,减去估计的传输时间。

注意,用于 HTTP 缓存的新鲜期(此处为 600 秒)不影响 Alt-Svc 值的缓存。

当从源接收到 Alt-Svc 响应头字段时,其值会使该源的所有已缓存替代服务无效并被替换。

默认情况下,当客户端检测到网络变化时,已缓存的替代服务将被清除。那些预期更长寿命的替代服务(例如不针对客户端访问网络特定的服务)可以带有 "persist" 参数并设置为值 "1",作为该服务可能在网络配置变化后仍有用的提示。

语法:

persist = "1"

例如:

Alt-Svc: h2=":443"; ma=2592000; persist=1

本规范仅为 "persist" 定义了单一值。客户端 MUST 忽略值不是 "1" 的 "persist" 参数。

关于替代服务缓存的一般要求,请参见 第 2.2 节

4. ALTSVC HTTP/2 帧

ALTSVC HTTP/2 帧(参见 [RFC7540] 第 4 节)向 HTTP/2 客户端通告替代服务的可用性。

ALTSVC 帧是对 HTTP/2 的非关键扩展。不支持该帧的端点将根据 [RFC7540] 中定义的可扩展性规则忽略它。

服务器发送到流 0 以外的流的 ALTSVC 帧表示所传达的替代服务与该流的源关联。

服务器发送到流 0 的 ALTSVC 帧表示所传达的替代服务与帧中 Origin 字段包含的源关联。与客户端当前连接不被视为该连接权威的源关联 MUST 被忽略。

ALTSVC 帧类型为 0xa(十进制 10)。

 +-------------------------------+-------------------------------+
 |         Origin-Len (16)       | Origin? (*)                 ...
 +-------------------------------+-------------------------------+
 |                   Alt-Svc-Field-Value (*)                   ...
 +---------------------------------------------------------------+

图 1:ALTSVC 帧有效载荷

ALTSVC 帧包含以下字段:

Origin-Len:
一个无符号 16 位整数,指示 Origin 字段的长度(以八位字节计)。
Origin:
一个 可选的 字符序列,包含一个源的 ASCII 序列化形式(参见 [RFC6454] 第 6.2 节),该源是替代服务适用的对象。
Alt-Svc-Field-Value:
一序列八位字节(长度由从帧长度中减去所有前置字段的长度来确定),包含与 第 3 节 中定义的 Alt-Svc 字段值相同的值(ABNF 生成式 "Alt-Svc")。

ALTSVC 帧未定义任何标志。

ALTSVC 帧旨在由客户端接收。作为服务器的设备 MUST 忽略它。

在流 0 上且 Origin 信息为空(长度为 0)的 ALTSVC 帧是无效的,MUST 被忽略。在流 0 以外的流上包含非空 Origin 信息的 ALTSVC 帧是无效的,MUST 被忽略。

ALTSVC 帧按逐跳处理。中间节点 MUST NOT 转发 ALTSVC 帧,尽管它可以使用 ALTSVC 帧中包含的信息来生成并发送给其自身客户端的新 ALTSVC 帧。

接收 ALTSVC 帧在语义上等同于接收 Alt-Svc 头字段。因此,ALTSVC 帧会导致对应源的替代服务被替换。注意,混合使用 Alt-Svc 头字段与 ALTSVC 帧并不是明智的做法,因为接收顺序可能难以预测。

5. Alt-Used HTTP 头部字段

Alt-Used 头字段用于请求中标识正在使用的替代服务,就像 Host 头字段用于标识源的主机和端口一样(参见 [RFC7230] 第 5.4 节)。

Alt-Used     = uri-host [ ":" port ]

Alt-Used 的目的是允许替代服务检测循环、区分用于负载均衡的流量,并确保可以识别流量的预期目的地,因为在协议使用后才引入此信息已被证明会导致问题。

使用替代服务时,客户端 SHOULD 在所有请求中包含 Alt-Used 头字段。

例如:

GET /thing HTTP/1.1
Host: origin.example.com
Alt-Used: alternate.example.net

6. 421(错误定向请求)HTTP 状态码

421(错误定向请求)状态码在 [RFC7540] 的第 9.1.2 节中定义,用于表明当前服务器实例并非请求资源的权威实体。这可以用来指示替代服务并非权威的情况(参见 第 2 节)。

客户端从替代服务接收到 421(错误定向请求)时,MUST 从其替代服务缓存中移除对应源的条目(见 第 2.2 节)。无论请求方法是否幂等,客户端 MAY 重试该请求,要么在另一个替代服务器上,要么在源上。

在 421(错误定向请求)响应中的 Alt-Svc 头字段 MUST 被忽略。

7. IANA 注意事项

7.1. 头部字段注册

HTTP 头部字段在 IANA 维护的 “Message Headers” 注册表中注册,地址为 <https://www.iana.org/assignments/message-headers/>。

本文档定义了以下 HTTP 头字段,因此它们的关联注册条目已根据永久注册添加(参见 BCP90):

头字段名 协议 状态 参考
Alt-Svc http standard 第 3 节
Alt-Used http standard 第 5 节

变更控制者为:“IETF (iesg@ietf.org) -- Internet Engineering Task Force”。

7.2. ALTSVC HTTP/2 帧类型

本文档在 “HTTP/2 Frame Type” 注册表中注册了 ALTSVC 帧类型(参见 [RFC7540] 第 11.2 节)。

  • 帧类型:ALTSVC
  • 代码:0xa
  • 规范:本文件的 第 4 节

7.3. Alt-Svc 参数注册表

“超文本传输协议 (HTTP) Alt-Svc 参数注册表”定义了参数名称空间。该注册表已创建并将在 <http://www.iana.org/assignments/http-alt-svc-parameters> 维护。

7.3.1. 程序

注册 MUST 包含以下字段:

  • 参数名称
  • 指向规范文本的指针

要添加到此名称空间的值需要专家审查(参见 [RFC5226] 第 4.1 节)。

7.3.2. 注册

“超文本传输协议 (HTTP) Alt-Svc 参数注册表”已用以下注册项填写:

Alt-Svc 参数 参考
ma 第 3.1 节
persist 第 3.1 节

8. 国际化注意事项

出现在头部字段(第 3 节)或 HTTP/2 帧(第 4 节)中的国际化域名 MUST 使用 A-label 表示(参见 [RFC5890] 第 2.3.2.1 节)。

9. 安全注意事项

9.1. 更改端口

使用替代服务至少意味着在替代端口上访问源的资源。因此,能够注入替代服务并在所通告端口上监听的攻击者能够劫持源。在某些服务器上,用户可以控制共享端口上一些个人页面,并且也可以在较低特权端口上接受请求,这是正常的。

例如,能够向某些页面添加 HTTP 响应头字段的攻击者可以使用 Alt-Svc 头字段将整个源的流量重定向到同一主机上的不同端口;如果该端口由攻击者控制,他们就可以冒充该 HTTP 服务器。

此风险可通过第 2.1 节 中的要求来缓解。

在服务器上,这种风险也可以通过限制通告替代服务的能力以及限制谁可以在该主机上打开监听端口来减轻。

9.2. 更改主机

当由于使用替代服务而更改主机时,这为攻击者提供了劫持与源的通信的机会。

例如,如果攻击者能说服用户代理将对 "innocent.example.org" 的所有流量发送到 "evil.example.com"(通过成功将其关联为替代服务),则他们可以冒充该源。这可以在本地完成(见第 9.1 节的缓解),也可以远程完成(例如作为中间人攻击)。

这就是第 2.1 节 要求客户端对替代服务有合理保证的原因;例如,出示给源的证书可以证明替代服务被授权为该源提供流量。

请注意,这种保证的强度取决于用于验证替代服务的方法。特别是,当使用 TLS 认证时,存在众所周知的漏洞可以使攻击者的证书看起来合法。

替代服务可能被用于维持此类攻击。例如,中间人可以对目标的 TLS 受保护通信进行中间人攻击,然后将所有流量指向具有较长有效期的替代服务,使得即使在不使用该中间人的情况下,用户代理仍将流量指向攻击者。

实现必须像在直接连接到源时一样,对替代服务执行任何证书固定验证(例如 [RFC7469])。实现也可能选择为可接受的替代服务证书添加其他要求。

9.3. 更改协议

当由于使用替代服务而更改 ALPN 协议时,与源的新连接的安全属性可能与“正常”连接不同,因为协议标识本身就暗示了这一点。

例如,如果对 "https://" URI 通告了不使用某种端到端加密形式(最可能是 TLS)的协议,则这违反了 URI 方案所暗示的安全期望。因此,客户端不能盲目使用替代服务,而应评估所提供的选项以确保满足规范、实现和最终用户对安全性的要求和期望。

9.4. 使用替代服务跟踪客户端

选择替代服务意味着要连接到新的、由服务器提供的主机名。通过使用唯一名称,服务器可以设法跟踪客户端请求。当使用 "persist" 标志时,这种跟踪甚至可以跨多个网络跟踪用户。

希望防止请求被关联的客户端可以决定不对那些本不应被关联的多个请求使用替代服务。

在用户代理中,当清除与源相关的数据时(通常在清除 cookie 时),任何替代服务信息 MUST 被移除(参见 [RFC6265])。

9.5. 关于请求方案的混淆

一些服务器端 HTTP 应用基于连接上下文对安全性作出假设;例如,将在端口 443 上提供服务等同于使用 "https://" URI 及其所暗示的各种安全属性。

这不仅影响连接本身的安全属性,还影响另一端的客户端状态;例如,Web 浏览器在许多方面会区别对待 "https://" URI 与 "http://" URI,不仅仅是协议处理方面。

由于替代服务的用途之一是允许连接迁移到不同的协议和端口,这些应用可能会对给定连接的安全属性产生混淆,把为安全上下文(如 "https://" URI)准备的信息(例如 cookie 和内容)发送给未将其视为安全上下文的客户端。

服务器可以通过使用协议显式携带的 URI 方案(例如 HTTP/2 中的 ":scheme" 或 HTTP/1.1 中的请求目标的“绝对形式”)作为安全上下文的指示来缓解此风险,而不是依赖其他连接属性(参见 [RFC7540] 第 8.1.2.3 节 和 [RFC7230] 第 5.3.2 节)。

当协议不显式携带方案(通常为在 TLS 上的 HTTP/1.1)时,服务器可以通过假定所有请求处于不安全上下文,或通过避免为不安全方案(例如 HTTP)通告替代服务来缓解该风险。

10. 参考文献

10.1. 规范性参考文献

[RFC2119]
Bradner, S., “Key words for use in RFCs to Indicate Requirement Levels”, BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, <http://www.rfc-editor.org/info/rfc2119>.
[RFC2818]
Rescorla, E., “HTTP Over TLS”, RFC 2818, DOI 10.17487/RFC2818, May 2000, <http://www.rfc-editor.org/info/rfc2818>.
[RFC3986]
Berners-Lee, T., Fielding, R., and L. Masinter, “Uniform Resource Identifier (URI): Generic Syntax”, STD 66, RFC 3986, DOI 10.17487/RFC3986, January 2005, <http://www.rfc-editor.org/info/rfc3986>.
[RFC5226]
Narten, T. and H. Alvestrand, “Guidelines for Writing an IANA Considerations Section in RFCs”, BCP 26, RFC 5226, DOI 10.17487/RFC5226, May 2008, <http://www.rfc-editor.org/info/rfc5226>.
[RFC5234]
Crocker, D., Ed. and P. Overell, “Augmented BNF for Syntax Specifications: ABNF”, STD 68, RFC 5234, DOI 10.17487/RFC5234, January 2008, <http://www.rfc-editor.org/info/rfc5234>.
[RFC5890]
Klensin, J., “Internationalized Domain Names for Applications (IDNA): Definitions and Document Framework”, RFC 5890, DOI 10.17487/RFC5890, August 2010, <http://www.rfc-editor.org/info/rfc5890>.
[RFC6066]
Eastlake, D., “Transport Layer Security (TLS) Extensions: Extension Definitions”, RFC 6066, DOI 10.17487/RFC6066, January 2011, <http://www.rfc-editor.org/info/rfc6066>.
[RFC6454]
Barth, A., “The Web Origin Concept”, RFC 6454, DOI 10.17487/RFC6454, December 2011, <http://www.rfc-editor.org/info/rfc6454>.
[RFC7230]
Fielding, R., Ed. and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing”, RFC 7230, DOI 10.17487/RFC7230, June 2014, <http://www.rfc-editor.org/info/rfc7230>.
[RFC7234]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., “Hypertext Transfer Protocol (HTTP/1.1): Caching”, RFC 7234, DOI 10.17487/RFC7234, June 2014, <http://www.rfc-editor.org/info/rfc7234>.
[RFC7301]
Friedl, S., Popov, A., Langley, A., and S. Emile, “Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension”, RFC 7301, DOI 10.17487/RFC7301, July 2014, <http://www.rfc-editor.org/info/rfc7301>.
[RFC7405]
Kyzivat, P., “Case-Sensitive String Support in ABNF”, RFC 7405, DOI 10.17487/RFC7405, December 2014, <http://www.rfc-editor.org/info/rfc7405>.
[RFC7540]
Belshe, M., Peon, R., and M. Thomson, Ed., “Hypertext Transfer Protocol version 2”, RFC 7540, DOI 10.17487/RFC7540, May 2015, <http://www.rfc-editor.org/info/rfc7540>.

10.2. 信息性参考文献

[BCP90]
Klyne, G., Nottingham, M., and J. Mogul, “Registration Procedures for Message Header Fields”, BCP 90, RFC 3864, September 2004, <http://www.rfc-editor.org/info/bcp90>.
[RFC5246]
Dierks, T. and E. Rescorla, “The Transport Layer Security (TLS) Protocol Version 1.2”, RFC 5246, DOI 10.17487/RFC5246, August 2008, <http://www.rfc-editor.org/info/rfc5246>.
[RFC6265]
Barth, A., “HTTP State Management Mechanism”, RFC 6265, DOI 10.17487/RFC6265, April 2011, <http://www.rfc-editor.org/info/rfc6265>.
[RFC7469]
Evans, C., Palmer, C., and R. Sleevi, “Public Key Pinning Extension for HTTP”, RFC 7469, DOI 10.17487/RFC7469, April 2015, <http://www.rfc-editor.org/info/rfc7469>.

致谢

感谢 Adam Langley、Bence Beky、Chris Lonvick、Eliot Lear、Erik Nygren、Guy Podjarny、Herve Ruellan、Lucas Pardue、Martin Thomson、Matthew Kerwin、Mike Bishop、Paul Hoffman、Richard Barnes、Richard Bradbury、Stephen Farrell、Stephen Ludin 和 Will Chan 的反馈和建议。

Alt-Svc 头字段的设计受到了 SPDY 中 Alternate-Protocol 头字段设计的影响。

作者地址

Mark Nottingham
Akamai
Email: mnot@mnot.net
URI: https://www.mnot.net/
Patrick McManus
Mozilla
Email: mcmanus@ducksong.com
URI: https://mozillians.org/u/pmcmanus/
Julian F. Reschke
greenbytes GmbH
Email: julian.reschke@greenbytes.de
URI: https://greenbytes.de/tech/webdav/