更新文档与注释

This commit is contained in:
hahahrfool
2022-03-13 13:30:29 +08:00
parent 9618eda770
commit 1e84e3b99a
4 changed files with 39 additions and 5 deletions
+23 -1
View File
@@ -60,7 +60,29 @@ tls lazy encrypt 特性 运行时可以用 -lazy 参数打开(服务端客户
我只是在内网自己试试玩一玩,从来不会真正用于安全性要求高的用途。 我只是在内网自己试试玩一玩,从来不会真正用于安全性要求高的用途。
注意,因为技术实现不同,该功能不兼容xtls。 关于splice的一个现有“降速”问题也要看看,我们这里也是会存在的 https://github.com/XTLS/Xray-core/discussions/59
**注意,因为技术实现不同,该功能不兼容xtls。**, 因为为了能够在tls包外进行过滤,我们需要做很多工作,所以技术实现与xtls是不一样的。
#### 总结 tls lazy encrypt 技术优点
解决了xtls一下痛点
1. 233 漏洞
2. 只有单向splice
3. 无法与fullcone配合
4. 无法与utls配合
原因:
1. 我不使用循环进行tls过滤,而且不魔改tls包
2. 我直接开启了双向splice;xtls只能优化客户端性能,我们两端都会优化
3. 因为我的vless v1的fullcone是非mux的,分离信道,所以说是可以应用splice的(以后会添加支持,可能需要加一些代码,有待考察)
4. 因为我不魔改tls包,所以说可以套任何tls包的,比如utls
而且alert根本不需要过滤,因为反正xtls本身过滤了还是有两个issue存在,是吧。
而且后面可以考虑,如果底层是使用的tls1.2,那么我们上层也可以用 tls1.2来握手。这个是可以做到的,因为底层的判断在客户端握手刚发生时就可以做到,而此时我们先判断,然后再发起对 服务端的连接,即可。
### ws/grpc ### ws/grpc
+6 -2
View File
@@ -392,7 +392,7 @@ func handleNewIncomeConnection(localServer proxy.Server, remoteClient proxy.Clie
} }
// tryRawCopy 尝试能否直接对拷,对拷 直接使用 原始 TCPConn // tryRawCopy 尝试能否直接对拷,对拷 直接使用 原始 TCPConn,也就是裸奔转发
//和 xtls的splice 含义相同 //和 xtls的splice 含义相同
// 我们内部先 使用 DetectConn进行过滤分析,然后再判断进化为splice 或者退化为普通拷贝 // 我们内部先 使用 DetectConn进行过滤分析,然后再判断进化为splice 或者退化为普通拷贝
func tryRawCopy(wrc, wlc io.ReadWriter, localConn net.Conn, isclient bool, theRecorder *tlsLayer.Recorder) { func tryRawCopy(wrc, wlc io.ReadWriter, localConn net.Conn, isclient bool, theRecorder *tlsLayer.Recorder) {
@@ -403,7 +403,7 @@ func tryRawCopy(wrc, wlc io.ReadWriter, localConn net.Conn, isclient bool, theRe
// 之所以可以对拷直连,是因为无论是 socks5 还是vless,只是在最开始的部分 加了目标头,后面的所有tcp连接都是直接传输的数据,就是说,一开始握手什么的是不能直接对拷的,等到后期就可以了 // 之所以可以对拷直连,是因为无论是 socks5 还是vless,只是在最开始的部分 加了目标头,后面的所有tcp连接都是直接传输的数据,就是说,一开始握手什么的是不能直接对拷的,等到后期就可以了
// 而且之所以能对拷,还有个原因就是,远程服务器 与 客户端 总是源源不断地 为 我们的 原始 TCP 连接 提供数据,我们只是一个中间商而已,左手倒右手 // 而且之所以能对拷,还有个原因就是,远程服务器 与 客户端 总是源源不断地 为 我们的 原始 TCP 连接 提供数据,我们只是一个中间商而已,左手倒右手
// 如果开启了 half lazy 开关,则会在 Write的那一端 加强过滤,过滤一些alert,然后 只在Read端 进行splice // 如果开启了 half lazy 开关,则会在 Write的那一端 加强过滤,过滤一些alert(目前还没做),然后 只在Read端 进行splice
// //
// 如果是客户端,则 从 wlc 读取,写入 wrc ,这种情况是 Write, 然后对于 DetectConn 来说是 Read,即 从DetectConn读取,然后 写入到远程连接 // 如果是客户端,则 从 wlc 读取,写入 wrc ,这种情况是 Write, 然后对于 DetectConn 来说是 Read,即 从DetectConn读取,然后 写入到远程连接
// 如果是服务端,则 从 wrc 读取,写入 wlc, 这种情况是 Write // 如果是服务端,则 从 wrc 读取,写入 wlc, 这种情况是 Write
@@ -425,6 +425,9 @@ func tryRawCopy(wrc, wlc io.ReadWriter, localConn net.Conn, isclient bool, theRe
tlsConn := wrcVless.Conn.(*tlsLayer.Conn) tlsConn := wrcVless.Conn.(*tlsLayer.Conn)
rawWRC = tlsConn.GetRaw(tls_lazy_encrypt) rawWRC = tlsConn.GetRaw(tls_lazy_encrypt)
//不过仔细思考,我们根本不需要这么繁琐地获取啊?!因为我们的 原始连接我们本来就是有的!
//rawWRC = localConn.(*net.TCPConn) //然而我实测,竟然传输会得到错误的结果,怎么回事
} else { } else {
rawWRC = wrc.(*net.TCPConn) //因为是direct rawWRC = wrc.(*net.TCPConn) //因为是direct
} }
@@ -468,6 +471,7 @@ func tryRawCopy(wrc, wlc io.ReadWriter, localConn net.Conn, isclient bool, theRe
break break
} }
//wrc.Write(p[:n]) //wrc.Write(p[:n])
//在判断 “是TLS” 的瞬间,它会舍弃写入数据,而把写入的主动权交回我们,我们发送特殊命令后,通过直连写入数据
if wlcdc.R.IsTls && wlcdc.RawConn != nil { if wlcdc.R.IsTls && wlcdc.RawConn != nil {
isgood = true isgood = true
+1
View File
@@ -421,6 +421,7 @@ func (dw *DetectWriter) SimpleWrite(p []byte) (n int, err error) {
return return
} }
//用于通知 “我们要开始tls数据部分啦” 的 “特殊指令”,该指令会被tls加密发送,因此不用担心暴露
var SpecialCommand = []byte{1, 2, 3, 4} var SpecialCommand = []byte{1, 2, 3, 4}
//发现,数据基本就是 23 3 3 22 3 322 3 1 20 3 3 //发现,数据基本就是 23 3 3 22 3 322 3 1 20 3 3
+9 -2
View File
@@ -35,6 +35,8 @@ func (wr *Recorder) StopRecord() {
wr.stop = true wr.stop = true
} }
// StartRecord后,Recorder就会开始记录数据。默认Recorder就是开启状态;
// 所以此方法仅用于之前 Stop过
func (wr *Recorder) StartRecord() { func (wr *Recorder) StartRecord() {
wr.stop = false wr.stop = false
} }
@@ -50,6 +52,7 @@ func (wr *Recorder) ReleaseBuffers() {
} }
// 打印内部所有包的前10字节
func (wr *Recorder) DigestAll() { func (wr *Recorder) DigestAll() {
tmp := wr.Buflist tmp := wr.Buflist
@@ -88,7 +91,7 @@ func (wr *Recorder) Write(p []byte) (n int, err error) {
} }
// 实现net.Conn,专门用于 tls 检测步骤 // 实现net.Conn,专门用于 tls 检测步骤
//每次 Read TeeConn, 都会从OldConn进行Read,然后把Read到的数据同时写入TargetWriter //每次 Read TeeConn, 都会从OldConn进行Read,然后把Read到的数据同时写入 TargetWriter(NewTeeConn 的参数)
// //
// 这个TeeConn设计时,专门用于 给 tls包一个 假的 net.Conn, 避免它 主动close我们的原Conn // 这个TeeConn设计时,专门用于 给 tls包一个 假的 net.Conn, 避免它 主动close我们的原Conn
// //
@@ -110,6 +113,7 @@ func NewTeeConn(oldConn net.Conn, targetWriter io.Writer) *TeeConn {
} }
// 使用我们的Tee功能进行Read
func (tc *TeeConn) Read(b []byte) (n int, err error) { func (tc *TeeConn) Read(b []byte) (n int, err error) {
n, err = tc.TargetReader.Read(b) n, err = tc.TargetReader.Read(b)
@@ -117,19 +121,22 @@ func (tc *TeeConn) Read(b []byte) (n int, err error) {
return return
} }
// 直接使用原Conn发送
func (tc *TeeConn) Write(b []byte) (n int, err error) { func (tc *TeeConn) Write(b []byte) (n int, err error) {
return tc.OldConn.Write(b) return tc.OldConn.Write(b)
} }
//返回原Conn的地址
func (tc *TeeConn) LocalAddr() net.Addr { func (tc *TeeConn) LocalAddr() net.Addr {
return tc.OldConn.LocalAddr() return tc.OldConn.LocalAddr()
} }
//返回原Conn的地址
func (tc *TeeConn) RemoteAddr() net.Addr { func (tc *TeeConn) RemoteAddr() net.Addr {
return tc.OldConn.RemoteAddr() return tc.OldConn.RemoteAddr()
} }
// //Close只会试图通知外界 Close调用过,并不真Close原Conn
func (tc *TeeConn) Close() error { func (tc *TeeConn) Close() error {
tc.closeCalled = true tc.closeCalled = true
log.Println("TeeConn Close Called") log.Println("TeeConn Close Called")