handle tls for tunnel entrypoint

This commit is contained in:
ginuerzh
2024-12-23 21:05:55 +08:00
parent 2693ba61c4
commit be8e0555e5
2 changed files with 73 additions and 0 deletions
+72
View File
@@ -4,6 +4,7 @@ import (
"bufio" "bufio"
"bytes" "bytes"
"context" "context"
"encoding/hex"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@@ -24,6 +25,7 @@ import (
"github.com/go-gost/core/recorder" "github.com/go-gost/core/recorder"
"github.com/go-gost/core/sd" "github.com/go-gost/core/sd"
"github.com/go-gost/relay" "github.com/go-gost/relay"
dissector "github.com/go-gost/tls-dissector"
admission "github.com/go-gost/x/admission/wrapper" admission "github.com/go-gost/x/admission/wrapper"
ctxvalue "github.com/go-gost/x/ctx" ctxvalue "github.com/go-gost/x/ctx"
ctx_internal "github.com/go-gost/x/internal/ctx" ctx_internal "github.com/go-gost/x/internal/ctx"
@@ -32,6 +34,7 @@ import (
xhttp "github.com/go-gost/x/internal/net/http" xhttp "github.com/go-gost/x/internal/net/http"
"github.com/go-gost/x/internal/net/proxyproto" "github.com/go-gost/x/internal/net/proxyproto"
"github.com/go-gost/x/internal/util/sniffing" "github.com/go-gost/x/internal/util/sniffing"
tls_util "github.com/go-gost/x/internal/util/tls"
ws_util "github.com/go-gost/x/internal/util/ws" ws_util "github.com/go-gost/x/internal/util/ws"
climiter "github.com/go-gost/x/limiter/conn/wrapper" climiter "github.com/go-gost/x/limiter/conn/wrapper"
metrics "github.com/go-gost/x/metrics/wrapper" metrics "github.com/go-gost/x/metrics/wrapper"
@@ -58,6 +61,8 @@ type entrypoint struct {
sniffingWebsocket bool sniffingWebsocket bool
websocketSampleRate float64 websocketSampleRate float64
readTimeout time.Duration
} }
func (ep *entrypoint) Handle(ctx context.Context, conn net.Conn) (err error) { func (ep *entrypoint) Handle(ctx context.Context, conn net.Conn) (err error) {
@@ -112,6 +117,9 @@ func (ep *entrypoint) Handle(ctx context.Context, conn net.Conn) (err error) {
if v[0] == relay.Version1 { if v[0] == relay.Version1 {
return ep.handleConnect(ctx, conn, ro, log) return ep.handleConnect(ctx, conn, ro, log)
} }
if v[0] == dissector.Handshake {
return ep.HandleTLS(ctx, conn, ro, log)
}
return ep.handleHTTP(ctx, conn, ro, log) return ep.handleHTTP(ctx, conn, ro, log)
} }
@@ -547,6 +555,70 @@ func (ep *entrypoint) copyWebsocketFrame(w io.Writer, r io.Reader, buf *bytes.Bu
return nil return nil
} }
func (ep *entrypoint) HandleTLS(ctx context.Context, conn net.Conn, ro *xrecorder.HandlerRecorderObject, log logger.Logger) error {
buf := new(bytes.Buffer)
clientHello, err := dissector.ParseClientHello(io.TeeReader(conn, buf))
if err != nil {
return err
}
ro.TLS = &xrecorder.TLSRecorderObject{
ServerName: clientHello.ServerName,
ClientHello: hex.EncodeToString(buf.Bytes()),
}
if len(clientHello.SupportedProtos) > 0 {
ro.TLS.Proto = clientHello.SupportedProtos[0]
}
host := clientHello.ServerName
if host != "" {
if _, _, err := net.SplitHostPort(host); err != nil {
host = net.JoinHostPort(strings.Trim(host, "[]"), "443")
}
ro.Host = host
}
ctx = ctxvalue.ContextWithClientAddr(ctx, ctxvalue.ClientAddr(ro.RemoteAddr))
ctx = ctx_internal.ContextWithRecorderObject(ctx, ro)
ctx = ctxvalue.ContextWithLogger(ctx, log)
cc, err := ep.dial(ctx, "tcp", host)
if err != nil {
return err
}
defer cc.Close()
if _, err := buf.WriteTo(cc); err != nil {
return err
}
xio.SetReadDeadline(cc, time.Now().Add(ep.readTimeout))
serverHello, err := dissector.ParseServerHello(io.TeeReader(cc, buf))
xio.SetReadDeadline(cc, time.Time{})
if 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 buf.Len() > 0 {
ro.TLS.ServerHello = hex.EncodeToString(buf.Bytes())
}
if _, err := buf.WriteTo(conn); err != nil {
return err
}
xnet.Transport(conn, cc)
return err
}
func (ep *entrypoint) handleConnect(ctx context.Context, conn net.Conn, ro *xrecorder.HandlerRecorderObject, log logger.Logger) (err error) { func (ep *entrypoint) handleConnect(ctx context.Context, conn net.Conn, ro *xrecorder.HandlerRecorderObject, log logger.Logger) (err error) {
req := relay.Request{} req := relay.Request{}
if _, err := req.ReadFrom(conn); err != nil { if _, err := req.ReadFrom(conn); err != nil {
+1
View File
@@ -92,6 +92,7 @@ func (h *tunnelHandler) Init(md md.Metadata) (err error) {
}), }),
sniffingWebsocket: h.md.sniffingWebsocket, sniffingWebsocket: h.md.sniffingWebsocket,
websocketSampleRate: h.md.sniffingWebsocketSampleRate, websocketSampleRate: h.md.sniffingWebsocketSampleRate,
readTimeout: h.md.entryPointReadTimeout,
} }
h.ep.transport = &http.Transport{ h.ep.transport = &http.Transport{
DialContext: h.ep.dial, DialContext: h.ep.dial,