preconnect & more

时间:2022-06-06
本文章向大家介绍preconnect & more,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

Resource Hints

preconnect 出现在 w3 组织 16 年制订 《Resource Hints》

《Resource Hints》是一套预加载机制的 w3 标准化产物,在没有标准化之前,我们常用诸如 XMLHttpRequest 等手段来预加载我们未来会使用到的资源。

《Resource Hints》文档通过 <link> 标签,定义了4个新的属性值。

<link rel="dns-prefetch" href="//www.mxgw.info">
<link rel="preconnect" href="//www.mxgw.info">
<link rel="prefetch" href="//www.mxgw.info">
<link rel="prerender" href="//www.mxgw.info">

PreConnect

文档一定定义了4个新属性值,今天由于某个案例,我们只讨论 preconnect。

The user agent should attempt to initiate a preconnect and perform the full connection handshake (DNS+TCP for HTTP, and DNS+TCP+TLS for HTTPS origins) whenever possible, but is allowed to elect to perform a partial handshake (DNS only for HTTP, and DNS or DNS+TCP for HTTPS origins), or skip it entirely, due to resource constraints or other reasons. The optimal number of connections per origin is dependent on the negotiated protocol, users current connectivity profile, available device resources, global connection limits, and other context specific variables. As a result, the decision for how many connections should be opened is deferred to the user agent.

preconnect 用于客户端与目标资源服务器,在请求资源前,预先完成 DNS 查询 + TCP 握手(如果是 HTTPS,会把 TLS 握手也预先完成),当客户端需要请求目标资源的时候,下一个 TCP 首包就可以直接发送 HTTP 的有效载荷,省去握手耗时。

需要注意规范仅仅是一个建议行为,具体处理细节由浏览器根据当时环境决定。

Caniuse

恩,Chrome、Firefox、Android 5.x 开始支持这个特性。

测试代码

理论讲完,我们来实操一下。

测试代码:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>preconnect</title>
  <link rel="preconnect" href="http://www.tencent.com/">
</head>
<body>
  <h1>hello world</h1>
  <p>test preconnect</p>
  <p>Link: <a href="http://www.tencent.com/">www.tencent.com</a></p>
</body>
</html>

测试地址:https://www.mxgw.info/demo/preconnect/index.html

对照测试代码:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>without preconnect</title>
</head>
<body>
  <h1>hello world</h1>
  <p>test preconnect</p>
  <p>Link: <a href="http://www.tencent.com/">www.tencent.com</a></p>
</body>
</html>

对照测试地址:https://www.mxgw.info/demo/preconnect/without_preconnect.html

Wireshark 抓包验证

支持 preconnect

可以看到,浏览器在觉得合适的时候,已经提前完成了和 www.tencent.com 的 TCP 握手,等到我真正点链接的时候,直接就发起了 HTTP 请求,不需要再 TCP 握手。

不支持 preconnect

正常情况下,我点击链接后,会先有 TCP 握手,然后才到 HTTP 请求。

TCP 握手大概消耗200~300ms。

More

如果我在页面中使用了 preconnect,但是我不点这个链接或者不请求这个具体资源,会发生什么呢?

正如我们前面的测试,支持 preconnect 的浏览器,依旧会朝着 preconnect 的目标服务器去建立 TCP 连接。

假如我把 preconnect 放在一个有海量用户访问的页面上,其 href 改为 targetserver.com。

<link rel="preconnect" href="https://targetserver.com">

其结果就是我们能轻易的将真实用户流量,引导去攻击目标站点,消耗目标站点的 tcp 连接数。如果目标站点支持 HTTPS,则攻击效果会更加明显。

对于 targetserver.com 而言,他只能用 netstat 或 ss 发现了一大堆的看上去不像黑产的 ip 对服务器不停的进行三次握手(或者外加 TLS 握手),由于没有 HTTP 流量,他无法通过 HTTP Referrer 来追踪流量来源页面。

这种形式的攻击流量,相比 SYN Flood 而言,它有完整的三次握手。相比 HTTP Flood 而言,它不存在 HTTP 流量。更重要的一点,流量发起源头的 ip 是真实用户,并且 ip 数量和分布是与安全界拥有的肉鸡 ip 池完全不对应。

所以常见的 DDoS 和 CC 的流量清洗方法对它不生效。

TCP Preconnect Traffic

继续八卦下去,终于找到这种攻击的名称

在网件一款名为 FWG114Pv2的说明书上,看到了 TCP preconnect traffic 关键词。

看这说明书,网件在2005年就有抵御 TCP preconnect traffic 的能力了。

看这说明书,网件在2005年就有抵御 TCP preconnect traffic 的能力了。