Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Proposal]Support Restls-V1 | 支持Restls-V1 协议 #442

Closed
3andne opened this issue Mar 13, 2023 · 10 comments
Closed

[Proposal]Support Restls-V1 | 支持Restls-V1 协议 #442

3andne opened this issue Mar 13, 2023 · 10 comments

Comments

@3andne
Copy link

3andne commented Mar 13, 2023

Clash.Meta的开发者们,大家好:
相关PR: #441
经过一段时间的开发,我们认为Restls已经具备实用性,因此我们提出向Clash.Meta中合并Restls支持的请求。
Restls-V1具有的以下能力:

  1. 服务器TLS伪装:Restls-V1可以将自己伪装成GFW白名单中的大部分网站,支持TLS 1.3和TLS 1.2网站,例如www.microsoft.com, vscode.dev伪装成TLS 1.2的能力是Restls独有的——现存的两个TLS伪装协议其中一个在设计上只支持伪装成TLS 1.3网站,另一个的TLS 1.2模式的无法防御重放、重定向等攻击方式。虽然现在距离TLS 1.3的标准化已经过去了5年,但Alexa全球访问量最大的网站中还有40%仅支持TLS 1.2。我们认为TLS 1.2一定会渐渐走入历史舞台。但在这个过程中,伪装成TLS 1.2网站的能力可以帮用户分散风险,并提高GFW的成本,这就是Restls支持TLS 1.2伪装的意义。
    • Restls-V1已经解决了初期的握手后流量保护问题,可以保证代理流量的完整性
    • 我们采纳了 @H1JK 的建议,将HMAC算法替换为Blake3以避免该环节成为短板。
    • 我们知晓TLS 1.2伪装中的「AES指纹」问题并有相关应对措施。
  2. 客户端伪装:Restls-V1的客户端fork自utls,可以将自己伪装成主流浏览器。
  3. 使用Restls「剧本」隐藏代理行为:代理行为是众多代理工具所共有的特征,其中最为人所知的就是"TLS in TLS"。TLS握手阶段的包具有高度确定的长度以及收发模式,可以被利用并对各种协议进行有效识别。现存代理工具的应对方案中,其中比较有代表性的就是 @klzgrad 在naiveproxy中使用的"padding"。通过把握手阶段的包填充变长,让这些包看起来不那么像TLS握手,从而一定程度上隐藏"TLS in TLS"。
    padding策略已经有所成效,但我们担心这仍然具有流量分析的风险:
    1. padding在根本上没有改变TLS握手的行为模式,比如客户端发送一个较短包 -> 服务端回复一个到四个包,其中有一个异常地长 -> 客户端发送一个较短包 -> 服务端回复一个较短包。
    2. padding往往只能增加包的长度,现存协议缺乏把长包拆分成短包的能力。
    3. 另外一方面,代理协议往往提供了统一的padding策略,可能形成协议特征。

基于以上几点观察,我们设计了Restls「剧本」机制。下图是Restls「剧本」和一种可行的padding策略的对比:

image

相比padding,我们让用户可以直接控制握手后的包的长度和收发模式,一切都按剧本来
如果数据比剧本规定的短,restls会为其增加padding;如果数据比剧本规定的长,那它就会被截断,从而破坏TLS握手的长度特征。
剧本还能要求对方向自己发送回包,从而破坏了TLS握手的收发模式。
最重要的是,用户可以设计自己的剧本,从而避免形成统一的特征


Hi there,

After a period of development, we believe that Restls has reached a level of practicality and we propose to merge Restls support into Clash.Meta.

Restls-V1 has the following capabilities:

  1. TLS Server impersonation: Restls-V1 can disguise itself as most websites in the GFW allowlist and supports TLS 1.3 and TLS 1.2 websites, such as www.microsoft.com, vscode.dev, etc. The ability to disguise itself as a TLS 1.2 server is unique to Restls - one of the two existing TLS impersonation protocols only supports disguising as TLS 1.3 servers, and the other's TLS 1.2 mode cannot defend against replay, redirection, and other attacks. Although it has been five years since the standardization of TLS 1.3, 40% of the world's most visited websites on Alexa still only support TLS 1.2. We believe that TLS 1.2 will gradually fade into history, but in the meantime, the ability to disguise itself as a TLS 1.2 server can help users diversify their choices and increase the cost for the GFW, which is the significance of Restls supporting TLS 1.2. It's worth noting that:
    • Restls-V1 has solved the problem of traffic protection after the initial handshake and can ensure the integrity of proxy traffic.
    • We have adopted the suggestion of @H1JK to replace the HMAC algorithm with Blake3 to avoid it becoming an obvious shortcoming.
    • We are aware of the "AES fingerprint" issue in TLS 1.2 impersonation and have corresponding countermeasures.
  2. Client impersonation: The client of Restls-V1 is forked and developed from utls and can disguise itself as mainstream browsers.
  3. Hide your proxy traffic behavior through restls-script: Proxy behavior is a common characteristic of many proxy tools, and the most well-known among them is "TLS in TLS." Records during the TLS handshake have highly determinable lengths and transmission patterns, which can be utilized to effectively recognize various protocols. Among the mitigation strategies of existing proxy protocols, the more representative one is the "padding" used by @klzgrad in naiveproxy. By padding the packets during the handshake to make them longer, these traffics no longer appear so much like TLS handshakes, thereby to some extent hiding "TLS in TLS."
    Although the padding strategy has been somewhat effective, we are concerned that it still poses a risk of traffic analysis:
    1. Padding does not fundamentally change the behavior pattern of the TLS handshake, which involves the client sending a short packet -> the server replying with one to four packets, the first or second packet is abnormally long -> the client sending another short packet -> the server replying with a short packet.
    2. Padding can only increase the length of the packets, and current protocols lack the ability to split long packets into short ones.
    3. On the other hand, proxy protocols often provide a unified padding strategy in their implementation, which may result in a protocol fingerprint.

Based on the above observations, we have designed the Restls "script" mechanism. The above figure shows a comparison between the Restls "script" mechanism and a feasible padding strategy ⬆️⬆️

Compared to padding, we allow users to directly control the length and transmission pattern of packets after the handshake, everything is done according to the "script"!
If the data is shorter than what the script specifies, Restls will add padding to it; if the data is longer than what the script specifies, it will be truncated, thus destroying the length characteristic of the TLS handshake.
The "script" can also require the other party to send a response packet back to oneself, thereby disrupting the transmission pattern of the TLS handshake.

Most importantly, users can design their own scripts to avoid creating a uniform characteristic.

@RPRX
Copy link

RPRX commented Mar 13, 2023

简单评价一下(序号对应):

  1. REALITY 只支持 TLSv1.3,一是因为 REALITY 是使用临时证书的真 TLS,需要加密证书,二是因为 TLSv1.3 行为模式比较单一,可以做到在处理 record 时呈现出和目标网站完全一致的特征,而 TLSv1.2 中奇怪的东西太多,可能会存在一些问题。
  2. 按 ShadowTLS / Restls 的设计,理论上无需 fork uTLS 库,若要修改 Client Hello 内的 Session ID 等可以参考 REALITY 的代码,若要获取一些内部变量和调用一些内部方法可以通过 reflect 和 linkname 来做到,若不得不改函数,那还是 fork 吧
  3. 「剧本」机制和 VLESS flow 的目标比较像,但需要注意的是,TLS in TLS 除了内层 TLS 握手特征,还有个“加密套娃”的特征,而 Restls 新加的“应用数据传输认证”又加了一层,共三层。XTLS Vision 可以直接裸奔,也是需要内外同为 TLSv1.3。

@RPRX
Copy link

RPRX commented Mar 13, 2023

大家应该知道我偶尔也会看 Clash.Meta 群吧

To leo:理解有误,第三点的重点不是“极致性能”,而是“加密套娃”特征。另外这里只是进行一些说明和评价,百花齐放当然更好。

@RPRX
Copy link

RPRX commented Mar 13, 2023

To 群里:其实在 Golang 中 str != ""len(str) != 0 编译后是一样的

@klzgrad
Copy link

klzgrad commented Mar 13, 2023

流量整形、流量模仿,应参考先有工作 net4people/bbs#129 (comment)

剧本的包长度应有工具进行现实的采集 net4people/bbs#136 (comment)

剧本的包长度应有定时变换的方法

@3andne
Copy link
Author

3andne commented Mar 13, 2023

简单评价一下(序号对应):

  1. REALITY 只支持 TLSv1.3,一是因为 REALITY 是使用临时证书的真 TLS,需要加密证书,二是因为 TLSv1.3 行为模式比较单一,可以做到在处理 record 时呈现出和目标网站完全一致的特征,而 TLSv1.2 中奇怪的东西太多,可能会存在一些问题。
  2. 按 ShadowTLS / Restls 的设计,理论上无需 fork uTLS 库,若要修改 Client Hello 内的 Session ID 等可以参考 REALITY 的代码,若要获取一些内部变量和调用一些内部方法可以通过 reflect 和 linkname 来做到,若不得不改函数,那还是 fork 吧。
  3. 「剧本」机制和 XTLS Vision, fixes TLS in TLS, to the star and beyond XTLS/Xray-core#1295 (comment) 的目标比较像,但需要注意的是,TLS in TLS 除了内层 TLS 握手特征,还有个“加密套娃”的特征,而 Restls 新加的“应用数据传输认证”又加了一层,共三层。XTLS Vision 可以直接裸奔,也是需要内外同为 TLSv1.3。

感谢 @RPRX 的评论。

  1. 我们理解REALITY的设计目标,即提供伪装的同时使用TLS的加密通道;而Restls的设计目标之一是兼容目前所有主流TLS版本,提供更多选择。两者在设计目标上的不同导致了不同的取舍。TLS1.2确实有不少值得注意的细节,比如已经提到的「AES指纹」,以及0x15包的问题。
  2. Restls对TLS 1.2的支持需要在ClientHello的时候生成KeyExchange的公钥,还需要实现特别的decrypt流程,对utls的更改或许难以避免。不过,如你所说,减少对utls的直接改动确实是值得探索的方向。
  3. 剧本目前的设计基于 @klzgrad 所提出的假设,即「GFW目前只重点关注链接早期的包」,以及「后续的包长度所能提供的信息比较有限」。在这个阶段,剧本可以非常灵活地制造出各种流量模式。这当然不会是完美解决方案,但我们认为相比padding,这为用户提供了一种不一样的选择。现阶段,后续流量中层层叠加导致的包增长没有通用的解决方案,XTLS在处理TLS 1.3流量时确实能避免该问题,但TLS 1.2流量的比例也不容忽视。对于我们而言,或许可以让剧本支持整个链接(而非开头n个包)从而提供这样的能力,但这显然会带来更大的开销。在尚不明确GFW如何利用这一特征的时候,我们准备暂时观望。

@chika0801

This comment was marked as outdated.

@3andne
Copy link
Author

3andne commented Mar 14, 2023

流量整形、流量模仿,应参考先有工作 net4people/bbs#129 (comment)
剧本的包长度应有工具进行现实的采集 net4people/bbs#136 (comment)
剧本的包长度应有定时变换的方法

@klzgrad 感谢评论

  1. 我们在设计剧本时调研了部分现有方案。我们发现现有方案往往倾向于向用户隐藏复杂性,例如只提供一个开关。在这种情况下工具本身更依赖「随机」或自身的采样来作为流量混淆的依据。这样的设计很难稳定地制造出我们所指定的效果(例如模仿HTTP请求)。「剧本」是为了提供这样的能力而设计的,理论上它具有模仿HTTP请求流量模式的能力。
  2. 墙目前对流量模式的识别是一种黑名单模式,即「封杀那些像TLS in TLS的链接」。而封杀具有随机混淆能力的协议需要从黑名单模式转变为白名单模式——「封杀除了合法协议以外的链接」。虽然只有一字之差,但两者的成本是截然不同的。因为TLS in TLS是一个很确定的特征,而「合法协议特征」则模糊得多。我们推测白名单相比黑名单有更高的误杀率,并有些乐观地认为这个误杀率会让墙投鼠忌器。
  3. 在墙完成转变之前,我们应该有机会像你说的那样,探索如何设计长得像HTTP连接的剧本。
  4. 目前剧本有两种处理包长度的方式:
    1. 「随机初始化」,例如规定客户端发出去的第一个包长度随机初始化为200-210之间的数(例如203),那么所有的连接的第一个包都将是203。提供这种随机初始化是因为创造稳定特征——与同一个网站的连接理应有一些包一直具有固定的长度。
    2. 「随机化」,用户规定一个范围,例如规定第二个包长度在400-600之间随机指定,那么每次连接的第二个包会有所不同。

@klzgrad
Copy link

klzgrad commented Mar 14, 2023

用户没有创造足够多熵的能力,当前的参数形式会因为可用性的需求收敛到一些固定的、著名的流量形状。完全可以利用环境因素帮助用户seeding。

指定流量形状不能代替对实际流量形状的记录和审计。实际的流量审计例子见 net4people/bbs#129 (comment) 的图。

模仿著名协议,如果没有足够强的流量审计和对抗分类,完全可能成为下一个不完美鹦鹉。除非做到 net4people/bbs#55 这种流量寄生。所以还是需要一定的随机性。

只有长度还是不够的。在RTT的时间限制下,如果不大量引入延迟,双向的流量特征即是有padding和大包分小包带来的混淆也是有限的,因为包间隔并不是一个显著的信息。当然,不完美的方法也是一种多样性的方法。

@klzgrad
Copy link

klzgrad commented Mar 15, 2023

我再用一个例子来说明这里面的问题:

如果要做TLS内的协议模仿,一种假想的策略叫“协议导言”,即在TLS连接中的第一个应用层请求是真实用户端发起的HTTP请求。例如https://example.com 是代理服务器,那么一个TLS连接创建以后,首先进行一个真实用户端的GET请求(h1或者h2),在完成这个GET请求以后,再开始运载隧道流量。在这种条件下,这个TLS连接的起始段是完全真实的,也不存在进行协议模仿或者采集协议流量形状模型的问题。但是后果是,这个协议导言会凭空增加>3个RTT的延迟。如果是1:1的连接模型,这个增加的延迟是用户不可接受的。如果是1:N的连接模型,即多路复用,这个延迟可以通过预连接进行缓解,如果不能预连接,也会在用户体验上在后续隧道连接中均摊这个延迟。假如1:1的连接模型下又不允许凭空增加>3 RTT延迟,在同一个RTT中把预设的包长度全部发出去,这个混淆作用很有限。这里的关键问题是在用户体验的要求下,在延迟上的变化空间很有限,同一个RTT中间进行大包分小包效果不明显。

@3andne
Copy link
Author

3andne commented Mar 15, 2023

指定流量形状不能代替对实际流量形状的记录和审计。

现阶段确实没有像你给的例子中那样,把流量的收发在时间轴上可视化表现出来,但我们有通过抓包工具进行定性分析。从经验上来讲,普通HTTP请求和内层TLS握手都紧跟在外层TLS握手之后,很难想象Restls出现像obfs4中那样“长达1秒的静默期”的特征。不过,我们认同定量分析的必要性,这将指导我们的后续改进。

如果不大量引入延迟.....同一个RTT中间进行大包分小包效果不明显

这听上去不像是「剧本」存在的问题,因为剧本已经具有增加RT的能力(我们在上文中称之为“打乱收发模式”)。简单把大包拆成小包,或者把小包填充成大包显然不足以混淆,所以我们设计了「要求对方向自己发一定数量的包」的能力。己方会等收到对方的包之后,再向对方继续发送东西,从而凭空制造了RT。由于在制造RT的过程中尽可能使用有效的用户数据,所以可用性也一定程度可以保证。但这些被创造出来的RT往往是连续的,客户端/服务端在发起两个round-trip之间的停顿很短。我们在net4people讨论区看见过一篇论文对这该时间间隔有所定义,但我们暂且称之为RT间隔;或许增加控制RT间隔的能力是一个值得尝试的改进。

@MetaCubeX MetaCubeX locked and limited conversation to collaborators Mar 31, 2023
@H1JK H1JK converted this issue into discussion #477 Mar 31, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants