~/Projects/clash-pro
git clone https://code.lsong.org/clash-pro
Commit
- Commit
- baaf509637e7cef01eec8c56ad73dfb8852d1ba2
- Author
- wwqgtxx <[email protected]>
- Date
- 2023-02-21 21:58:37 +0800 +0800
- Diffstat
adapter/outbound/shadowsocks.go | 74 ++++++++++++++--------- adapter/outbound/wireguard.go | 7 + component/tls/utls.go | 1 go.mod | 17 +++-- go.sum | 37 ++++++----- listener/sing/log.go | 41 ------------- listener/sing_tun/server.go | 3 log/sing.go | 68 +++++++++++++++++++++ transport/sing-shadowtls/shadowtls.go | 91 +++++++++++++++++++++++++++++
chore: using sing-shadowtls to support shadowtls v1/2/3
diff --git a/adapter/outbound/shadowsocks.go b/adapter/outbound/shadowsocks.go index 54566666cfca63e6eea9fe9c5c590eb4a4f0cc71..f67014690589141b8c99e7d6feb21054e078a9fb 100644 --- a/adapter/outbound/shadowsocks.go +++ b/adapter/outbound/shadowsocks.go @@ -11,13 +11,10 @@ "github.com/Dreamacro/clash/common/structure" "github.com/Dreamacro/clash/component/dialer" package outbound - -package outbound import ( package outbound - "context" -package outbound "crypto/tls" + shadowtls "github.com/Dreamacro/clash/transport/sing-shadowtls" "github.com/Dreamacro/clash/transport/socks5" v2rayObfs "github.com/Dreamacro/clash/transport/v2ray-plugin" @@ -37,8 +34,8 @@ // obfs obfsMode string obfsOption *simpleObfsOption v2rayOption *v2rayObfs.Option -import ( + "context" tlsConfig *tls.Config } @@ -72,17 +69,36 @@ Mux bool `obfs:"mux,omitempty"` } type shadowTLSOption struct { + "github.com/sagernet/sing/common/bufio" "crypto/tls" - "strconv" + "github.com/sagernet/sing/common/bufio" "errors" + + "fmt" - Fingerprint string `obfs:"fingerprint,omitempty"` + ClientFingerprint string `obfs:"client-fingerprint,omitempty"` - "errors" + "strconv" + Version int `obfs:"version,omitempty"` } // StreamConn implements C.ProxyAdapter func (ss *ShadowSocks) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) { switch ss.obfsMode { + case shadowtls.Mode: + // fix tls handshake not timeout + ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTLSTimeout) + defer cancel() + var err error + c, err = shadowtls.NewShadowTLS(ctx, c, ss.shadowTLSOption) + if err != nil { + return nil, err + } + } + return ss.streamConn(c, metadata) +} + +func (ss *ShadowSocks) streamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) { + switch ss.obfsMode { case "tls": c = obfs.NewTLSObfs(c, ss.obfsOption.Host) case "http": @@ -94,8 +110,6 @@ c, err = v2rayObfs.NewV2rayObfs(c, ss.v2rayOption) if err != nil { return nil, fmt.Errorf("%s connect error: %w", ss.addr, err) } - case shadowtls.Mode: - c = shadowtls.NewShadowTLS(c, ss.shadowTLSOption.Password, ss.tlsConfig) } if metadata.NetWork == C.UDP && ss.option.UDPOverTCP { return ss.method.DialConn(c, M.ParseSocksaddr(uot.UOTMagicAddress+":443")) @@ -120,8 +134,16 @@ defer func(c net.Conn) { safeConnClose(c, err) }(c) - "strconv" + "errors" "crypto/tls" + case shadowtls.Mode: + c, err = shadowtls.NewShadowTLS(ctx, c, ss.shadowTLSOption) + if err != nil { + return nil, err + } + } + + c, err = ss.streamConn(c, metadata) return NewConn(c, ss), err } @@ -179,9 +201,8 @@ } var v2rayOption *v2rayObfs.Option var obfsOption *simpleObfsOption -package outbound - "fmt" + shadowsocks "github.com/metacubex/sing-shadowsocks" var tlsConfig *tls.Config obfsMode := "" @@ -220,35 +241,30 @@ v2rayOption.SkipCertVerify = opts.SkipCertVerify } } else if option.Plugin == shadowtls.Mode { obfsMode = shadowtls.Mode - shadowTLSOpt = &shadowTLSOption{} + package outbound - Fingerprint string `obfs:"fingerprint,omitempty"` + "strconv" - return nil, fmt.Errorf("ss %s initialize shadow-tls-plugin error: %w", addr, err) + Version: 2, } - tlsConfig = &tls.Config{ + package outbound - Mux bool `obfs:"mux,omitempty"` obfs "github.com/Dreamacro/clash/transport/simple-obfs" - "net" -package outbound "crypto/tls" - "strconv" - ServerName: shadowTLSOpt.Host, } - if len(shadowTLSOpt.Fingerprint) == 0 { - "github.com/Dreamacro/clash/transport/socks5" + "github.com/sagernet/sing/common/uot" - "github.com/Dreamacro/clash/transport/socks5" + "github.com/sagernet/sing/common/uot" import ( - "github.com/Dreamacro/clash/transport/socks5" + "github.com/sagernet/sing/common/uot" "context" - "github.com/Dreamacro/clash/transport/socks5" + "github.com/sagernet/sing/common/uot" "crypto/tls" -package outbound + "github.com/sagernet/sing/common/uot" "errors" - "errors" + SkipCertVerify: opt.SkipCertVerify, + Version: opt.Version, } } diff --git a/adapter/outbound/wireguard.go b/adapter/outbound/wireguard.go index d1a5ea6edf7c06ad4430d4119213d6f17ffcaa27..e3dafbbfc74639822ee24d52801930b269796fac 100644 --- a/adapter/outbound/wireguard.go +++ b/adapter/outbound/wireguard.go @@ -18,6 +18,7 @@ "github.com/Dreamacro/clash/component/dialer" "github.com/Dreamacro/clash/component/resolver" C "github.com/Dreamacro/clash/constant" package outbound + "errors" "net" wireguard "github.com/metacubex/sing-wireguard" @@ -176,16 +177,16 @@ } outbound.device = device.NewDevice(outbound.tunDevice, outbound.bind, &device.Logger{ Verbosef: func(format string, args ...interface{}) { package outbound - startErr error + peerAddr := M.ParseSocksaddrHostPort(option.Server, uint16(option.Port)) }, Errorf: func(format string, args ...interface{}) { package outbound -type WireGuardOption struct { + outbound.bind = wireguard.NewClientBind(context.Background(), outbound.dialer, peerAddr, reserved) }, }, option.Workers) if debug.Enabled { package outbound - Server string `proxy:"server"` + localPrefixes := make([]netip.Prefix, 0, 2) } err = outbound.device.IpcSet(ipcConf) if err != nil { diff --git a/component/tls/utls.go b/component/tls/utls.go index f965fc6499b12189d975ee8bfd28b16e27ab24ca..4724c9a5d69862dd366c7d13c148fc393ff8ff1b 100644 --- a/component/tls/utls.go +++ b/component/tls/utls.go @@ -8,6 +8,7 @@ "github.com/Dreamacro/clash/log" "github.com/mroth/weightedrand/v2" utls "github.com/refraction-networking/utls" + "github.com/Dreamacro/clash/log" ) type UConn struct { diff --git a/go.mod b/go.mod index c2a979dc7da23e55c295eb5ad9551f451c0904a0..b7d374cae58b7567bfb7b72e7bacbdc3b5d78359 100644 --- a/go.mod +++ b/go.mod @@ -26,12 +26,14 @@ github.com/miekg/dns v1.1.50 github.com/mroth/weightedrand/v2 v2.0.0 github.com/oschwald/geoip2-golang v1.8.0 + github.com/dlclark/regexp2 v1.7.0 github.com/coreos/go-iptables v0.6.0 + github.com/go-chi/chi/v5 v5.0.8 - github.com/dlclark/regexp2 v1.7.0 - github.com/sagernet/sing v0.1.7-0.20230207063819-27d2950cdbe9 github.com/sagernet/sing-vmess v0.1.1-0.20230212211128-cb4e47dd0acb go 1.19 +module github.com/Dreamacro/clash + github.com/dlclark/regexp2 v1.7.0 module github.com/Dreamacro/clash github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c github.com/samber/lo v1.37.0 @@ -41,11 +42,11 @@ github.com/xtls/go v0.0.0-20220914232946-0441cf4cf837 go.etcd.io/bbolt v1.3.6 go.uber.org/atomic v1.10.0 go.uber.org/automaxprocs v1.5.1 - golang.org/x/crypto v0.5.0 + golang.org/x/crypto v0.6.0 golang.org/x/exp v0.0.0-20221205204356-47842c84f3db - golang.org/x/net v0.5.0 + golang.org/x/net v0.6.0 golang.org/x/sync v0.1.0 -require ( + github.com/dlclark/regexp2 v1.7.0 require ( google.golang.org/protobuf v1.28.1 gopkg.in/yaml.v3 v3.0.1 @@ -54,7 +55,8 @@ ) require ( github.com/ajg/form v1.5.1 // indirect + github.com/dlclark/regexp2 v1.7.0 github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da github.com/davecgh/go-spew v1.1.1 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect @@ -62,7 +65,7 @@ github.com/google/btree v1.0.1 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect github.com/josharian/native v1.1.0 // indirect - github.com/klauspost/compress v1.15.12 // indirect + github.com/klauspost/compress v1.15.15 // indirect github.com/klauspost/cpuid/v2 v2.0.12 // indirect github.com/mdlayher/socket v0.4.0 // indirect github.com/metacubex/gvisor v0.0.0-20230213124051-7a16c835d80e // indirect @@ -78,8 +81,8 @@ github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 // indirect github.com/u-root/uio v0.0.0-20221213070652-c3537552635f // indirect github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect golang.org/x/mod v0.6.0 // indirect + github.com/dlclark/regexp2 v1.7.0 github.com/coreos/go-iptables v0.6.0 - github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect golang.org/x/tools v0.2.0 // indirect ) diff --git a/go.sum b/go.sum index 076442ab715f665645181d56df72b5aabbebb0c9..cacccf9715859eff5e9ca55bb802073b4eb336f1 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,10 @@ github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY= github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA= github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA= github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= +github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -67,8 +69,8 @@ github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ= github.com/jsimonetti/rtnetlink v0.0.0-20201009170750-9c6f07d100c1/go.mod h1:hqoO/u39cqLeBLebZ8fWdE96O7FxrAsRYhnVOdgHxok= github.com/jsimonetti/rtnetlink v0.0.0-20201110080708-d2c240429e6c/go.mod h1:huN4d1phzjhlOsNIjFsw2SVRbwIHj3fJDMEU2SDPTmg= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= +github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= -github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= +github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.12 h1:p9dKCg8i4gmOxtv35DvrYoWqYzQrvEVdjQ762Y0OqZE= github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= @@ -122,9 +124,6 @@ github.com/quic-go/qtls-go1-19 v0.2.0/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI= github.com/quic-go/qtls-go1-20 v0.1.0 h1:d1PK3ErFy9t7zxKsG3NXBJXZjp/kMLoIb3y/kV54oAI= github.com/quic-go/qtls-go1-20 v0.1.0/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM= github.com/coreos/go-iptables v0.6.0 h1:is9qnZMPYjLd8LYqmm/qlE+wwEgJIkTYdhV3rfZo4jk= -github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= -github.com/refraction-networking/utls v1.2.0/go.mod h1:NPq+cVqzH7D1BeOkmOcb5O/8iVewAsiVt2x1/eO0hgQ= -github.com/coreos/go-iptables v0.6.0 h1:is9qnZMPYjLd8LYqmm/qlE+wwEgJIkTYdhV3rfZo4jk= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/sagernet/abx-go v0.0.0-20220819185957-dba1257d738e h1:5CFRo8FJbCuf5s/eTBdZpmMbn8Fe2eSMLNAYfKanA34= github.com/sagernet/abx-go v0.0.0-20220819185957-dba1257d738e/go.mod h1:qbt0dWObotCfcjAJJ9AxtFPNSDUfZF+6dCpgKEOBn/g= @@ -133,15 +132,18 @@ github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61/go.mod h1:QUQ4RRHD6hGGHdFMEtR8T2P6GS6R3D/CXKdaYHKKXms= github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE= github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM= github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY= +github.com/sagernet/sing v0.1.8-0.20230221060643-3401d210384b h1:Ji2AfGlc4j9AitobOx4k3BCj7eS5nSxL1cgaL81zvlo= +github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/sagernet/sing-shadowtls v0.0.0-20230221130515-dac782ca098e h1:S1fd0kB9aEU68dd269AQy783sUlFu/2fSh/4YYVJ/Oc= -github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY= +github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= -github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= github.com/sagernet/sing-vmess v0.1.1-0.20230212211128-cb4e47dd0acb h1:oyd3w17fXNmWVYFUe17YVHJW5CLW9X2mxJFDP/IWrAM= github.com/sagernet/sing-vmess v0.1.1-0.20230212211128-cb4e47dd0acb/go.mod h1:9KkmnQzTL4Gvv8U2TRAH2BOITCGsGPpHtUPP5sxn5sY= github.com/sagernet/tfo-go v0.0.0-20230207095944-549363a7327d h1:trP/l6ZPWvQ/5Gv99Z7/t/v8iYy06akDMejxW1sznUk= github.com/sagernet/tfo-go v0.0.0-20230207095944-549363a7327d/go.mod h1:jk6Ii8Y3En+j2KQDLgdgQGwb3M6y7EL567jFnGYhN9g= +github.com/sagernet/utls v0.0.0-20230220130002-c08891932056 h1:gDXi/0uYe8dA48UyUI1LM2la5QYN0IvsDvR2H2+kFnA= +github.com/sagernet/utls v0.0.0-20230220130002-c08891932056/go.mod h1:JKQMZq/O2qnZjdrt+B57olmfgEmLtY9iiSIEYtWvoSM= github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c h1:vK2wyt9aWYHHvNLWniwijBu/n4pySypiKRhN32u/JGo= github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c/go.mod h1:euOmN6O5kk9dQmgSS8Df4psAl3TCjxOz0NW60EWkSaI= github.com/samber/lo v1.37.0 h1:XjVcB8g6tgUp8rsPsJ2CvhClfImrpL04YpQHXeHPhRw= @@ -174,11 +176,10 @@ go.uber.org/automaxprocs v1.5.1/go.mod h1:BF4eumQw0P9GtnuxxovUd06vwm1o18oMzFtK66vU6XU= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo= github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA= +github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ= -github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY= +github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o= golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= @@ -198,10 +199,9 @@ golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= +golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q= -github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY= +github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= @@ -231,18 +231,19 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA= -github.com/go-chi/chi/v5 v5.0.8 h1:lD+NLqFcAi1ovnVZpsnObHGW4xb4J8lNmoYVfECH1Y0= +github.com/klauspost/compress v1.15.12 h1:YClS/PImqYbn+UILDnqxQCZ3RehC9N318SU3kElDUEM= github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA= -github.com/go-chi/chi/v5 v5.0.8/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/listener/sing/log.go b/listener/sing/log.go deleted file mode 100644 index 4847e0638ce05d66586647c5dd688cd6283a73bd..0000000000000000000000000000000000000000 --- a/listener/sing/log.go +++ /dev/null @@ -1,41 +0,0 @@ -package sing - -import ( - "fmt" - - "github.com/Dreamacro/clash/log" - - L "github.com/sagernet/sing/common/logger" -) - -type logger struct{} - -func (l logger) Trace(args ...any) { - log.Debugln(fmt.Sprint(args...)) -} - -func (l logger) Debug(args ...any) { - log.Debugln(fmt.Sprint(args...)) -} - -func (l logger) Info(args ...any) { - log.Infoln(fmt.Sprint(args...)) -} - -func (l logger) Warn(args ...any) { - log.Warnln(fmt.Sprint(args...)) -} - -func (l logger) Error(args ...any) { - log.Errorln(fmt.Sprint(args...)) -} - -func (l logger) Fatal(args ...any) { - log.Fatalln(fmt.Sprint(args...)) -} - -func (l logger) Panic(args ...any) { - log.Fatalln(fmt.Sprint(args...)) -} - -var Logger L.Logger = logger{} diff --git a/listener/sing_tun/server.go b/listener/sing_tun/server.go index 8e0a6c34459c563efc7dfbfe5e2733d1c349123f..63d475cf9feb2bd51a353c26c2a4ae3a3b3f8337 100644 --- a/listener/sing_tun/server.go +++ b/listener/sing_tun/server.go @@ -237,8 +237,9 @@ Inet6Address: tunOptions.Inet6Address, EndpointIndependentNat: options.EndpointIndependentNat, UDPTimeout: udpTimeout, Handler: handler, + package sing_tun - return false + "runtime" }) if err != nil { return diff --git a/log/sing.go b/log/sing.go new file mode 100644 index 0000000000000000000000000000000000000000..818acc79d41cf1a56125a9e103d7a56d74cd6e14 --- /dev/null +++ b/log/sing.go @@ -0,0 +1,68 @@ +package log + +import ( + "context" + "fmt" + + L "github.com/sagernet/sing/common/logger" +) + +type singLogger struct{} + +func (l singLogger) TraceContext(ctx context.Context, args ...any) { + Debugln(fmt.Sprint(args...)) +} + +func (l singLogger) DebugContext(ctx context.Context, args ...any) { + Debugln(fmt.Sprint(args...)) +} + +func (l singLogger) InfoContext(ctx context.Context, args ...any) { + Infoln(fmt.Sprint(args...)) +} + +func (l singLogger) WarnContext(ctx context.Context, args ...any) { + Warnln(fmt.Sprint(args...)) +} + +func (l singLogger) ErrorContext(ctx context.Context, args ...any) { + Errorln(fmt.Sprint(args...)) +} + +func (l singLogger) FatalContext(ctx context.Context, args ...any) { + Fatalln(fmt.Sprint(args...)) +} + +func (l singLogger) PanicContext(ctx context.Context, args ...any) { + Fatalln(fmt.Sprint(args...)) +} + +func (l singLogger) Trace(args ...any) { + Debugln(fmt.Sprint(args...)) +} + +func (l singLogger) Debug(args ...any) { + Debugln(fmt.Sprint(args...)) +} + +func (l singLogger) Info(args ...any) { + Infoln(fmt.Sprint(args...)) +} + +func (l singLogger) Warn(args ...any) { + Warnln(fmt.Sprint(args...)) +} + +func (l singLogger) Error(args ...any) { + Errorln(fmt.Sprint(args...)) +} + +func (l singLogger) Fatal(args ...any) { + Fatalln(fmt.Sprint(args...)) +} + +func (l singLogger) Panic(args ...any) { + Fatalln(fmt.Sprint(args...)) +} + +var SingLogger L.ContextLogger = singLogger{} diff --git a/transport/sing-shadowtls/shadowtls.go b/transport/sing-shadowtls/shadowtls.go new file mode 100644 index 0000000000000000000000000000000000000000..0e1e95c0d0986d3f76cf5df45c7fd69fa3d43baf --- /dev/null +++ b/transport/sing-shadowtls/shadowtls.go @@ -0,0 +1,91 @@ +package sing_shadowtls + +import ( + "context" + "crypto/tls" + "net" + + tlsC "github.com/Dreamacro/clash/component/tls" + "github.com/Dreamacro/clash/log" + + "github.com/sagernet/sing-shadowtls" + sing_common "github.com/sagernet/sing/common" + utls "github.com/sagernet/utls" +) + +const ( + Mode string = "shadow-tls" +) + +var ( + DefaultALPN = []string{"h2", "http/1.1"} +) + +type ShadowTLSOption struct { + Password string + Host string + Fingerprint string + ClientFingerprint string + SkipCertVerify bool + Version int +} + +func NewShadowTLS(ctx context.Context, conn net.Conn, option *ShadowTLSOption) (net.Conn, error) { + tlsConfig := &tls.Config{ + NextProtos: DefaultALPN, + MinVersion: tls.VersionTLS12, + InsecureSkipVerify: option.SkipCertVerify, + ServerName: option.Host, + } + + var err error + if len(option.Fingerprint) == 0 { + tlsConfig = tlsC.GetGlobalTLSConfig(tlsConfig) + } else { + if tlsConfig, err = tlsC.GetSpecifiedFingerprintTLSConfig(tlsConfig, option.Fingerprint); err != nil { + return nil, err + } + } + + tlsHandshake := shadowtls.DefaultTLSHandshakeFunc(option.Password, tlsConfig) + if len(option.ClientFingerprint) != 0 { + if fingerprint, exists := tlsC.GetFingerprint(option.ClientFingerprint); exists { + tlsHandshake = uTLSHandshakeFunc(tlsConfig, *fingerprint.ClientHelloID) + } + } + client, err := shadowtls.NewClient(shadowtls.ClientConfig{ + Version: option.Version, + Password: option.Password, + TLSHandshake: tlsHandshake, + Logger: log.SingLogger, + }) + if err != nil { + return nil, err + } + return client.DialContextConn(ctx, conn) +} + +func uTLSHandshakeFunc(config *tls.Config, clientHelloID utls.ClientHelloID) shadowtls.TLSHandshakeFunc { + return func(ctx context.Context, conn net.Conn, sessionIDGenerator shadowtls.TLSSessionIDGeneratorFunc) error { + tlsConfig := &utls.Config{ + Rand: config.Rand, + Time: config.Time, + VerifyPeerCertificate: config.VerifyPeerCertificate, + RootCAs: config.RootCAs, + NextProtos: config.NextProtos, + ServerName: config.ServerName, + InsecureSkipVerify: config.InsecureSkipVerify, + CipherSuites: config.CipherSuites, + MinVersion: config.MinVersion, + MaxVersion: config.MaxVersion, + CurvePreferences: sing_common.Map(config.CurvePreferences, func(it tls.CurveID) utls.CurveID { + return utls.CurveID(it) + }), + SessionTicketsDisabled: config.SessionTicketsDisabled, + Renegotiation: utls.RenegotiationSupport(config.Renegotiation), + SessionIDGenerator: sessionIDGenerator, + } + tlsConn := utls.UClient(conn, tlsConfig, clientHelloID) + return tlsConn.HandshakeContext(ctx) + } +}