Quinn-jls
Quinn-jls 是 quinn 的fork 分支,该库将QUIC的tls层替换为 JLS协议,以实现 高性能,低延迟的抗白名单封锁的代理协议
特性
- 基于QUIC的多路复用
- 用户层的BBR拥塞控制
- 基于QUIC和tls1.3的0rtt握手
- SNI伪装(Http3网站)
- 无需域名和证书(自签或自动生成)
- 非JLS客户端自动进行UDP转发
使用示例
关于 0 RTT
即便0rtt被使能了,也不一定能实现0rtt握手,0rtt握手有 严格的要求,不符合这些要求的握手将退化为1rtt握手:
- 服务器和客户端必须同时在内存中有0rtt密钥,也就是说,二者 必须曾经建立过连接,内存中有对方的缓存信息。因此刚启动的客户端一定会使用1rtt握手
- 0rtt密钥没有过期,如果服务器和客户端曾经建立过连接,但连接断开时间过久(数个小时),此时0rtt密钥过期,0rtt握手会被拒绝,此时将使用1rtt握手
0 RTT 的安全问题
0 RTT基于TLS1.3. TLS1.3 0RTT功能被广泛认为会遭受重放攻击。然而,个人认为这一安全问题被放大了,尤其是使用单服务器的代理。成功的重放攻击的条件是及其严苛的,它要求至少 有两个服务器使用同一域名(通常大型公司的网站)
根据 RFC 8446 Section 8. 通常有两种类型的
-
第一种重放攻击直接重放0RTT握手,一般TLS协议实现的0RTT密钥至多只能使用一次,该攻击不会生效。
-
第二种更复杂一点。它要求至少有两台服务器使用同一域名, 假设客户端和服务器A建立过连接,连接断开后尝试使用0RTT握手, 此时中间人捕获并拦截了0RTT信息的响应。由于重连接机制的存在,客户端会尝试再次使用0RTT进行连接,此时中间人将该连接重定向到使用同一证书的服务器B,如果服务器B没有和A共享状态信息,B服务器会拒绝0-RTT,并退化为1-RTT,此时数据可能被重放。
对大多数用户来说,他们不会使用服务器集群部署QUIC。即便有几台服务器共享同一域名,使用不同的密码可以规避重放。
此外,因为JLS承载的是代理流量,如果代理流量是明文协议,使用者应当知道流量的不安全性,那么重放攻击不会降低其安全性。因为流量本身就不安全。如果代理流量是加密协议如tls,那么tls是安全协议,本身会处理重放流量。
总而言之JLS不会遭受重放攻击。
已知的问题
- @RPRX 指出, 如果使能0RTT,可以通过流量劫持识别JLS具体来说
- 假设JLS伪装为microsoft.com
- 将0RTT client hello 重定向到microsoft.com后, 0RTT 将被拒绝,退化为1RTT。可以根据这一行为识别JLS
- 但是服务器可以以任何理由拒绝0-RTT,不一定是因为JLS伪装。实际上,只要服务器集群之间没有共享足够多的信息, 那么即便是劫持真实的服务器,也会发生0-RTT拒绝的现象。
- 并且,劫持QUIC流量成本较高(需要解密Initial Packet)。
- 如果担心这一风险,建议关闭0RTT。