add tls handshake for recorder
This commit is contained in:
@@ -14,7 +14,7 @@ require (
|
|||||||
github.com/go-gost/gosocks5 v0.4.2
|
github.com/go-gost/gosocks5 v0.4.2
|
||||||
github.com/go-gost/plugin v0.1.1
|
github.com/go-gost/plugin v0.1.1
|
||||||
github.com/go-gost/relay v0.5.0
|
github.com/go-gost/relay v0.5.0
|
||||||
github.com/go-gost/tls-dissector v0.0.2-0.20220408131628-aac992c27451
|
github.com/go-gost/tls-dissector v0.1.0
|
||||||
github.com/go-redis/redis/v8 v8.11.5
|
github.com/go-redis/redis/v8 v8.11.5
|
||||||
github.com/gobwas/glob v0.2.3
|
github.com/gobwas/glob v0.2.3
|
||||||
github.com/golang/snappy v0.0.4
|
github.com/golang/snappy v0.0.4
|
||||||
|
|||||||
@@ -63,8 +63,8 @@ github.com/go-gost/plugin v0.1.1 h1:LNoc/Rqwb3ceGhhxwhpjf1SeeYBGe80MJ9E4lpM3qak=
|
|||||||
github.com/go-gost/plugin v0.1.1/go.mod h1:oN23l+yGDCIP9G3KnDl/I/0zVGOobZUDCB2Z5yYYXts=
|
github.com/go-gost/plugin v0.1.1/go.mod h1:oN23l+yGDCIP9G3KnDl/I/0zVGOobZUDCB2Z5yYYXts=
|
||||||
github.com/go-gost/relay v0.5.0 h1:JG1tgy/KWiVXS0ukuVXvbM0kbYuJTWxYpJ5JwzsCf/c=
|
github.com/go-gost/relay v0.5.0 h1:JG1tgy/KWiVXS0ukuVXvbM0kbYuJTWxYpJ5JwzsCf/c=
|
||||||
github.com/go-gost/relay v0.5.0/go.mod h1:lcX+23LCQ3khIeASBo+tJ/WbwXFO32/N5YN6ucuYTG8=
|
github.com/go-gost/relay v0.5.0/go.mod h1:lcX+23LCQ3khIeASBo+tJ/WbwXFO32/N5YN6ucuYTG8=
|
||||||
github.com/go-gost/tls-dissector v0.0.2-0.20220408131628-aac992c27451 h1:xj8gUZGYO3nb5+6Bjw9+tsFkA9sYynrOvDvvC4uDV2I=
|
github.com/go-gost/tls-dissector v0.1.0 h1:hpgzC/Qt9MMGGie+hLeBAZ379OG72sSc1TRiG7+rahI=
|
||||||
github.com/go-gost/tls-dissector v0.0.2-0.20220408131628-aac992c27451/go.mod h1:/9QfdewqmHdaE362Hv5nDaSWLx3pCmtD870d6GaquXs=
|
github.com/go-gost/tls-dissector v0.1.0/go.mod h1:/9QfdewqmHdaE362Hv5nDaSWLx3pCmtD870d6GaquXs=
|
||||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||||
|
|||||||
@@ -25,13 +25,14 @@ import (
|
|||||||
xio "github.com/go-gost/x/internal/io"
|
xio "github.com/go-gost/x/internal/io"
|
||||||
netpkg "github.com/go-gost/x/internal/net"
|
netpkg "github.com/go-gost/x/internal/net"
|
||||||
xhttp "github.com/go-gost/x/internal/net/http"
|
xhttp "github.com/go-gost/x/internal/net/http"
|
||||||
|
tls_util "github.com/go-gost/x/internal/util/tls"
|
||||||
rate_limiter "github.com/go-gost/x/limiter/rate"
|
rate_limiter "github.com/go-gost/x/limiter/rate"
|
||||||
xrecorder "github.com/go-gost/x/recorder"
|
xrecorder "github.com/go-gost/x/recorder"
|
||||||
"github.com/go-gost/x/registry"
|
"github.com/go-gost/x/registry"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultBodySize = 1024 * 1024 * 10 // 10MB
|
defaultBodySize = 1024 * 1024 // 1MB
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -100,7 +101,9 @@ func (h *redirectHandler) Handle(ctx context.Context, conn net.Conn, opts ...han
|
|||||||
ro.Err = err.Error()
|
ro.Err = err.Error()
|
||||||
}
|
}
|
||||||
ro.Duration = time.Since(start)
|
ro.Duration = time.Since(start)
|
||||||
ro.Record(ctx, h.recorder.Recorder)
|
if err := ro.Record(ctx, h.recorder.Recorder); err != nil {
|
||||||
|
log.Errorf("record: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.WithFields(map[string]any{
|
log.WithFields(map[string]any{
|
||||||
@@ -309,14 +312,21 @@ func (h *redirectHandler) handleHTTP(ctx context.Context, rw io.ReadWriter, radd
|
|||||||
|
|
||||||
func (h *redirectHandler) handleHTTPS(ctx context.Context, rw io.ReadWriter, raddr, dstAddr net.Addr, ro *xrecorder.HandlerRecorderObject, log logger.Logger) error {
|
func (h *redirectHandler) handleHTTPS(ctx context.Context, rw io.ReadWriter, raddr, dstAddr net.Addr, ro *xrecorder.HandlerRecorderObject, log logger.Logger) error {
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
host, err := h.getServerName(ctx, io.TeeReader(rw, buf))
|
|
||||||
|
clientHello, err := dissector.ParseClientHello(io.TeeReader(rw, buf))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
ro.TLS = &xrecorder.TLSRecorderObject{
|
||||||
|
ServerName: clientHello.ServerName,
|
||||||
|
}
|
||||||
|
if len(clientHello.SupportedProtos) > 0 {
|
||||||
|
ro.TLS.Proto = clientHello.SupportedProtos[0]
|
||||||
|
}
|
||||||
|
|
||||||
var cc io.ReadWriteCloser
|
var cc io.ReadWriteCloser
|
||||||
|
|
||||||
|
host := clientHello.ServerName
|
||||||
if host != "" {
|
if host != "" {
|
||||||
if _, _, err := net.SplitHostPort(host); err != nil {
|
if _, _, err := net.SplitHostPort(host); err != nil {
|
||||||
_, port, _ := net.SplitHostPort(dstAddr.String())
|
_, port, _ := net.SplitHostPort(dstAddr.String())
|
||||||
@@ -354,9 +364,28 @@ func (h *redirectHandler) handleHTTPS(ctx context.Context, rw io.ReadWriter, rad
|
|||||||
}
|
}
|
||||||
defer cc.Close()
|
defer cc.Close()
|
||||||
|
|
||||||
|
if _, err := buf.WriteTo(cc); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if serverHello, _ := dissector.ParseServerHello(io.TeeReader(cc, buf)); serverHello != nil {
|
||||||
|
ro.TLS.CipherSuite = tls_util.CipherSuite(serverHello.CipherSuite).String()
|
||||||
|
ro.TLS.CompressionMethod = serverHello.CompressionMethod
|
||||||
|
if serverHello.Proto != "" {
|
||||||
|
ro.TLS.Proto = serverHello.Proto
|
||||||
|
}
|
||||||
|
if serverHello.Version > 0 {
|
||||||
|
ro.TLS.Version = tls_util.Version(serverHello.Version).String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := buf.WriteTo(rw); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
t := time.Now()
|
t := time.Now()
|
||||||
log.Infof("%s <-> %s", raddr, host)
|
log.Infof("%s <-> %s", raddr, host)
|
||||||
netpkg.Transport(xio.NewReadWriter(io.MultiReader(buf, rw), rw), cc)
|
netpkg.Transport(rw, cc)
|
||||||
log.WithFields(map[string]any{
|
log.WithFields(map[string]any{
|
||||||
"duration": time.Since(t),
|
"duration": time.Since(t),
|
||||||
}).Infof("%s >-< %s", raddr, host)
|
}).Infof("%s >-< %s", raddr, host)
|
||||||
@@ -364,28 +393,6 @@ func (h *redirectHandler) handleHTTPS(ctx context.Context, rw io.ReadWriter, rad
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *redirectHandler) getServerName(_ context.Context, r io.Reader) (host string, err error) {
|
|
||||||
record, err := dissector.ReadRecord(r)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
clientHello := dissector.ClientHelloMsg{}
|
|
||||||
if err = clientHello.Decode(record.Opaque); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, ext := range clientHello.Extensions {
|
|
||||||
if ext.Type() == dissector.ExtServerName {
|
|
||||||
snExtension := ext.(*dissector.ServerNameExtension)
|
|
||||||
host = snExtension.Name
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *redirectHandler) checkRateLimit(addr net.Addr) bool {
|
func (h *redirectHandler) checkRateLimit(addr net.Addr) bool {
|
||||||
if h.options.RateLimiter == nil {
|
if h.options.RateLimiter == nil {
|
||||||
return true
|
return true
|
||||||
|
|||||||
+33
-2
@@ -27,13 +27,14 @@ import (
|
|||||||
xio "github.com/go-gost/x/internal/io"
|
xio "github.com/go-gost/x/internal/io"
|
||||||
netpkg "github.com/go-gost/x/internal/net"
|
netpkg "github.com/go-gost/x/internal/net"
|
||||||
xhttp "github.com/go-gost/x/internal/net/http"
|
xhttp "github.com/go-gost/x/internal/net/http"
|
||||||
|
tls_util "github.com/go-gost/x/internal/util/tls"
|
||||||
rate_limiter "github.com/go-gost/x/limiter/rate"
|
rate_limiter "github.com/go-gost/x/limiter/rate"
|
||||||
xrecorder "github.com/go-gost/x/recorder"
|
xrecorder "github.com/go-gost/x/recorder"
|
||||||
"github.com/go-gost/x/registry"
|
"github.com/go-gost/x/registry"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultBodySize = 1024 * 1024 * 10 // 10MB
|
defaultBodySize = 1024 * 1024 // 1MB
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@@ -262,6 +263,17 @@ func (h *sniHandler) handleHTTPS(ctx context.Context, rw io.ReadWriter, raddr ne
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clientHello, err := dissector.ParseClientHello(bytes.NewReader(buf.Bytes()))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ro.TLS = &xrecorder.TLSRecorderObject{
|
||||||
|
ServerName: clientHello.ServerName,
|
||||||
|
}
|
||||||
|
if len(clientHello.SupportedProtos) > 0 {
|
||||||
|
ro.TLS.Proto = clientHello.SupportedProtos[0]
|
||||||
|
}
|
||||||
|
|
||||||
if _, _, err := net.SplitHostPort(host); err != nil {
|
if _, _, err := net.SplitHostPort(host); err != nil {
|
||||||
host = net.JoinHostPort(strings.Trim(host, "[]"), "443")
|
host = net.JoinHostPort(strings.Trim(host, "[]"), "443")
|
||||||
}
|
}
|
||||||
@@ -290,9 +302,28 @@ func (h *sniHandler) handleHTTPS(ctx context.Context, rw io.ReadWriter, raddr ne
|
|||||||
}
|
}
|
||||||
defer cc.Close()
|
defer cc.Close()
|
||||||
|
|
||||||
|
if _, err := buf.WriteTo(cc); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if serverHello, _ := dissector.ParseServerHello(io.TeeReader(cc, buf)); serverHello != nil {
|
||||||
|
ro.TLS.CipherSuite = tls_util.CipherSuite(serverHello.CipherSuite).String()
|
||||||
|
ro.TLS.CompressionMethod = serverHello.CompressionMethod
|
||||||
|
if serverHello.Proto != "" {
|
||||||
|
ro.TLS.Proto = serverHello.Proto
|
||||||
|
}
|
||||||
|
if serverHello.Version > 0 {
|
||||||
|
ro.TLS.Version = tls_util.Version(serverHello.Version).String()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := buf.WriteTo(rw); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
t := time.Now()
|
t := time.Now()
|
||||||
log.Infof("%s <-> %s", raddr, host)
|
log.Infof("%s <-> %s", raddr, host)
|
||||||
netpkg.Transport(xio.NewReadWriter(io.MultiReader(buf, rw), rw), cc)
|
netpkg.Transport(rw, cc)
|
||||||
log.WithFields(map[string]any{
|
log.WithFields(map[string]any{
|
||||||
"duration": time.Since(t),
|
"duration": time.Since(t),
|
||||||
}).Infof("%s >-< %s", raddr, host)
|
}).Infof("%s >-< %s", raddr, host)
|
||||||
|
|||||||
Reference in New Issue
Block a user