From 6e9808926b118545799794894641c3d4aa1fdffd Mon Sep 17 00:00:00 2001 From: e1732a364fed <75717694+e1732a364fed@users.noreply.github.com> Date: Sat, 1 Jan 2000 00:00:00 +0000 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E8=AE=A2shadowTls=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.go | 7 ++++- netLayer/io.go | 12 --------- tlsLayer/fake.go | 11 ++++++++ tlsLayer/server.go | 25 ++++++++++++------ tlsLayer/shadow.go | 65 +++++++++++++++++++++++++--------------------- 5 files changed, 69 insertions(+), 51 deletions(-) diff --git a/main.go b/main.go index dfb6b1a..a2fb608 100644 --- a/main.go +++ b/main.go @@ -338,7 +338,12 @@ func handleNewIncomeConnection(inServer proxy.Server, defaultClientForThis proxy iics.inServerTlsRawReadRecorder.StartRecord() } - iics.inServerTlsConn = tlsConn + realtlsConn, ok := tlsConn.(tlsLayer.Conn) + if ok { + iics.inServerTlsConn = realtlsConn + + } + wrappedConn = tlsConn } diff --git a/netLayer/io.go b/netLayer/io.go index fa13748..5b4b08f 100644 --- a/netLayer/io.go +++ b/netLayer/io.go @@ -5,8 +5,6 @@ import ( "net" "os" "sync" - - "github.com/e1732a364fed/v2ray_simple/utils" ) // 选择性从 OptionalReader读取, 直到 RemainFirstBufLen 小于等于0 为止; @@ -30,16 +28,6 @@ func (rw *ReadWrapper) Read(p []byte) (n int, err error) { } -func (rw *ReadWrapper) WriteBuffers(buffers [][]byte) (int64, error) { - bigbs, dup := utils.MergeBuffers(buffers) - n, e := rw.Write(bigbs) - if dup { - utils.PutPacket(bigbs) - } - return int64(n), e - -} - // 一个自定义的由多个组件组成的实现 net.Conn 的结构, 也通过设置 Rejecter 实现 RejectConn type IOWrapper struct { EasyNetAddresser diff --git a/tlsLayer/fake.go b/tlsLayer/fake.go index 80d0bb8..34149d3 100644 --- a/tlsLayer/fake.go +++ b/tlsLayer/fake.go @@ -18,11 +18,22 @@ type FakeAppDataConn struct { net.Conn readRemaining int + OptionalReader io.Reader + OptionalReaderRemainLen int + //for readv rr syscall.RawConn } func (c *FakeAppDataConn) Read(p []byte) (n int, err error) { + if c.OptionalReaderRemainLen > 0 { + n, err := c.OptionalReader.Read(p) + if n > 0 { + c.OptionalReaderRemainLen -= n + } + return n, err + } + if c.readRemaining > 0 { if len(p) > c.readRemaining { p = p[:c.readRemaining] diff --git a/tlsLayer/server.go b/tlsLayer/server.go index 6398f54..92c7cd7 100644 --- a/tlsLayer/server.go +++ b/tlsLayer/server.go @@ -14,6 +14,8 @@ type Server struct { tlstype int + //用于shadowTls,使用shadowTls时 我们不使用 tlsConfig + serverName string shadowpass string } @@ -37,25 +39,32 @@ func NewServer(conf Conf) (*Server, error) { } s := &Server{ - tlsConfig: GetTlsConfig(true, conf), - tlstype: conf.Tls_type, + tlstype: conf.Tls_type, } - if conf.Tls_type == ShadowTls2_t { - s.shadowpass = getShadowTlsPasswordFromExtra(conf.Extra) + if conf.IsShadowTls() { + s.serverName = conf.Host + + if conf.Tls_type == ShadowTls2_t { + s.shadowpass = getShadowTlsPasswordFromExtra(conf.Extra) + } + } else { + s.tlsConfig = GetTlsConfig(true, conf) } return s, nil } -func (s *Server) Handshake(clientConn net.Conn) (tlsConn Conn, err error) { +// tls时返回 tlsLayer.Conn, shadowTls1时返回原 clientConn, shadowTls2时返回 FakeAppDataConn +func (s *Server) Handshake(clientConn net.Conn) (result net.Conn, err error) { switch s.tlstype { case ShadowTls_t: - return shadowTls1(s.tlsConfig.ServerName, clientConn) + + return clientConn, shadowTls1(s.serverName, clientConn) case ShadowTls2_t: - return shadowTls2(s.tlsConfig.ServerName, clientConn, s.shadowpass) + return shadowTls2(s.serverName, clientConn, s.shadowpass) } @@ -67,7 +76,7 @@ func (s *Server) Handshake(clientConn net.Conn) (tlsConn Conn, err error) { return } - tlsConn = &conn{ + result = &conn{ Conn: rawTlsConn, ptr: unsafe.Pointer(rawTlsConn), } diff --git a/tlsLayer/shadow.go b/tlsLayer/shadow.go index 2b15909..e408de6 100644 --- a/tlsLayer/shadow.go +++ b/tlsLayer/shadow.go @@ -27,7 +27,8 @@ func getShadowTlsPasswordFromExtra(extra map[string]any) string { return "" } -func shadowTls1(servername string, clientConn net.Conn) (tlsConn *conn, err error) { +// 转发并判断tls1握手结束后直接返回 +func shadowTls1(servername string, clientConn net.Conn) (err error) { var fakeConn net.Conn fakeConn, err = net.Dial("tcp", servername+":443") if err != nil { @@ -70,22 +71,18 @@ func shadowTls1(servername string, clientConn net.Conn) (tlsConn *conn, err erro {Index: 2, E: e2}, }} - return nil, e + return e } if ce := utils.CanLogDebug("shadowTls fake ok "); ce != nil { ce.Write() } - tlsConn = &conn{ - Conn: clientConn, - tlsType: ShadowTls_t, - } - return } -func shadowTls2(servername string, clientConn net.Conn, password string) (tlsConn *conn, err error) { +// 握手成功后返回 *FakeAppDataConn +func shadowTls2(servername string, clientConn net.Conn, password string) (result net.Conn, err error) { var fakeConn net.Conn fakeConn, err = net.Dial("tcp", servername+":443") if err != nil { @@ -112,21 +109,12 @@ func shadowTls2(servername string, clientConn net.Conn, password string) (tlsCon realconn := &FakeAppDataConn{ Conn: clientConn, + + OptionalReader: firstPayload, + OptionalReaderRemainLen: firstPayload.Len(), } - allDataConn := &netLayer.IOWrapper{ - Reader: &utils.ReadWrapper{ - Reader: realconn, - OptionalReader: firstPayload, - RemainFirstBufLen: firstPayload.Len(), - }, - Writer: realconn, - } - - return &conn{ - Conn: allDataConn, - tlsType: ShadowTls2_t, - }, nil + return realconn, nil } else if err == utils.ErrFailed { if ce := utils.CanLogWarn("shadowTls2 fake failed!"); ce != nil { ce.Write() @@ -140,12 +128,13 @@ func shadowTls2(servername string, clientConn net.Conn, password string) (tlsCon } +// 根据shadowTls v2的方式,它一定会返回一个 firstPayload func shadowCopyHandshakeClientToFake(fakeConn, clientConn net.Conn, hashW *utils.HashWriter) (*bytes.Buffer, error) { var header [5]byte step := 0 var applicationDataCount int - buf := utils.GetBuf() + var firstPayload *bytes.Buffer for { if ce := utils.CanLogDebug("shadowTls2 copy "); ce != nil { @@ -159,6 +148,10 @@ func shadowCopyHandshakeClientToFake(fakeConn, clientConn net.Conn, hashW *utils netLayer.PersistConn(clientConn) if err != nil { + if firstPayload != nil { + utils.PutBuf(firstPayload) + + } return nil, utils.ErrInErr{ErrDetail: err, ErrDesc: "shadowTls2, io.ReadFull err"} } @@ -174,21 +167,25 @@ func shadowCopyHandshakeClientToFake(fakeConn, clientConn net.Conn, hashW *utils if contentType == 23 { + if firstPayload == nil { + firstPayload = utils.GetBuf() + } + netLayer.SetCommonReadTimeout(clientConn) - _, err = io.Copy(buf, io.LimitReader(clientConn, int64(length))) + _, err = io.Copy(firstPayload, io.LimitReader(clientConn, int64(length))) netLayer.PersistRead(clientConn) if err != nil { - utils.PutBuf(buf) + utils.PutBuf(firstPayload) return nil, utils.ErrInErr{ErrDetail: err, ErrDesc: "shadowTls2, copy err1"} } if hashW.Written() && length >= 8 { checksum := hashW.Sum() - first8 := buf.Bytes()[:8] + first8 := firstPayload.Bytes()[:8] if ce := utils.CanLogDebug("shadowTls2 check "); ce != nil { ce.Write(zap.Int("step", step), @@ -198,23 +195,23 @@ func shadowCopyHandshakeClientToFake(fakeConn, clientConn net.Conn, hashW *utils } if bytes.Equal(first8, checksum) { - buf.Next(8) - return buf, nil + firstPayload.Next(8) + return firstPayload, nil } } netLayer.SetCommonWriteTimeout(fakeConn) - _, err = io.Copy(fakeConn, io.MultiReader(bytes.NewReader(header[:]), buf)) + _, err = io.Copy(fakeConn, io.MultiReader(bytes.NewReader(header[:]), firstPayload)) netLayer.PersistWrite(fakeConn) if err != nil { - utils.PutBuf(buf) + utils.PutBuf(firstPayload) return nil, utils.ErrInErr{ErrDetail: err, ErrDesc: "shadowTls2, copy err2"} } - buf.Reset() + firstPayload.Reset() applicationDataCount++ } else { @@ -228,17 +225,25 @@ func shadowCopyHandshakeClientToFake(fakeConn, clientConn net.Conn, hashW *utils netLayer.PersistWrite(fakeConn) if err != nil { + if firstPayload != nil { + utils.PutBuf(firstPayload) + } return nil, utils.ErrInErr{ErrDetail: err, ErrDesc: "shadowTls2, copy err3"} } } const maxAppDataCount = 3 if applicationDataCount > maxAppDataCount { + utils.PutBuf(firstPayload) + return nil, utils.ErrFailed } step++ if step > 8 { + if firstPayload != nil { + utils.PutBuf(firstPayload) + } return nil, errors.New("shadowTls2 copy loop > 8, maybe under attack") }