3andne / restls

Restls Protocol: A Perfect Impersonation of TLS; Restls协议: 对TLS的完美伪装
BSD 3-Clause "New" or "Revised" License
279 stars 24 forks source link

关于sni阻断的讨论,我在shadowtls尝试建立服务,但发现无法使用,首次链接能通,然后本地ip与服务器ip被阻断3分钟,不知道restls是否也有这个问题? #8

Open moranno opened 1 year ago

moranno commented 1 year ago

这是我在那边的情况描述:https://github.com/ihciah/shadow-tls/issues/78

restls暂时没有测试。

请 @3andne 也来看看?

3andne commented 1 year ago

你好 @moranno 感谢你的反馈。但很遗憾,我们无法告诉你准确的答案,只能给出一些猜测以及建议。

  1. 我们认为GFW除了有域名黑/白名单外,也会有IP黑/白名单。如果你的VPS(甚至客户端的IP)被封杀过,你的流量可能会被高级别审查。我们无法得知究竟发生了什么,但这种情况下,GFW可能不介意用一些误杀率很高的方法。你观察到的现象很难让人有确切结论。
  2. 关于使用shadow-tls被封杀的问题,我可以想到以下原因:
    • 目前所有的shadow-tls客户端都没有关注客户端指纹问题。对于一个在黑名单上的IP,GFW可能会直接封杀可疑指纹的TLS请求 —— 例如clash实现的Go指纹和官方实现的Rust指纹。
    • shadow-tls的设计目标包含「容易实现」,实现的便利性让它不得不牺牲一些隐蔽性。例如我们曾指出,shadow-tls-v3可能导致TLS握手中的一些长度固定的包出现4byte的增长。不过,我们认为这一特征暂时没有被利用。
    • 根据你的描述(第一次成功,之后失败),我们认为GFW目前不太可能是使用篡改包的方法来识别shadow-tls的。
    • 我们认为,GFW还有可能根据代理协议的普遍特征来识别它们,即握手后的行为特征。这其中最为人所知的就是"TLS in TLS"。受限于设计目标,shadow-tls目前并没有关注这一问题。
  3. 我们无法预测「Restls是否有同样的问题」,但上述所有特征,在Restls的最新版本中都有应对:
    • 我们的客户端核心库fork自utls,具有伪装成普通浏览器的能力。
    • 我们的协议以伪装能力为核心目标,除了能够伪装成任意TLS1.2/1.3网站外,在握手阶段不引入其他特征,在握手后继续提供保护。
    • 我们设计了Restls「剧本」机制,用来破坏"TLS in TLS"等行为特征。

我们欢迎你试试Restls的效果: 使用方法 服务端 客户端


Hello @moranno,

Thank you for your feedback. Unfortunately, we cannot give you an accurate answer and can only provide some guesses and suggestions.

  1. We believe that in addition to domain allow/blocklists, the GFW also has IP allow/blocklists. If your VPS (or even your client IP) has been blocked before, your traffic may be subject to higher-level scrutiny. We do not know exactly what happened, but in this situation, the GFW may not hesitate to use methods with high false positive rates. The phenomenon you observed is difficult to draw a definitive conclusion.

  2. Regarding the issue of shadow-tls being blocked, here are our guesses:

    • Currently, all shadow-tls clients do not pay attention to client fingerprint issues. For an IP on the blocklist, the GFW may directly block TLS ClientHello with suspicious fingerprints, such as the Go fingerprint and the Rust fingerprint.
    • The design goal of shadow-tls includes "easy implementation," and the convenience of implementation forces it to sacrifice some stealthiness. For example, we have pointed out that shadow-tls-v3 may cause a 4-byte increase in some fixed-length records in TLS handshake. However, we believe that this feature has not been exploited for the time being.
    • Based on your description (successful the first time, failed thereafter), we believe that the GFW is currently unlikely to use packet tampering to identify shadow-tls.
    • We believe that the GFW may also identify proxies based on their common characteristics, i.e., post-handshake behavioral characteristics. The most well-known of these is "TLS in TLS." Due to its design goals, shadow-tls currently does not pay attention to this issue.
  3. We cannot predict whether Restls has the same issue, but all of the above issues have been addressed in the latest version of Restls:

    • Our client core library is forked from utls and has the ability to disguise as a normal browser.
    • Our protocol focuses on disguise capability as its core goal and does not introduce other characteristics during the handshake. It continues to provide protection after the handshake.
    • We designed the restls-script mechanism for Restls to disrupt behavioral characteristics such as "TLS in TLS."

We invite you to try the effectiveness of Restls:

Usage instructions Server Client

moranno commented 1 year ago

@3andne 刚刚测试了restls tls12和tls13 两种配置,同样发生了和 https://github.com/ihciah/shadow-tls/issues/78 一模一样的阻断...

服务端使用了最新版shadowsocks rust:

./ss-server -s "127.0.0.1:8888" -k 2659d9f0-8d8a-4313-bffa-67194607a6b5 -m "chacha20-ietf-poly1305"
2023-03-15T05:33:41.683452664+00:00 INFO  shadowsocks server 1.15.3 build 2023-03-12T16:41:55.182659561+00:00
2023-03-15T05:33:41.695856850+00:00 INFO  shadowsocks tcp server listening on 127.0.0.1:8888, inbound address 127.0.0.1:8888

restls启动参数:

./restls -s "www.cloudflare.com" -l "0.0.0.0:4430" -p 2659d9f0-8d8a-4313-bffa-67194607a6b5 -f "127.0.0.1:8888" --script "200?100,400?100,1200?200<1,1100~300,1000~100<1,2500~500,1300~50,1300~50,100~1200"
2023-03-15T05:53:14.776740Z  INFO Restls server started as www.cloudflare.com:443 on 0.0.0.0:4430, forwarding to 127.0.0.1:8888
2023-03-15T05:53:34.402576Z ERROR handshake failed: unexpected eof

clash meta配置:

- { name: testrestls, type: ss, server: 150.230.xx.xx, port: 4430, cipher: chacha20-ietf-poly1305, password: 2659d9f0-8d8a-4313-bffa-67194607a6b5, plugin: restls, plugin-opts: { host: "www.cloudflare.com", password: 2659d9f0-8d8a-4313-bffa-67194607a6b5, version-hint: "tls13", client-id: chrome } }

阻断截图: iShot_2023-03-15_14 01 11

3andne commented 1 year ago

请问这是ping吗?你在什么地方ping什么呢?ping是不是不能被代理呢?

moranno commented 1 year ago

请问这是ping吗?你在什么地方ping什么呢?ping是不是不能被代理呢?

是在我本地客户端ping安装有restls的vps 用ping测试是否发生了阻断(阻断的时候目标ip的通信完全被拦截3分钟)

应该是运营商/省墙级别的阻断,不是gfw。

截图是我只要尝试使用restls/shadowtls/reallity链接目标IP,目标ip就会被完全阻断3分钟。 这个情况大多发生电信运营商下

但使用自己域名的trojan/vless或vmess + tls则不会发生这样的阻断情况

3andne commented 1 year ago

我有一个猜测,但需要你帮忙核实一下,请问你可以更改你在墙内的主机的hosts吗?可否在你墙内的机器上将你要伪装的网站(例如cloudflare.com)解析为你的vps ip,然后在你墙内的机器上使用curl或wget或者浏览器去访问你的VPS,即cloudflare.com。多发几次请求,然后看看会不会出现同样的阻断。

moranno commented 1 year ago

我有一个猜测,但需要你帮忙核实一下,请问你可以更改你在墙内的主机的hosts吗?可否在你墙内的机器上将你要伪装的网站(例如cloudflare.com)解析为你的vps ip,然后在你墙内的机器上使用curl或wget或者浏览器去访问你的VPS,即cloudflare.com。多发几次请求,然后看看会不会出现同样的阻断。

今天测试了,使用浏览器同样发生了阻断,下面是测试过程:

iShot_2023-03-16_10 19 44

iShot_2023-03-16_10 22 26

iShot_2023-03-16_10 28 31

下面是console的restls日志输出

./restls -s "www.cloudflare.com" -l "0.0.0.0:4430" -p 2659d9f0-8d8a-4313-bffa-67194607a6b5 -f "127.0.0.1:8888" --script "200?100,400?100,1200?200<1,1100~300,1000~100<1,2500~500,1300~50,1300~50,100~1200"
2023-03-16T02:16:43.631593Z  INFO Restls server started as www.cloudflare.com:443 on 0.0.0.0:4430, forwarding to 127.0.0.1:8888
2023-03-16T02:17:13.836116Z ERROR handshake failed: unexpected eof  //第一次使用clash meta尝试链接,下面是修改host后用浏览器访问www.cloudflare.com
2023-03-16T02:23:17.498180Z ERROR handshake failed: reject: incorrect session id, expect: [74, 46, 156, 242, 124, 77, 132, 171, 230, 75, 219, 104, 199, 123, 11, 204], actual [97, 206, 231, 29, 41, 192, 77, 213, 159, 176, 25, 189, 230, 70, 117, 39]
2023-03-16T02:23:17.508544Z ERROR handshake failed: reject: incorrect session id, expect: [130, 32, 124, 85, 250, 208, 189, 44, 91, 110, 104, 247, 175, 160, 54, 133], actual [162, 17, 39, 217, 163, 246, 188, 215, 255, 43, 183, 112, 171, 109, 147, 177]
2023-03-16T02:26:23.965291Z ERROR handshake failed: reject: incorrect session id, expect: [39, 252, 245, 101, 231, 173, 156, 82, 34, 229, 83, 252, 117, 188, 193, 239], actual [222, 253, 79, 239, 50, 46, 5, 87, 253, 26, 181, 138, 6, 226, 189, 181]
3andne commented 1 year ago

从你的log看得出来

  1. 确实是通过浏览器连接成功了。
  2. 排除你遇到的墙根据代理流量特征来封杀你,因为即便是使用浏览器(无代理行为)也会被封杀。
  3. 结合你所说的trojan可用,我们推测你遇到的墙会检查IP是否属于域名,如果不属于则进行阻断。我们不知道这样会有多大的代价或误伤率,但如我们在一开始所说的,对于一个黑名单上的IP,墙应该不介意使用准确率低/代价高的激进手段。
moranno commented 1 year ago
3. 结合你所说的trojan可用,我们推测你遇到的墙会检查IP是否属于域名,如果不属于则进行阻断。

有点不解的是,墙如何检查IP是否属于域名呢?通过域名(反向)解析还是通过 TLS Client Hello 中是否包括 SNI 来进行判断?

如果是前者,那我把这个某个域名解析到这个IP;如果是后者,那是否能在TLS Client Hello指定发送SNI?

3andne commented 1 year ago

墙可以通过DNS确定IP和域名的关系。你不拥有一个域名的话是不可能将其解析到你的IP上的。

moranno commented 1 year ago

墙可以通过DNS确定IP和域名的关系。你不拥有一个域名的话是不可能将其解析到你的IP上的。

如果是通过dns来确定,那我应该可以在vps建一个正常的网站服务,然后配置目标域名为自己的域名来偷自己的tls链接...这就去试试这个方案。

moranno commented 1 year ago

@3andne @RPRX 基本上确定是墙针对某些IP段的新阻断手段,参考这些例子:https://note.lazzman.com:18084/doc/277/

chika0801 commented 1 year ago

墙可以通过DNS确定IP和域名的关系。你不拥有一个域名的话是不可能将其解析到你的IP上的。

https://github.com/XTLS/Xray-core/discussions/1772

类似现象也观察到了,推测当地ISP对一些黑IP的阻断