reality_client.go 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. //go:build with_utls
  2. package tls
  3. import (
  4. "bytes"
  5. "context"
  6. "crypto/aes"
  7. "crypto/cipher"
  8. "crypto/ecdh"
  9. "crypto/ed25519"
  10. "crypto/hmac"
  11. "crypto/sha256"
  12. "crypto/sha512"
  13. "crypto/tls"
  14. "crypto/x509"
  15. "encoding/base64"
  16. "encoding/binary"
  17. "encoding/hex"
  18. "fmt"
  19. "io"
  20. mRand "math/rand"
  21. "net"
  22. "net/http"
  23. "reflect"
  24. "strings"
  25. "time"
  26. "unsafe"
  27. "github.com/sagernet/sing-box/adapter"
  28. C "github.com/sagernet/sing-box/constant"
  29. "github.com/sagernet/sing-box/option"
  30. "github.com/sagernet/sing/common"
  31. "github.com/sagernet/sing/common/debug"
  32. E "github.com/sagernet/sing/common/exceptions"
  33. "github.com/sagernet/sing/common/logger"
  34. "github.com/sagernet/sing/common/ntp"
  35. aTLS "github.com/sagernet/sing/common/tls"
  36. utls "github.com/metacubex/utls"
  37. "golang.org/x/crypto/hkdf"
  38. "golang.org/x/net/http2"
  39. )
  40. var _ ConfigCompat = (*RealityClientConfig)(nil)
  41. type RealityClientConfig struct {
  42. ctx context.Context
  43. uClient *UTLSClientConfig
  44. publicKey []byte
  45. shortID [8]byte
  46. }
  47. func NewRealityClient(ctx context.Context, logger logger.ContextLogger, serverAddress string, options option.OutboundTLSOptions) (Config, error) {
  48. if options.UTLS == nil || !options.UTLS.Enabled {
  49. return nil, E.New("uTLS is required by reality client")
  50. }
  51. uClient, err := NewUTLSClient(ctx, logger, serverAddress, options)
  52. if err != nil {
  53. return nil, err
  54. }
  55. publicKey, err := base64.RawURLEncoding.DecodeString(options.Reality.PublicKey)
  56. if err != nil {
  57. return nil, E.Cause(err, "decode public_key")
  58. }
  59. if len(publicKey) != 32 {
  60. return nil, E.New("invalid public_key")
  61. }
  62. var shortID [8]byte
  63. decodedLen, err := hex.Decode(shortID[:], []byte(options.Reality.ShortID))
  64. if err != nil {
  65. return nil, E.Cause(err, "decode short_id")
  66. }
  67. if decodedLen > 8 {
  68. return nil, E.New("invalid short_id")
  69. }
  70. var config Config = &RealityClientConfig{ctx, uClient.(*UTLSClientConfig), publicKey, shortID}
  71. if options.KernelRx || options.KernelTx {
  72. if !C.IsLinux {
  73. return nil, E.New("kTLS is only supported on Linux")
  74. }
  75. config = &KTLSClientConfig{
  76. Config: config,
  77. logger: logger,
  78. kernelTx: options.KernelTx,
  79. kernelRx: options.KernelRx,
  80. }
  81. }
  82. return config, nil
  83. }
  84. func (e *RealityClientConfig) ServerName() string {
  85. return e.uClient.ServerName()
  86. }
  87. func (e *RealityClientConfig) SetServerName(serverName string) {
  88. e.uClient.SetServerName(serverName)
  89. }
  90. func (e *RealityClientConfig) NextProtos() []string {
  91. return e.uClient.NextProtos()
  92. }
  93. func (e *RealityClientConfig) SetNextProtos(nextProto []string) {
  94. e.uClient.SetNextProtos(nextProto)
  95. }
  96. func (e *RealityClientConfig) STDConfig() (*STDConfig, error) {
  97. return nil, E.New("unsupported usage for reality")
  98. }
  99. func (e *RealityClientConfig) Client(conn net.Conn) (Conn, error) {
  100. return ClientHandshake(context.Background(), conn, e)
  101. }
  102. func (e *RealityClientConfig) ClientHandshake(ctx context.Context, conn net.Conn) (aTLS.Conn, error) {
  103. verifier := &realityVerifier{
  104. serverName: e.uClient.ServerName(),
  105. }
  106. uConfig := e.uClient.config.Clone()
  107. uConfig.InsecureSkipVerify = true
  108. uConfig.SessionTicketsDisabled = true
  109. uConfig.VerifyPeerCertificate = verifier.VerifyPeerCertificate
  110. uConn := utls.UClient(conn, uConfig, e.uClient.id)
  111. verifier.UConn = uConn
  112. err := uConn.BuildHandshakeState()
  113. if err != nil {
  114. return nil, err
  115. }
  116. for _, extension := range uConn.Extensions {
  117. if ce, ok := extension.(*utls.SupportedCurvesExtension); ok {
  118. ce.Curves = common.Filter(ce.Curves, func(curveID utls.CurveID) bool {
  119. return curveID != utls.X25519MLKEM768
  120. })
  121. }
  122. if ks, ok := extension.(*utls.KeyShareExtension); ok {
  123. ks.KeyShares = common.Filter(ks.KeyShares, func(share utls.KeyShare) bool {
  124. return share.Group != utls.X25519MLKEM768
  125. })
  126. }
  127. }
  128. err = uConn.BuildHandshakeState()
  129. if err != nil {
  130. return nil, err
  131. }
  132. if len(uConfig.NextProtos) > 0 {
  133. for _, extension := range uConn.Extensions {
  134. if alpnExtension, isALPN := extension.(*utls.ALPNExtension); isALPN {
  135. alpnExtension.AlpnProtocols = uConfig.NextProtos
  136. break
  137. }
  138. }
  139. }
  140. hello := uConn.HandshakeState.Hello
  141. hello.SessionId = make([]byte, 32)
  142. copy(hello.Raw[39:], hello.SessionId)
  143. var nowTime time.Time
  144. if uConfig.Time != nil {
  145. nowTime = uConfig.Time()
  146. } else {
  147. nowTime = time.Now()
  148. }
  149. binary.BigEndian.PutUint64(hello.SessionId, uint64(nowTime.Unix()))
  150. hello.SessionId[0] = 1
  151. hello.SessionId[1] = 8
  152. hello.SessionId[2] = 1
  153. binary.BigEndian.PutUint32(hello.SessionId[4:], uint32(time.Now().Unix()))
  154. copy(hello.SessionId[8:], e.shortID[:])
  155. if debug.Enabled {
  156. fmt.Printf("REALITY hello.sessionId[:16]: %v\n", hello.SessionId[:16])
  157. }
  158. publicKey, err := ecdh.X25519().NewPublicKey(e.publicKey)
  159. if err != nil {
  160. return nil, err
  161. }
  162. keyShareKeys := uConn.HandshakeState.State13.KeyShareKeys
  163. if keyShareKeys == nil {
  164. return nil, E.New("nil KeyShareKeys")
  165. }
  166. ecdheKey := keyShareKeys.Ecdhe
  167. if ecdheKey == nil {
  168. return nil, E.New("nil ecdheKey")
  169. }
  170. authKey, err := ecdheKey.ECDH(publicKey)
  171. if err != nil {
  172. return nil, err
  173. }
  174. if authKey == nil {
  175. return nil, E.New("nil auth_key")
  176. }
  177. verifier.authKey = authKey
  178. _, err = hkdf.New(sha256.New, authKey, hello.Random[:20], []byte("REALITY")).Read(authKey)
  179. if err != nil {
  180. return nil, err
  181. }
  182. aesBlock, _ := aes.NewCipher(authKey)
  183. aesGcmCipher, _ := cipher.NewGCM(aesBlock)
  184. aesGcmCipher.Seal(hello.SessionId[:0], hello.Random[20:], hello.SessionId[:16], hello.Raw)
  185. copy(hello.Raw[39:], hello.SessionId)
  186. if debug.Enabled {
  187. fmt.Printf("REALITY hello.sessionId: %v\n", hello.SessionId)
  188. fmt.Printf("REALITY uConn.AuthKey: %v\n", authKey)
  189. }
  190. err = uConn.HandshakeContext(ctx)
  191. if err != nil {
  192. return nil, err
  193. }
  194. if debug.Enabled {
  195. fmt.Printf("REALITY Conn.Verified: %v\n", verifier.verified)
  196. }
  197. if !verifier.verified {
  198. go realityClientFallback(e.ctx, uConn, e.uClient.ServerName(), e.uClient.id)
  199. return nil, E.New("reality verification failed")
  200. }
  201. return &realityClientConnWrapper{uConn}, nil
  202. }
  203. func realityClientFallback(ctx context.Context, uConn net.Conn, serverName string, fingerprint utls.ClientHelloID) {
  204. defer uConn.Close()
  205. client := &http.Client{
  206. Transport: &http2.Transport{
  207. DialTLSContext: func(ctx context.Context, network, addr string, config *tls.Config) (net.Conn, error) {
  208. return uConn, nil
  209. },
  210. TLSClientConfig: &tls.Config{
  211. Time: ntp.TimeFuncFromContext(ctx),
  212. RootCAs: adapter.RootPoolFromContext(ctx),
  213. },
  214. },
  215. }
  216. request, _ := http.NewRequest("GET", "https://"+serverName, nil)
  217. request.Header.Set("User-Agent", fingerprint.Client)
  218. request.AddCookie(&http.Cookie{Name: "padding", Value: strings.Repeat("0", mRand.Intn(32)+30)})
  219. response, err := client.Do(request)
  220. if err != nil {
  221. return
  222. }
  223. _, _ = io.Copy(io.Discard, response.Body)
  224. response.Body.Close()
  225. }
  226. func (e *RealityClientConfig) Clone() Config {
  227. return &RealityClientConfig{
  228. e.ctx,
  229. e.uClient.Clone().(*UTLSClientConfig),
  230. e.publicKey,
  231. e.shortID,
  232. }
  233. }
  234. type realityVerifier struct {
  235. *utls.UConn
  236. serverName string
  237. authKey []byte
  238. verified bool
  239. }
  240. func (c *realityVerifier) VerifyPeerCertificate(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
  241. p, _ := reflect.TypeOf(c.Conn).Elem().FieldByName("peerCertificates")
  242. certs := *(*([]*x509.Certificate))(unsafe.Pointer(uintptr(unsafe.Pointer(c.Conn)) + p.Offset))
  243. if pub, ok := certs[0].PublicKey.(ed25519.PublicKey); ok {
  244. h := hmac.New(sha512.New, c.authKey)
  245. h.Write(pub)
  246. if bytes.Equal(h.Sum(nil), certs[0].Signature) {
  247. c.verified = true
  248. return nil
  249. }
  250. }
  251. opts := x509.VerifyOptions{
  252. DNSName: c.serverName,
  253. Intermediates: x509.NewCertPool(),
  254. }
  255. for _, cert := range certs[1:] {
  256. opts.Intermediates.AddCert(cert)
  257. }
  258. if _, err := certs[0].Verify(opts); err != nil {
  259. return err
  260. }
  261. return nil
  262. }
  263. type realityClientConnWrapper struct {
  264. *utls.UConn
  265. }
  266. func (c *realityClientConnWrapper) ConnectionState() tls.ConnectionState {
  267. state := c.Conn.ConnectionState()
  268. //nolint:staticcheck
  269. return tls.ConnectionState{
  270. Version: state.Version,
  271. HandshakeComplete: state.HandshakeComplete,
  272. DidResume: state.DidResume,
  273. CipherSuite: state.CipherSuite,
  274. NegotiatedProtocol: state.NegotiatedProtocol,
  275. NegotiatedProtocolIsMutual: state.NegotiatedProtocolIsMutual,
  276. ServerName: state.ServerName,
  277. PeerCertificates: state.PeerCertificates,
  278. VerifiedChains: state.VerifiedChains,
  279. SignedCertificateTimestamps: state.SignedCertificateTimestamps,
  280. OCSPResponse: state.OCSPResponse,
  281. TLSUnique: state.TLSUnique,
  282. }
  283. }
  284. func (c *realityClientConnWrapper) Upstream() any {
  285. return c.UConn
  286. }
  287. // Due to low implementation quality, the reality server intercepted half close and caused memory leaks.
  288. // We fixed it by calling Close() directly.
  289. func (c *realityClientConnWrapper) CloseWrite() error {
  290. return c.Close()
  291. }
  292. func (c *realityClientConnWrapper) ReaderReplaceable() bool {
  293. return true
  294. }
  295. func (c *realityClientConnWrapper) WriterReplaceable() bool {
  296. return true
  297. }