chore: using sing-shadowtls to support shadowtls v1/2/3
This commit is contained in:
parent
04e6177a01
commit
a694155b20
9 changed files with 236 additions and 97 deletions
|
@ -10,10 +10,9 @@ import (
|
|||
|
||||
"github.com/Dreamacro/clash/common/structure"
|
||||
"github.com/Dreamacro/clash/component/dialer"
|
||||
tlsC "github.com/Dreamacro/clash/component/tls"
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
"github.com/Dreamacro/clash/transport/shadowtls"
|
||||
obfs "github.com/Dreamacro/clash/transport/simple-obfs"
|
||||
shadowtls "github.com/Dreamacro/clash/transport/sing-shadowtls"
|
||||
"github.com/Dreamacro/clash/transport/socks5"
|
||||
v2rayObfs "github.com/Dreamacro/clash/transport/v2ray-plugin"
|
||||
|
||||
|
@ -33,7 +32,7 @@ type ShadowSocks struct {
|
|||
obfsMode string
|
||||
obfsOption *simpleObfsOption
|
||||
v2rayOption *v2rayObfs.Option
|
||||
shadowTLSOption *shadowTLSOption
|
||||
shadowTLSOption *shadowtls.ShadowTLSOption
|
||||
tlsConfig *tls.Config
|
||||
}
|
||||
|
||||
|
@ -67,14 +66,31 @@ type v2rayObfsOption struct {
|
|||
}
|
||||
|
||||
type shadowTLSOption struct {
|
||||
Password string `obfs:"password"`
|
||||
Host string `obfs:"host"`
|
||||
Fingerprint string `obfs:"fingerprint,omitempty"`
|
||||
SkipCertVerify bool `obfs:"skip-cert-verify,omitempty"`
|
||||
Password string `obfs:"password"`
|
||||
Host string `obfs:"host"`
|
||||
Fingerprint string `obfs:"fingerprint,omitempty"`
|
||||
ClientFingerprint string `obfs:"client-fingerprint,omitempty"`
|
||||
SkipCertVerify bool `obfs:"skip-cert-verify,omitempty"`
|
||||
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)
|
||||
|
@ -87,8 +103,6 @@ func (ss *ShadowSocks) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, e
|
|||
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"))
|
||||
|
@ -113,7 +127,15 @@ func (ss *ShadowSocks) DialContextWithDialer(ctx context.Context, dialer C.Diale
|
|||
safeConnClose(c, err)
|
||||
}(c)
|
||||
|
||||
c, err = ss.StreamConn(c, metadata)
|
||||
switch ss.obfsMode {
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -171,7 +193,7 @@ func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) {
|
|||
|
||||
var v2rayOption *v2rayObfs.Option
|
||||
var obfsOption *simpleObfsOption
|
||||
var shadowTLSOpt *shadowTLSOption
|
||||
var shadowTLSOpt *shadowtls.ShadowTLSOption
|
||||
var tlsConfig *tls.Config
|
||||
obfsMode := ""
|
||||
|
||||
|
@ -210,24 +232,20 @@ func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) {
|
|||
}
|
||||
} else if option.Plugin == shadowtls.Mode {
|
||||
obfsMode = shadowtls.Mode
|
||||
shadowTLSOpt = &shadowTLSOption{}
|
||||
if err := decoder.Decode(option.PluginOpts, shadowTLSOpt); err != nil {
|
||||
opt := &shadowTLSOption{
|
||||
Version: 2,
|
||||
}
|
||||
if err := decoder.Decode(option.PluginOpts, opt); err != nil {
|
||||
return nil, fmt.Errorf("ss %s initialize shadow-tls-plugin error: %w", addr, err)
|
||||
}
|
||||
|
||||
tlsConfig = &tls.Config{
|
||||
NextProtos: shadowtls.DefaultALPN,
|
||||
MinVersion: tls.VersionTLS12,
|
||||
InsecureSkipVerify: shadowTLSOpt.SkipCertVerify,
|
||||
ServerName: shadowTLSOpt.Host,
|
||||
}
|
||||
|
||||
if len(shadowTLSOpt.Fingerprint) == 0 {
|
||||
tlsConfig = tlsC.GetGlobalTLSConfig(tlsConfig)
|
||||
} else {
|
||||
if tlsConfig, err = tlsC.GetSpecifiedFingerprintTLSConfig(tlsConfig, shadowTLSOpt.Fingerprint); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
shadowTLSOpt = &shadowtls.ShadowTLSOption{
|
||||
Password: opt.Password,
|
||||
Host: opt.Host,
|
||||
Fingerprint: opt.Fingerprint,
|
||||
ClientFingerprint: opt.ClientFingerprint,
|
||||
SkipCertVerify: opt.SkipCertVerify,
|
||||
Version: opt.Version,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ import (
|
|||
"github.com/Dreamacro/clash/component/dialer"
|
||||
"github.com/Dreamacro/clash/component/resolver"
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
"github.com/Dreamacro/clash/listener/sing"
|
||||
"github.com/Dreamacro/clash/log"
|
||||
|
||||
wireguard "github.com/metacubex/sing-wireguard"
|
||||
|
||||
|
@ -174,14 +174,14 @@ func NewWireGuard(option WireGuardOption) (*WireGuard, error) {
|
|||
}
|
||||
outbound.device = device.NewDevice(outbound.tunDevice, outbound.bind, &device.Logger{
|
||||
Verbosef: func(format string, args ...interface{}) {
|
||||
sing.Logger.Debug(fmt.Sprintf(strings.ToLower(format), args...))
|
||||
log.SingLogger.Debug(fmt.Sprintf(strings.ToLower(format), args...))
|
||||
},
|
||||
Errorf: func(format string, args ...interface{}) {
|
||||
sing.Logger.Error(fmt.Sprintf(strings.ToLower(format), args...))
|
||||
log.SingLogger.Error(fmt.Sprintf(strings.ToLower(format), args...))
|
||||
},
|
||||
}, option.Workers)
|
||||
if debug.Enabled {
|
||||
sing.Logger.Trace("created wireguard ipc conf: \n", ipcConf)
|
||||
log.SingLogger.Trace("created wireguard ipc conf: \n", ipcConf)
|
||||
}
|
||||
err = outbound.device.IpcSet(ipcConf)
|
||||
if err != nil {
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"github.com/Dreamacro/clash/log"
|
||||
|
||||
"github.com/mroth/weightedrand/v2"
|
||||
utls "github.com/refraction-networking/utls"
|
||||
utls "github.com/sagernet/utls"
|
||||
)
|
||||
|
||||
type UConn struct {
|
||||
|
|
17
go.mod
17
go.mod
|
@ -25,11 +25,12 @@ require (
|
|||
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/refraction-networking/utls v1.2.0
|
||||
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97
|
||||
github.com/sagernet/sing v0.1.7-0.20230207063819-27d2950cdbe9
|
||||
github.com/sagernet/sing v0.1.8-0.20230221060643-3401d210384b
|
||||
github.com/sagernet/sing-shadowtls v0.0.0-20230221130515-dac782ca098e
|
||||
github.com/sagernet/sing-vmess v0.1.1-0.20230212211128-cb4e47dd0acb
|
||||
github.com/sagernet/tfo-go v0.0.0-20230207095944-549363a7327d
|
||||
github.com/sagernet/utls v0.0.0-20230220130002-c08891932056
|
||||
github.com/sagernet/wireguard-go v0.0.0-20221116151939-c99467f53f2c
|
||||
github.com/samber/lo v1.37.0
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
|
@ -38,11 +39,11 @@ require (
|
|||
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
|
||||
golang.org/x/sys v0.4.0
|
||||
golang.org/x/sys v0.5.0
|
||||
google.golang.org/protobuf v1.28.1
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
lukechampine.com/blake3 v1.1.7
|
||||
|
@ -50,7 +51,7 @@ require (
|
|||
|
||||
require (
|
||||
github.com/ajg/form v1.5.1 // indirect
|
||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||
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
|
||||
|
@ -59,7 +60,7 @@ require (
|
|||
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
|
||||
|
@ -75,7 +76,7 @@ require (
|
|||
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
|
||||
golang.org/x/text v0.6.0 // indirect
|
||||
golang.org/x/text v0.7.0 // indirect
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 // indirect
|
||||
golang.org/x/tools v0.2.0 // indirect
|
||||
)
|
||||
|
|
34
go.sum
34
go.sum
|
@ -2,8 +2,8 @@ github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmH
|
|||
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/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.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
||||
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 +67,8 @@ github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod h1:WGu
|
|||
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.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
|
||||
github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw=
|
||||
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=
|
||||
|
@ -121,8 +121,6 @@ github.com/quic-go/qtls-go1-19 v0.2.0 h1:Cvn2WdhyViFUHoOqK52i51k4nDX8EwIh5VJiVM4
|
|||
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/refraction-networking/utls v1.2.0 h1:U5f8wkij2NVinfLuJdFP3gCMwIHs+EzvhxmYdXgiapo=
|
||||
github.com/refraction-networking/utls v1.2.0/go.mod h1:NPq+cVqzH7D1BeOkmOcb5O/8iVewAsiVt2x1/eO0hgQ=
|
||||
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||
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=
|
||||
|
@ -131,12 +129,16 @@ github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61/go.mod h
|
|||
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.7-0.20230207063819-27d2950cdbe9 h1:qnXh4RjHsNjdZXkfbqwVqAzYUfc160gfkS5gepmsA+A=
|
||||
github.com/sagernet/sing v0.1.7-0.20230207063819-27d2950cdbe9/go.mod h1:JLSXsPTGRJFo/3X7EcAOCUgJH2/gAoxSJgBsnCZRp/w=
|
||||
github.com/sagernet/sing v0.1.8-0.20230221060643-3401d210384b h1:Ji2AfGlc4j9AitobOx4k3BCj7eS5nSxL1cgaL81zvlo=
|
||||
github.com/sagernet/sing v0.1.8-0.20230221060643-3401d210384b/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk=
|
||||
github.com/sagernet/sing-shadowtls v0.0.0-20230221130515-dac782ca098e h1:S1fd0kB9aEU68dd269AQy783sUlFu/2fSh/4YYVJ/Oc=
|
||||
github.com/sagernet/sing-shadowtls v0.0.0-20230221130515-dac782ca098e/go.mod h1:Kn1VUIprdkwCgkS6SXYaLmIpKzQbqBIKJBMY+RvBhYc=
|
||||
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=
|
||||
|
@ -169,8 +171,8 @@ go.uber.org/automaxprocs v1.5.1/go.mod h1:BF4eumQw0P9GtnuxxovUd06vwm1o18oMzFtK66
|
|||
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=
|
||||
golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=
|
||||
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
|
||||
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
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=
|
||||
|
@ -190,8 +192,8 @@ golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwY
|
|||
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.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
||||
golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
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=
|
||||
|
@ -220,14 +222,14 @@ golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
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=
|
||||
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
|
||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
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=
|
||||
golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k=
|
||||
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
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=
|
||||
|
|
|
@ -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{}
|
|
@ -237,7 +237,7 @@ func New(options LC.Tun, tcpIn chan<- C.ConnContext, udpIn chan<- C.PacketAdapte
|
|||
EndpointIndependentNat: options.EndpointIndependentNat,
|
||||
UDPTimeout: udpTimeout,
|
||||
Handler: handler,
|
||||
Logger: sing.Logger,
|
||||
Logger: log.SingLogger,
|
||||
})
|
||||
if err != nil {
|
||||
return
|
||||
|
|
68
log/sing.go
Normal file
68
log/sing.go
Normal file
|
@ -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{}
|
91
transport/sing-shadowtls/shadowtls.go
Normal file
91
transport/sing-shadowtls/shadowtls.go
Normal file
|
@ -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)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue