mirror of
https://github.com/e1732a364fed/v2ray_simple.git
synced 2026-04-23 01:37:05 +08:00
修订文档注释;将自签证书更换为ecc证书;
在代码中,新增了 tls lazy secure 的部分,但还未完成全部代码
This commit is contained in:
@@ -2,5 +2,6 @@
|
||||
v2ray_simple
|
||||
v2ray_simple_linux*
|
||||
v2ray_simple_win*
|
||||
*.exe
|
||||
client.json
|
||||
server.json
|
||||
|
||||
@@ -2,15 +2,18 @@
|
||||
|
||||
V2ray Simple, 建议读作 very simple (显然只适用于汉语母语者),
|
||||
|
||||
正式项目名称是v2ray simple(大小写、带不带连词符或下划线均可),平时可以直接用 very simple 或 verysimple 指代。直接在任何场合 用verysimple 这个名称都是可以的,但是项目名字要弄清楚,是 v2ray_simple
|
||||
verysimple项目大大简化了 转发机制,能提高运行速度。本项目 转发流量时,关键代码直接放在main.go里!非常直白易懂
|
||||
|
||||
正式项目名称是v2ray simple(大小写、带不带连词符或下划线均可),平时可以直接用 verysimple 指代。直接在任何场合 用verysimple 这个名称都是可以的,但是项目名字要弄清楚,是 v2ray_simple
|
||||
|
||||
verysimple项目大大简化了 转发机制,能提高运行速度。
|
||||
|
||||
## 特点
|
||||
|
||||
实现了vless协议(v0,v1)和vlesss(即vless+tcp+tls),入口使用socks5协议
|
||||
|
||||
在本项目里 制定 并实现了 vless v1标准。
|
||||
在本项目里 制定 并实现了 vless v1标准,添加了非mux的fullcone;
|
||||
|
||||
本项目 发明了独特的非魔改tls包的 双向splice
|
||||
|
||||
### 关于vless v1
|
||||
|
||||
@@ -44,9 +47,9 @@ tls lazy encrypt 特性 运行时可以用 -lazy 参数打开(服务端客户
|
||||
|
||||
关于 splice,还可以参考我的文章 https://github.com/hahahrfool/xray_splice-
|
||||
|
||||
该特性不稳定,会导致一些网页访问有时出现异常
|
||||
该特性不完全稳定,可能会导致一些网页访问有时出现异常
|
||||
|
||||
不是速度慢,应该是因为 目前的tls过滤方式有点问题, 对close_alert等情况没处理好。而且使用不同的浏览器,现象也会不同,似乎对safari支持好一些, chrome就差很多
|
||||
不是速度慢,是因为 目前的tls过滤方式有点问题, 对close_alert等情况没处理好。而且使用不同的浏览器,现象也会不同,似乎对safari支持好一些, chrome就差很多
|
||||
|
||||
在我的最新代码里,采用了独特的技术,已经规避了大部分不稳定性。有时网页显示可能会出点问题,但是刷新网页一般可以解决;总之比较适合看视频,毕竟双向splice,不是白给的!
|
||||
|
||||
@@ -60,13 +63,13 @@ tls lazy encrypt 特性 运行时可以用 -lazy 参数打开(服务端客户
|
||||
|
||||
我只是在内网自己试试玩一玩,从来不会真正用于安全性要求高的用途。
|
||||
|
||||
关于splice的一个现有“降速”问题也要看看,我们这里也是会存在的 https://github.com/XTLS/Xray-core/discussions/59
|
||||
关于splice的一个现有“降速”问题也要看看,(linux 的 forward配置问题),我们这里也是会存在的 https://github.com/XTLS/Xray-core/discussions/59
|
||||
|
||||
**注意,因为技术实现不同,该功能不兼容xtls。**, 因为为了能够在tls包外进行过滤,我们需要做很多工作,所以技术实现与xtls是不一样的。
|
||||
|
||||
#### 总结 tls lazy encrypt 技术优点
|
||||
|
||||
解决了xtls一下痛点
|
||||
解决了xtls以下痛点
|
||||
|
||||
1. 233 漏洞
|
||||
2. 只有单向splice
|
||||
@@ -172,6 +175,14 @@ GOARCH=arm64 GOOS=linux go build -trimpath -ldflags "-s -w -buildid=" -o v2ray
|
||||
GOARCH=amd64 GOOS=windows go build -trimpath -ldflags "-s -w -buildid=" -o v2ray_simple_win10_v1.0.0.exe
|
||||
```
|
||||
|
||||
## 生成自签名证书
|
||||
|
||||
注意运行第二行命令时会要求你输入一些信息。确保至少有一行不是空白即可,比如打个1
|
||||
```sh
|
||||
openssl ecparam -genkey -name prime256v1 -out cert.key
|
||||
openssl req -new -x509 -days 7305 -key cert.key -out cert.pem
|
||||
```
|
||||
## 交流
|
||||
|
||||
https://t.me/shadowrocket_unofficial
|
||||
|
||||
|
||||
@@ -1,27 +1,8 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAqW0rLtNVQEep3oXscshiZnJdOafWxPzge2TaicHP6PMbvucM
|
||||
mINdNgGBjxr76JQkq/ryDrAqxsJpSxO7ZSbyZNjVAZQYRIESIB0TOZsKq/T9/NC2
|
||||
re6mgjEPdDLjd5F3imGKfFqfuagRt2COynbRjL8nC553FhY0dVOixN7MY8g8tdvu
|
||||
exWFeSB+rLkvXMRlGIHXS5KzdJpPKkw07hGtirO6QZVgxW52P3FJGnnGDNHuRd70
|
||||
QCSbd59XSIGf2jNadXS0vbiaAYkn02wLMrZFQfXmC0XDFobRXjcjeIbN/wjyoN6T
|
||||
bCM1Lhc+L9HlUzexY0gyL3h3aaSMPKhSl9SvHQIDAQABAoIBAEHREexv1ndRH5E9
|
||||
L1xrsaYgmUyTgeAmaEInLKpFKzJQdp/Te9YneedH8H+aOO/h1NkmdC/2ibeKwIKU
|
||||
2MBzv8gjX6PsVv0Nsu/cu6IuM5gXZS94GO86fV6oFlvKhQjm7qxINhcW0WO7AZ7e
|
||||
GLpYLBFkFJPz7EkdOSW25s1Zy8aa2gDco2QjywxeJkUhk1ewtIW6x7yL9KlXwb/V
|
||||
ewtmbnlPIAE16WoKRe3lSfJatffkEU9uJsGVVxvfow6sJ2AQBZ0D3zBdJYgLupoX
|
||||
B+UaTYe3Upb4cma3EAJLXcUW9crmYoPH4OW8tsHzi1TlUg9eQd0DgEAcVcM3A+I9
|
||||
7lgyX1UCgYEA0rgiuiUzpCy+y8c2Mi92QiOdaxBfP4WBfi9HbXjU83H8SpT358cn
|
||||
JQfvZVMcRm3zTZFe5Z0mlTJOAs1uj9McrDP1p48k8ahoGYAtSm6etFTRR0Kq12PA
|
||||
32fUqXV81i5iGwmdSfmWfeAuY5XbJ38xcRYOeHOV0/G2w1qwCOeUJjsCgYEAzdV5
|
||||
sSzf6EZybK/guHIdHUqCxTAc7T02h3CImz7iEaGawU+AzGc1q5zvEAk90iEGskl0
|
||||
vjTTFL+VamsicmW3P5DZN0/Gut5FE/AaTWjG8hyGhsS2npoiA9jtvjaD4XQKNI0a
|
||||
7clU356muhPwasiwVe2Vx6eMJLb/mhKCUn7nMocCgYEAu6Pa0LXF+aEaua2IlkHr
|
||||
ZdP/HtKyboc9G5eQXGxn/Oz4w5VJ+GxAcFpTlH/gwtqv+NfFkGRTcjIcg6RZmttc
|
||||
Qf/29aGjPUpAgMzCB/DfhCevQGyeYzTiEE6OceQ8KSGenQL/vFrz5t1VkbplMBO0
|
||||
fEYu1pXeyqAIpodAEH3fT/cCgYB1qtjzgTzLEyKsoWqs5odgTE0vns6ajMjUam+d
|
||||
mDgybhkC84kk0MeswH0lxLKzoi+q0jVL2vTkQpWPDYnWrfExBIQ4i4GHKDODL1pJ
|
||||
8GDy3X3GI0RmrKRPYL6gY5fG1chTvGqtjs/XOmIDtAxXbzznEnfyeAS0pGzATl5z
|
||||
/Jn8lwKBgA3saY5JtIREaRRBdVuIi+lWT8wDwoXWx7oQoVY4yTqVCsxF3GlteLnA
|
||||
S+tJdmjCPCOigsikWNxiJtPSYOeQCHZhyU0eS9/oiLWi51BElote3lzCp3J6ePmt
|
||||
cJ3yJB1V/DcTOGm/zxInGkFhcY8lYfFbrWWmifbo2wl5GcIJpaT2
|
||||
-----END RSA PRIVATE KEY-----
|
||||
-----BEGIN EC PARAMETERS-----
|
||||
BggqhkjOPQMBBw==
|
||||
-----END EC PARAMETERS-----
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIJiyKDkte11rShAK5ygu62BP6ioXfKhoylzD/sESGMvvoAoGCCqGSM49
|
||||
AwEHoUQDQgAEsg6Lwv2CIPTotJ5VfbdxpZ80H1tDkXychZLVZ6J98A7VcX9EeFkk
|
||||
vFm+AtHsUBbMatWWy3Bu/EXWq5hi9M65iw==
|
||||
-----END EC PRIVATE KEY-----
|
||||
|
||||
@@ -1,20 +1,8 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDRjCCAi4CCQCSSzLVNZv+qDANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQGEwJj
|
||||
bjEMMAoGA1UECAwDc2RmMQwwCgYDVQQHDANhc2YxCzAJBgNVBAoMAnNmMQswCQYD
|
||||
VQQLDAJkZjEMMAoGA1UEAwwDZGZzMRIwEAYJKoZIhvcNAQkBFgNzZmQwHhcNMjIw
|
||||
MzAzMTczMDIyWhcNMjIwNDAyMTczMDIyWjBlMQswCQYDVQQGEwJjbjEMMAoGA1UE
|
||||
CAwDc2RmMQwwCgYDVQQHDANhc2YxCzAJBgNVBAoMAnNmMQswCQYDVQQLDAJkZjEM
|
||||
MAoGA1UEAwwDZGZzMRIwEAYJKoZIhvcNAQkBFgNzZmQwggEiMA0GCSqGSIb3DQEB
|
||||
AQUAA4IBDwAwggEKAoIBAQCpbSsu01VAR6nehexyyGJmcl05p9bE/OB7ZNqJwc/o
|
||||
8xu+5wyYg102AYGPGvvolCSr+vIOsCrGwmlLE7tlJvJk2NUBlBhEgRIgHRM5mwqr
|
||||
9P380Lat7qaCMQ90MuN3kXeKYYp8Wp+5qBG3YI7KdtGMvycLnncWFjR1U6LE3sxj
|
||||
yDy12+57FYV5IH6suS9cxGUYgddLkrN0mk8qTDTuEa2Ks7pBlWDFbnY/cUkaecYM
|
||||
0e5F3vRAJJt3n1dIgZ/aM1p1dLS9uJoBiSfTbAsytkVB9eYLRcMWhtFeNyN4hs3/
|
||||
CPKg3pNsIzUuFz4v0eVTN7FjSDIveHdppIw8qFKX1K8dAgMBAAEwDQYJKoZIhvcN
|
||||
AQELBQADggEBAJw/UdmBc3mqpaTfy8ZlelTKd8vQvEXiNMU/A9ie7dIyUxYQufNw
|
||||
jLYUJs1WEY5oDjA7zRsF0UGxYrIrx3zSsacw5VGOjjHFSSu2ZTJ7glFufnWlfEl9
|
||||
MBET2sHFg9vm35H0aKvwMEQppezwfO/YC9qAzm6Vl3R/pEvbxxSfdaqY02hkfAiu
|
||||
t0IUzm1AWAU/KJyKjVQnlvKH0rc59lAplWOul1Ju0mhgbbXt2BfLh2TpcRvvaver
|
||||
shPR8VTaQbmssaTAu0TEI5tBODkB74c+zEO4lHbtsc3vtO1os/NYnL7S27Cjt7zI
|
||||
j5cpQ75Kw4zg8qeTwHqnQmo4z8sGfEUm1kI=
|
||||
MIIBBjCBrgIJAIOrQb0ZSnWgMAoGCCqGSM49BAMCMAwxCjAIBgNVBAoMATEwHhcN
|
||||
MjIwMzEzMDgzMzM3WhcNNDIwMzEzMDgzMzM3WjAMMQowCAYDVQQKDAExMFkwEwYH
|
||||
KoZIzj0CAQYIKoZIzj0DAQcDQgAEsg6Lwv2CIPTotJ5VfbdxpZ80H1tDkXychZLV
|
||||
Z6J98A7VcX9EeFkkvFm+AtHsUBbMatWWy3Bu/EXWq5hi9M65izAKBggqhkjOPQQD
|
||||
AgNHADBEAiBSXOvcDdEKXbHWuglN7t8cY9ZLSU280WpStZQVLONTnwIgfEnuwk1F
|
||||
gHrM4WOnNH6JONOEcC3cN5BN3TUkLWXV6oU=
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
@@ -36,18 +36,18 @@ var (
|
||||
//directClient proxy.Client
|
||||
|
||||
tls_lazy_encrypt bool
|
||||
tls_half_lazy bool
|
||||
tls_lazy_secure bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
//directClient, _ = proxy.ClientFromURL("direct://")
|
||||
|
||||
flag.BoolVar(&tls_lazy_encrypt, "lazy", false, "tls lazy encrypt (splice)")
|
||||
flag.BoolVar(&tls_half_lazy, "hl", false, "tls half lazy, filter data when write and use splice when read; only take effect when '-lazy' is set")
|
||||
flag.BoolVar(&tls_lazy_secure, "ls", false, "tls lazy secure, use special techs to ensure the tls lazy encrypt data can't be detected. Only valid at client end.")
|
||||
|
||||
flag.StringVar(&configFileName, "c", "client.json", "config file name")
|
||||
|
||||
flag.StringVar(&uniqueTestDomain, "td", "", "test a single domain")
|
||||
flag.StringVar(&uniqueTestDomain, "td", "", "test a single domain, like www.domain.com")
|
||||
}
|
||||
|
||||
func printVersion() {
|
||||
@@ -128,6 +128,7 @@ func main() {
|
||||
}
|
||||
log.Println("failed to accepted connection: ", err)
|
||||
if strings.Contains(errStr, "too many") {
|
||||
log.Println("To many incoming conn! Sleep ", errStr)
|
||||
time.Sleep(time.Millisecond * 500)
|
||||
}
|
||||
continue
|
||||
@@ -319,7 +320,7 @@ func handleNewIncomeConnection(localServer proxy.Server, remoteClient proxy.Clie
|
||||
var realTargetAddr *proxy.Addr = targetAddr //direct的话自己是没有目的地址的,直接使用 请求的地址
|
||||
|
||||
if uniqueTestDomain != "" && uniqueTestDomain != targetAddr.Name {
|
||||
log.Println("request not contain same domain", targetAddr, uniqueTestDomain)
|
||||
log.Println("request isn't the appointed domain", targetAddr, uniqueTestDomain)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -339,13 +340,22 @@ func handleNewIncomeConnection(localServer proxy.Server, remoteClient proxy.Clie
|
||||
|
||||
var clientEndRemoteClientTlsRawReadRecorder *tlsLayer.Recorder
|
||||
|
||||
if client.IsUseTLS() {
|
||||
if client.IsUseTLS() { //即客户端
|
||||
|
||||
if tls_lazy_encrypt {
|
||||
clientEndRemoteClientTlsRawReadRecorder = tlsLayer.NewRecorder()
|
||||
teeConn := tlsLayer.NewTeeConn(clientConn, clientEndRemoteClientTlsRawReadRecorder)
|
||||
|
||||
clientConn = teeConn
|
||||
if tls_lazy_secure {
|
||||
// 如果使用secure办法,则我们每次不能先拨号,而是要detect用户的首包后再拨号
|
||||
// 这种情况只需要客户端操作, 此时我们wrc直接传入原始的 刚拨号好的 tcp连接,即 clientConn
|
||||
tryRawCopy(true, client, clientConn, wlc, nil, true, nil)
|
||||
return
|
||||
|
||||
} else {
|
||||
clientEndRemoteClientTlsRawReadRecorder = tlsLayer.NewRecorder()
|
||||
teeConn := tlsLayer.NewTeeConn(clientConn, clientEndRemoteClientTlsRawReadRecorder)
|
||||
|
||||
clientConn = teeConn
|
||||
}
|
||||
}
|
||||
|
||||
tlsConn, err := client.GetTLS_Client().Handshake(clientConn)
|
||||
@@ -364,6 +374,18 @@ func handleNewIncomeConnection(localServer proxy.Server, remoteClient proxy.Clie
|
||||
return
|
||||
}
|
||||
|
||||
if tls_lazy_encrypt {
|
||||
isclient := client.IsUseTLS()
|
||||
if isclient {
|
||||
tryRawCopy(false, nil, wrc, wlc, baseLocalConn, true, clientEndRemoteClientTlsRawReadRecorder)
|
||||
} else {
|
||||
tryRawCopy(false, nil, wrc, wlc, baseLocalConn, false, serverEndLocalServerTlsRawReadRecorder)
|
||||
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
// debug时可以使用这段代码
|
||||
go func() {
|
||||
@@ -375,18 +397,6 @@ func handleNewIncomeConnection(localServer proxy.Server, remoteClient proxy.Clie
|
||||
log.Println("远程->本地 转发结束", realTargetAddr.String(), n, e)
|
||||
*/
|
||||
|
||||
if tls_lazy_encrypt {
|
||||
isclient := client.IsUseTLS()
|
||||
if isclient {
|
||||
tryRawCopy(wrc, wlc, baseLocalConn, true, clientEndRemoteClientTlsRawReadRecorder)
|
||||
} else {
|
||||
tryRawCopy(wrc, wlc, baseLocalConn, false, serverEndLocalServerTlsRawReadRecorder)
|
||||
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
go io.Copy(wrc, wlc)
|
||||
io.Copy(wlc, wrc)
|
||||
|
||||
@@ -395,7 +405,8 @@ func handleNewIncomeConnection(localServer proxy.Server, remoteClient proxy.Clie
|
||||
// tryRawCopy 尝试能否直接对拷,对拷 直接使用 原始 TCPConn,也就是裸奔转发
|
||||
//和 xtls的splice 含义相同
|
||||
// 我们内部先 使用 DetectConn进行过滤分析,然后再判断进化为splice 或者退化为普通拷贝
|
||||
func tryRawCopy(wrc, wlc io.ReadWriter, localConn net.Conn, isclient bool, theRecorder *tlsLayer.Recorder) {
|
||||
// 前两个参数仅用于 tls_lazy_secure
|
||||
func tryRawCopy(useSecureMethod bool, proxy_client proxy.Client, wrc, wlc io.ReadWriter, localConn net.Conn, isclient bool, theRecorder *tlsLayer.Recorder) {
|
||||
|
||||
//如果用了 lazy_encrypt, 则不直接利用Copy,因为有两个阶段:判断阶段和直连阶段
|
||||
// 在判断阶段,因为还没确定是否是 tls,所以是要继续用tls加密的,
|
||||
@@ -415,38 +426,43 @@ func tryRawCopy(wrc, wlc io.ReadWriter, localConn net.Conn, isclient bool, theRe
|
||||
|
||||
var rawWRC *net.TCPConn
|
||||
|
||||
//wrc 有两种情况,如果客户端那就是tls,服务端那就是direct。我们不讨论服务端 处于中间层的情况
|
||||
if !useSecureMethod {
|
||||
|
||||
if isclient {
|
||||
// 不过实际上客户端 wrc 是 vless的 UserConn, 而UserConn的底层连接才是TLS
|
||||
// 很明显,目前我们只支持vless所以才可这么操作,以后再说。
|
||||
//wrc 有两种情况,如果客户端那就是tls,服务端那就是direct。我们不讨论服务端 处于中间层的情况
|
||||
|
||||
wrcVless := wrc.(*vless.UserConn)
|
||||
tlsConn := wrcVless.Conn.(*tlsLayer.Conn)
|
||||
rawWRC = tlsConn.GetRaw(tls_lazy_encrypt)
|
||||
if isclient {
|
||||
// 不过实际上客户端 wrc 是 vless的 UserConn, 而UserConn的底层连接才是TLS
|
||||
// 很明显,目前我们只支持vless所以才可这么操作,以后再说。
|
||||
|
||||
//不过仔细思考,我们根本不需要这么繁琐地获取啊?!因为我们的 原始连接我们本来就是有的!
|
||||
//rawWRC = localConn.(*net.TCPConn) //然而我实测,竟然传输会得到错误的结果,怎么回事
|
||||
wrcVless := wrc.(*vless.UserConn)
|
||||
tlsConn := wrcVless.Conn.(*tlsLayer.Conn)
|
||||
rawWRC = tlsConn.GetRaw(tls_lazy_encrypt)
|
||||
|
||||
//不过仔细思考,我们根本不需要这么繁琐地获取啊?!因为我们的 原始连接我们本来就是有的!
|
||||
//rawWRC = localConn.(*net.TCPConn) //然而我实测,竟然传输会得到错误的结果,怎么回事
|
||||
|
||||
} else {
|
||||
rawWRC = wrc.(*net.TCPConn) //因为是direct
|
||||
}
|
||||
|
||||
if rawWRC == nil {
|
||||
if tlsLayer.PDD {
|
||||
log.Println("splice fail reason 0 ")
|
||||
|
||||
}
|
||||
|
||||
if tls_lazy_encrypt {
|
||||
theRecorder.StopRecord()
|
||||
theRecorder.ReleaseBuffers()
|
||||
}
|
||||
|
||||
//退化回原始状态
|
||||
go io.Copy(wrc, wlc)
|
||||
io.Copy(wlc, wrc)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
rawWRC = wrc.(*net.TCPConn) //因为是direct
|
||||
}
|
||||
|
||||
if rawWRC == nil {
|
||||
if tlsLayer.PDD {
|
||||
log.Println("splice fail reason 0 ")
|
||||
|
||||
}
|
||||
|
||||
if tls_lazy_encrypt {
|
||||
theRecorder.StopRecord()
|
||||
theRecorder.ReleaseBuffers()
|
||||
}
|
||||
|
||||
//退化回原始状态
|
||||
go io.Copy(wrc, wlc)
|
||||
io.Copy(wlc, wrc)
|
||||
return
|
||||
rawWRC = wrc.(*net.TCPConn)
|
||||
}
|
||||
|
||||
go func() {
|
||||
@@ -459,9 +475,6 @@ func tryRawCopy(wrc, wlc io.ReadWriter, localConn net.Conn, isclient bool, theRe
|
||||
isgood := false
|
||||
isbad := false
|
||||
|
||||
if tls_half_lazy && isclient { // half_lazy时,写入时不使用splice
|
||||
isbad = true
|
||||
}
|
||||
for {
|
||||
if isgood || isbad {
|
||||
break
|
||||
@@ -558,9 +571,7 @@ func tryRawCopy(wrc, wlc io.ReadWriter, localConn net.Conn, isclient bool, theRe
|
||||
|
||||
isgood2 := false
|
||||
isbad2 := false
|
||||
if tls_half_lazy && !isclient { // half_lazy时,写入时不使用splice
|
||||
isbad2 = true
|
||||
}
|
||||
|
||||
p := common.GetPacket()
|
||||
|
||||
//从 wrc 读取,向 wlccc 写入
|
||||
|
||||
+3
-3
@@ -22,15 +22,15 @@ func NewTlsClient(host string, insecure bool) *Client {
|
||||
}
|
||||
|
||||
func (c *Client) Handshake(underlay net.Conn) (tlsConn *Conn, err error) {
|
||||
rawConn := tls.Client(underlay, c.tlsConfig)
|
||||
err = rawConn.Handshake()
|
||||
rawTlsConn := tls.Client(underlay, c.tlsConfig)
|
||||
err = rawTlsConn.Handshake()
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
tlsConn = &Conn{
|
||||
Conn: rawConn,
|
||||
Conn: rawTlsConn,
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
+5
-5
@@ -6,11 +6,6 @@ import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// 本包会用到这个Conn,唯一特性就是它可以返回tls连接的底层tcp连接,见 GetRaw
|
||||
type Conn struct {
|
||||
*tls.Conn
|
||||
}
|
||||
|
||||
//参考 crypt/tls 的 conn.go, 注意,如果上游代码的底层结构发生了改变,则这里也要跟着修改,保持头部结构一致
|
||||
type faketlsconn struct {
|
||||
// constant
|
||||
@@ -18,6 +13,11 @@ type faketlsconn struct {
|
||||
isClient bool
|
||||
}
|
||||
|
||||
// 本包会用到这个Conn,唯一特性就是它可以返回tls连接的底层tcp连接,见 GetRaw
|
||||
type Conn struct {
|
||||
*tls.Conn
|
||||
}
|
||||
|
||||
func (c *Conn) GetRaw(tls_lazy_encrypt bool) *net.TCPConn {
|
||||
rc := (*faketlsconn)(unsafe.Pointer(uintptr(unsafe.Pointer(c.Conn))))
|
||||
if rc != nil {
|
||||
|
||||
+40
-10
@@ -2,6 +2,7 @@ package tlsLayer
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"flag"
|
||||
"io"
|
||||
"log"
|
||||
@@ -84,6 +85,7 @@ type ComDetectStruct struct {
|
||||
packetCount int
|
||||
|
||||
handShakePass bool
|
||||
handshakeVer uint16
|
||||
|
||||
handshakeFailReason int
|
||||
}
|
||||
@@ -108,6 +110,14 @@ func commonDetect(cd *ComDetectStruct, p []byte, isRead bool) {
|
||||
/*
|
||||
我们把tls的细节放在这个注释里,便于参考
|
||||
|
||||
首先是rfc文件
|
||||
|
||||
tls1.3标准 https://datatracker.ietf.org/doc/html/rfc8446
|
||||
tls1.2标准 https://datatracker.ietf.org/doc/html/rfc5246
|
||||
tls1.1标准 https://datatracker.ietf.org/doc/html/rfc4346
|
||||
tls1.0标准: https://datatracker.ietf.org/doc/html/rfc2246
|
||||
|
||||
|
||||
首先判断握手包,即第一个包
|
||||
The Client Hello messages contain 01 in the sixth data byte of the TCP packet.
|
||||
应该是这里定义的: https://datatracker.ietf.org/doc/html/rfc5246#section-7.4
|
||||
@@ -116,16 +126,16 @@ func commonDetect(cd *ComDetectStruct, p []byte, isRead bool) {
|
||||
//https://datatracker.ietf.org/doc/html/rfc5246
|
||||
|
||||
struct {
|
||||
ContentType type; //第一字节
|
||||
ProtocolVersion version;//第2、3字节
|
||||
uint16 length;// 第4、5字节
|
||||
opaque fragment[TLSPlaintext.length];
|
||||
} TLSPlaintext;
|
||||
ContentType type; //第一字节
|
||||
ProtocolVersion version;//第2、3字节
|
||||
uint16 length;// 第4、5字节
|
||||
opaque fragment[TLSPlaintext.length];
|
||||
} TLSPlaintext;
|
||||
|
||||
//ContentType 中,handshake始终是22,也就是说,tls连接的hello字节第一个肯定是22
|
||||
// 从tls1.0 到 1.3, 这个情况都是一样的
|
||||
|
||||
tls1.0, tls1.2: change_cipher_spec(20), alert(21), handshake(22),application_data(23)
|
||||
tls1.0 ~ tls1.3: change_cipher_spec(20), alert(21), handshake(22),application_data(23)
|
||||
|
||||
enum {
|
||||
hello_request(0), client_hello(1), server_hello(2),
|
||||
@@ -172,6 +182,14 @@ func commonDetect(cd *ComDetectStruct, p []byte, isRead bool) {
|
||||
};
|
||||
} ClientHello;
|
||||
|
||||
但是tls1.3的 clientHello的 ProtocolVersion是 legacy_version,依然是0303
|
||||
https://datatracker.ietf.org/doc/html/rfc8446#section-4.1.2
|
||||
// 而后面在 supported_versions extension 里会包含 0304
|
||||
|
||||
“TLS 1.3 ClientHellos are identified as having
|
||||
a legacy_version of 0x0303 and a supported_versions extension
|
||||
present with 0x0304 as the highest version indicated therein.”
|
||||
|
||||
ProtocolVersion:
|
||||
TLSv1.0 – 0x0301
|
||||
TLSv1.1 – 0x0302
|
||||
@@ -223,7 +241,6 @@ func commonDetect(cd *ComDetectStruct, p []byte, isRead bool) {
|
||||
}
|
||||
if p0 != 22 {
|
||||
cd.handshakeFailReason = 2
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -249,6 +266,15 @@ func commonDetect(cd *ComDetectStruct, p []byte, isRead bool) {
|
||||
return
|
||||
}
|
||||
|
||||
//VersionTLS10,VersionTLS11,VersionTLS12,VersionTLS13
|
||||
handshakeVer := uint16(p[10]) | uint16(p[9])<<8
|
||||
|
||||
cd.handshakeVer = handshakeVer
|
||||
if handshakeVer == tls.VersionTLS12 { //0303
|
||||
//需要判断到底是 tls 1.3 还是 tls1.2
|
||||
|
||||
}
|
||||
|
||||
cd.handShakePass = true
|
||||
|
||||
} else if !cd.handShakePass {
|
||||
@@ -294,8 +320,6 @@ func commonDetect(cd *ComDetectStruct, p []byte, isRead bool) {
|
||||
cd.IsTls = true
|
||||
return
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -310,6 +334,13 @@ func commonDetect(cd *ComDetectStruct, p []byte, isRead bool) {
|
||||
// 其它都是 能被捕捉到的。
|
||||
|
||||
// 23表示 数据层,第二字节3是固定的,然后第3字节 从1到4,表示tls版本,不过tls1.3 和 1.2这里都是 23 3 3
|
||||
|
||||
//见 https://datatracker.ietf.org/doc/html/rfc8446#section-5.1
|
||||
// tls1.3 的 ContentType(23) 后面紧接着的是 legacy_record_version,而这个必须设成 0x0303
|
||||
// 也就是说和tls1.2一样;而1.1的话是 0302, 1.0 是 0301,总之第三字节只会是1,2,3
|
||||
//
|
||||
// 不过因为我们先过滤的clientHello握手包,所以是能够区分 tls1.3/1.2 的;只是在这里验证一下
|
||||
//
|
||||
if p0 == 23 && p1 == 3 && p2 > 0 && p2 < 4 {
|
||||
if PDD {
|
||||
str := "W"
|
||||
@@ -320,7 +351,6 @@ func commonDetect(cd *ComDetectStruct, p []byte, isRead bool) {
|
||||
}
|
||||
|
||||
if !OnlyTest {
|
||||
|
||||
cd.IsTls = true
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -31,8 +31,8 @@ func NewServer(hostAndPort, host, certFile, keyFile string, isInsecure bool) (*S
|
||||
}
|
||||
|
||||
func (s *Server) Handshake(underlay net.Conn) (tlsConn *Conn, err error) {
|
||||
rawConn := tls.Server(underlay, s.tlsConfig)
|
||||
err = rawConn.Handshake()
|
||||
rawTlsConn := tls.Server(underlay, s.tlsConfig)
|
||||
err = rawTlsConn.Handshake()
|
||||
if err != nil {
|
||||
//return tlsConn,
|
||||
err = common.NewErr("tls握手失败", err)
|
||||
@@ -41,7 +41,7 @@ func (s *Server) Handshake(underlay net.Conn) (tlsConn *Conn, err error) {
|
||||
}
|
||||
|
||||
tlsConn = &Conn{
|
||||
Conn: rawConn,
|
||||
Conn: rawTlsConn,
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user