From 44dd834fef54311c8d9c7c57c519e8435beebc08 Mon Sep 17 00:00:00 2001 From: wwqgtxx Date: Tue, 14 Jul 2026 17:58:05 +0800 Subject: [PATCH] chore: preserve jls in-user for shadowsocks listeners --- listener/jls/jls.go | 4 ++++ listener/sing_shadowsocks/server.go | 29 ++++++++--------------------- transport/jls/jls.go | 12 ++++++++++++ transport/jls/jls_test.go | 4 ++++ 4 files changed, 28 insertions(+), 21 deletions(-) diff --git a/listener/jls/jls.go b/listener/jls/jls.go index 89d1c61f..99c8e362 100644 --- a/listener/jls/jls.go +++ b/listener/jls/jls.go @@ -41,3 +41,7 @@ func (b Builder) NewListener(listener net.Listener) net.Listener { return jls.Server(ctx, conn, b.config) }, nil) } + +func UserFromConn(conn net.Conn) (string, bool) { + return jls.UserFromConn(conn) +} diff --git a/listener/sing_shadowsocks/server.go b/listener/sing_shadowsocks/server.go index 4ed5ab58..670aeaae 100644 --- a/listener/sing_shadowsocks/server.go +++ b/listener/sing_shadowsocks/server.go @@ -11,12 +11,12 @@ import ( C "github.com/metacubex/mihomo/constant" LC "github.com/metacubex/mihomo/listener/config" "github.com/metacubex/mihomo/listener/inner" + "github.com/metacubex/mihomo/listener/jls" embedSS "github.com/metacubex/mihomo/listener/shadowsocks" "github.com/metacubex/mihomo/listener/shadowtls" "github.com/metacubex/mihomo/listener/sing" "github.com/metacubex/mihomo/log" "github.com/metacubex/mihomo/ntp" - "github.com/metacubex/mihomo/transport/jls" "github.com/metacubex/mihomo/transport/kcptun" "github.com/metacubex/mihomo/transport/restls" obfs "github.com/metacubex/mihomo/transport/simple-obfs" @@ -39,7 +39,6 @@ type Listener struct { udpListeners []net.PacketConn service shadowsocks.Service resTLS *restls.ServerConfig - jls *jls.ServerConfig simpleObfs func(net.Conn) net.Conn } @@ -108,19 +107,9 @@ func New(config LC.ShadowsocksServer, lc C.InboundListenConfig, tunnel C.Tunnel, } } + var jlsBuilder *jls.Builder if config.JLSConfig.Enable { - sl.jls, err = jls.NewServerConfig( - config.JLSConfig.SNI, - config.JLSConfig.Dest, - common.Map(config.JLSConfig.Users, func(user LC.JLSUser) jls.User { - return jls.User{Username: user.Username, Password: user.Password} - }), - config.JLSConfig.ALPN, - config.JLSConfig.RateLimit, - func(ctx context.Context, network, address string) (net.Conn, error) { - return inner.HandleTcp(tunnel, address, config.JLSConfig.Proxy) - }, - ) + jlsBuilder, err = jls.New(config.JLSConfig, tunnel) if err != nil { return nil, err } @@ -215,6 +204,9 @@ func New(config LC.ShadowsocksServer, lc C.InboundListenConfig, tunnel C.Tunnel, if shadowTLSBuilder != nil { l = shadowTLSBuilder.NewListener(l) } + if jlsBuilder != nil { + l = jlsBuilder.NewListener(l) + } sl.listeners = append(sl.listeners, l) go func() { @@ -269,13 +261,8 @@ func (l *Listener) AddrList() (addrList []net.Addr) { func (l *Listener) HandleConn(conn net.Conn, tunnel C.Tunnel, additions ...inbound.Addition) { user, loaded := shadowtls.UserFromConn(conn) - if l.jls != nil { - c, err := jls.Server(context.TODO(), conn, l.jls) - if err != nil { - _ = conn.Close() - return - } - conn = c + if jlsUser, jlsLoaded := jls.UserFromConn(conn); jlsLoaded { + user, loaded = jlsUser, true } if l.resTLS != nil { c, err := restls.Server(context.TODO(), conn, l.resTLS) diff --git a/transport/jls/jls.go b/transport/jls/jls.go index 1b910410..1b283a98 100644 --- a/transport/jls/jls.go +++ b/transport/jls/jls.go @@ -194,6 +194,18 @@ func Server(ctx context.Context, conn net.Conn, config *ServerConfig) (net.Conn, return tlsConn, nil } +func UserFromConn(conn net.Conn) (string, bool) { + tlsConn, ok := conn.(*tls.Conn) + if !ok { + return "", false + } + state := tlsConn.ConnectionState().JLS + if !state.Authenticated || state.User == "" { + return "", false + } + return state.User, true +} + func relayFallback(ctx context.Context, inbound net.Conn, prefix []byte, config *ServerConfig) error { upstream, err := config.DialContext(ctx, "tcp", config.Dest) if err != nil { diff --git a/transport/jls/jls_test.go b/transport/jls/jls_test.go index 53c61509..3e12e06c 100644 --- a/transport/jls/jls_test.go +++ b/transport/jls/jls_test.go @@ -56,6 +56,10 @@ func testJLSClientServer(t *testing.T, clientFingerprint string) { serverDone <- errors.New("server did not authenticate JLS user") return } + if authenticatedUser, ok := UserFromConn(conn); !ok || authenticatedUser != user.Username { + serverDone <- errors.New("server did not expose JLS user") + return + } _, err = io.Copy(conn, conn) serverDone <- err }()