reality.go 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. package reality
  2. import (
  3. "bytes"
  4. "context"
  5. "crypto/aes"
  6. "crypto/cipher"
  7. "crypto/ecdh"
  8. "crypto/ed25519"
  9. "crypto/hmac"
  10. "crypto/rand"
  11. "crypto/sha256"
  12. "crypto/sha512"
  13. gotls "crypto/tls"
  14. "crypto/x509"
  15. "encoding/binary"
  16. "fmt"
  17. "io"
  18. "math/big"
  19. "net/http"
  20. "reflect"
  21. "regexp"
  22. "strings"
  23. "sync"
  24. "time"
  25. "unsafe"
  26. utls "github.com/refraction-networking/utls"
  27. "github.com/xtls/reality"
  28. "github.com/xtls/xray-core/common/errors"
  29. "github.com/xtls/xray-core/common/net"
  30. "github.com/xtls/xray-core/core"
  31. "github.com/xtls/xray-core/transport/internet/tls"
  32. "golang.org/x/crypto/chacha20poly1305"
  33. "golang.org/x/crypto/hkdf"
  34. "golang.org/x/net/http2"
  35. )
  36. //go:linkname aesgcmPreferred github.com/refraction-networking/utls.aesgcmPreferred
  37. func aesgcmPreferred(ciphers []uint16) bool
  38. type Conn struct {
  39. *reality.Conn
  40. }
  41. func (c *Conn) HandshakeAddress() net.Address {
  42. if err := c.Handshake(); err != nil {
  43. return nil
  44. }
  45. state := c.ConnectionState()
  46. if state.ServerName == "" {
  47. return nil
  48. }
  49. return net.ParseAddress(state.ServerName)
  50. }
  51. func Server(c net.Conn, config *reality.Config) (net.Conn, error) {
  52. realityConn, err := reality.Server(context.Background(), c, config)
  53. return &Conn{Conn: realityConn}, err
  54. }
  55. type UConn struct {
  56. *utls.UConn
  57. ServerName string
  58. AuthKey []byte
  59. Verified bool
  60. }
  61. func (c *UConn) HandshakeAddress() net.Address {
  62. if err := c.Handshake(); err != nil {
  63. return nil
  64. }
  65. state := c.ConnectionState()
  66. if state.ServerName == "" {
  67. return nil
  68. }
  69. return net.ParseAddress(state.ServerName)
  70. }
  71. func (c *UConn) VerifyPeerCertificate(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
  72. p, _ := reflect.TypeOf(c.Conn).Elem().FieldByName("peerCertificates")
  73. certs := *(*([]*x509.Certificate))(unsafe.Pointer(uintptr(unsafe.Pointer(c.Conn)) + p.Offset))
  74. if pub, ok := certs[0].PublicKey.(ed25519.PublicKey); ok {
  75. h := hmac.New(sha512.New, c.AuthKey)
  76. h.Write(pub)
  77. if bytes.Equal(h.Sum(nil), certs[0].Signature) {
  78. c.Verified = true
  79. return nil
  80. }
  81. }
  82. opts := x509.VerifyOptions{
  83. DNSName: c.ServerName,
  84. Intermediates: x509.NewCertPool(),
  85. }
  86. for _, cert := range certs[1:] {
  87. opts.Intermediates.AddCert(cert)
  88. }
  89. if _, err := certs[0].Verify(opts); err != nil {
  90. return err
  91. }
  92. return nil
  93. }
  94. func UClient(c net.Conn, config *Config, ctx context.Context, dest net.Destination) (net.Conn, error) {
  95. localAddr := c.LocalAddr().String()
  96. uConn := &UConn{}
  97. utlsConfig := &utls.Config{
  98. VerifyPeerCertificate: uConn.VerifyPeerCertificate,
  99. ServerName: config.ServerName,
  100. InsecureSkipVerify: true,
  101. SessionTicketsDisabled: true,
  102. KeyLogWriter: KeyLogWriterFromConfig(config),
  103. }
  104. if utlsConfig.ServerName == "" {
  105. utlsConfig.ServerName = dest.Address.String()
  106. }
  107. uConn.ServerName = utlsConfig.ServerName
  108. fingerprint := tls.GetFingerprint(config.Fingerprint)
  109. if fingerprint == nil {
  110. return nil, errors.New("REALITY: failed to get fingerprint").AtError()
  111. }
  112. uConn.UConn = utls.UClient(c, utlsConfig, *fingerprint)
  113. {
  114. uConn.BuildHandshakeState()
  115. hello := uConn.HandshakeState.Hello
  116. hello.SessionId = make([]byte, 32)
  117. copy(hello.Raw[39:], hello.SessionId) // the fixed location of `Session ID`
  118. hello.SessionId[0] = core.Version_x
  119. hello.SessionId[1] = core.Version_y
  120. hello.SessionId[2] = core.Version_z
  121. hello.SessionId[3] = 0 // reserved
  122. binary.BigEndian.PutUint32(hello.SessionId[4:], uint32(time.Now().Unix()))
  123. copy(hello.SessionId[8:], config.ShortId)
  124. if config.Show {
  125. errors.LogInfo(ctx, fmt.Sprintf("REALITY localAddr: %v\thello.SessionId[:16]: %v\n", localAddr, hello.SessionId[:16]))
  126. }
  127. publicKey, err := ecdh.X25519().NewPublicKey(config.PublicKey)
  128. if err != nil {
  129. return nil, errors.New("REALITY: publicKey == nil")
  130. }
  131. if uConn.HandshakeState.State13.EcdheKey == nil {
  132. return nil, errors.New("Current fingerprint ", uConn.ClientHelloID.Client, uConn.ClientHelloID.Version, " does not support TLS 1.3, REALITY handshake cannot establish.")
  133. }
  134. uConn.AuthKey, _ = uConn.HandshakeState.State13.EcdheKey.ECDH(publicKey)
  135. if uConn.AuthKey == nil {
  136. return nil, errors.New("REALITY: SharedKey == nil")
  137. }
  138. if _, err := hkdf.New(sha256.New, uConn.AuthKey, hello.Random[:20], []byte("REALITY")).Read(uConn.AuthKey); err != nil {
  139. return nil, err
  140. }
  141. var aead cipher.AEAD
  142. if aesgcmPreferred(hello.CipherSuites) {
  143. block, _ := aes.NewCipher(uConn.AuthKey)
  144. aead, _ = cipher.NewGCM(block)
  145. } else {
  146. aead, _ = chacha20poly1305.New(uConn.AuthKey)
  147. }
  148. if config.Show {
  149. errors.LogInfo(ctx, fmt.Sprintf("REALITY localAddr: %v\tuConn.AuthKey[:16]: %v\tAEAD: %T\n", localAddr, uConn.AuthKey[:16], aead))
  150. }
  151. aead.Seal(hello.SessionId[:0], hello.Random[20:], hello.SessionId[:16], hello.Raw)
  152. copy(hello.Raw[39:], hello.SessionId)
  153. }
  154. if err := uConn.HandshakeContext(ctx); err != nil {
  155. return nil, err
  156. }
  157. if config.Show {
  158. errors.LogInfo(ctx, fmt.Sprintf("REALITY localAddr: %v\tuConn.Verified: %v\n", localAddr, uConn.Verified))
  159. }
  160. if !uConn.Verified {
  161. go func() {
  162. client := &http.Client{
  163. Transport: &http2.Transport{
  164. DialTLSContext: func(ctx context.Context, network, addr string, cfg *gotls.Config) (net.Conn, error) {
  165. errors.LogInfo(ctx, fmt.Sprintf("REALITY localAddr: %v\tDialTLSContext\n", localAddr))
  166. return uConn, nil
  167. },
  168. },
  169. }
  170. prefix := []byte("https://" + uConn.ServerName)
  171. maps.Lock()
  172. if maps.maps == nil {
  173. maps.maps = make(map[string]map[string]struct{})
  174. }
  175. paths := maps.maps[uConn.ServerName]
  176. if paths == nil {
  177. paths = make(map[string]struct{})
  178. paths[config.SpiderX] = struct{}{}
  179. maps.maps[uConn.ServerName] = paths
  180. }
  181. firstURL := string(prefix) + getPathLocked(paths)
  182. maps.Unlock()
  183. get := func(first bool) {
  184. var (
  185. req *http.Request
  186. resp *http.Response
  187. err error
  188. body []byte
  189. )
  190. if first {
  191. req, _ = http.NewRequest("GET", firstURL, nil)
  192. } else {
  193. maps.Lock()
  194. req, _ = http.NewRequest("GET", string(prefix)+getPathLocked(paths), nil)
  195. maps.Unlock()
  196. }
  197. if req == nil {
  198. return
  199. }
  200. req.Header.Set("User-Agent", fingerprint.Client) // TODO: User-Agent map
  201. if first && config.Show {
  202. errors.LogInfo(ctx, fmt.Sprintf("REALITY localAddr: %v\treq.UserAgent(): %v\n", localAddr, req.UserAgent()))
  203. }
  204. times := 1
  205. if !first {
  206. times = int(randBetween(config.SpiderY[4], config.SpiderY[5]))
  207. }
  208. for j := 0; j < times; j++ {
  209. if !first && j == 0 {
  210. req.Header.Set("Referer", firstURL)
  211. }
  212. req.AddCookie(&http.Cookie{Name: "padding", Value: strings.Repeat("0", int(randBetween(config.SpiderY[0], config.SpiderY[1])))})
  213. if resp, err = client.Do(req); err != nil {
  214. break
  215. }
  216. defer resp.Body.Close()
  217. req.Header.Set("Referer", req.URL.String())
  218. if body, err = io.ReadAll(resp.Body); err != nil {
  219. break
  220. }
  221. maps.Lock()
  222. for _, m := range href.FindAllSubmatch(body, -1) {
  223. m[1] = bytes.TrimPrefix(m[1], prefix)
  224. if !bytes.Contains(m[1], dot) {
  225. paths[string(m[1])] = struct{}{}
  226. }
  227. }
  228. req.URL.Path = getPathLocked(paths)
  229. if config.Show {
  230. errors.LogInfo(ctx, fmt.Sprintf("REALITY localAddr: %v\treq.Referer(): %v\n", localAddr, req.Referer()))
  231. errors.LogInfo(ctx, fmt.Sprintf("REALITY localAddr: %v\tlen(body): %v\n", localAddr, len(body)))
  232. errors.LogInfo(ctx, fmt.Sprintf("REALITY localAddr: %v\tlen(paths): %v\n", localAddr, len(paths)))
  233. }
  234. maps.Unlock()
  235. if !first {
  236. time.Sleep(time.Duration(randBetween(config.SpiderY[6], config.SpiderY[7])) * time.Millisecond) // interval
  237. }
  238. }
  239. }
  240. get(true)
  241. concurrency := int(randBetween(config.SpiderY[2], config.SpiderY[3]))
  242. for i := 0; i < concurrency; i++ {
  243. go get(false)
  244. }
  245. // Do not close the connection
  246. }()
  247. time.Sleep(time.Duration(randBetween(config.SpiderY[8], config.SpiderY[9])) * time.Millisecond) // return
  248. return nil, errors.New("REALITY: processed invalid connection").AtWarning()
  249. }
  250. return uConn, nil
  251. }
  252. var (
  253. href = regexp.MustCompile(`href="([/h].*?)"`)
  254. dot = []byte(".")
  255. )
  256. var maps struct {
  257. sync.Mutex
  258. maps map[string]map[string]struct{}
  259. }
  260. func getPathLocked(paths map[string]struct{}) string {
  261. stopAt := int(randBetween(0, int64(len(paths)-1)))
  262. i := 0
  263. for s := range paths {
  264. if i == stopAt {
  265. return s
  266. }
  267. i++
  268. }
  269. return "/"
  270. }
  271. func randBetween(left int64, right int64) int64 {
  272. if left == right {
  273. return left
  274. }
  275. bigInt, _ := rand.Int(rand.Reader, big.NewInt(right-left))
  276. return left + bigInt.Int64()
  277. }