vless.go 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. package conf
  2. import (
  3. "encoding/base64"
  4. "encoding/json"
  5. "path/filepath"
  6. "runtime"
  7. "strconv"
  8. "strings"
  9. "syscall"
  10. "github.com/xtls/xray-core/common/errors"
  11. "github.com/xtls/xray-core/common/net"
  12. "github.com/xtls/xray-core/common/protocol"
  13. "github.com/xtls/xray-core/common/serial"
  14. "github.com/xtls/xray-core/common/uuid"
  15. "github.com/xtls/xray-core/proxy/vless"
  16. "github.com/xtls/xray-core/proxy/vless/inbound"
  17. "github.com/xtls/xray-core/proxy/vless/outbound"
  18. "google.golang.org/protobuf/proto"
  19. )
  20. type VLessInboundFallback struct {
  21. Name string `json:"name"`
  22. Alpn string `json:"alpn"`
  23. Path string `json:"path"`
  24. Type string `json:"type"`
  25. Dest json.RawMessage `json:"dest"`
  26. Xver uint64 `json:"xver"`
  27. }
  28. type VLessInboundConfig struct {
  29. Clients []json.RawMessage `json:"clients"`
  30. Decryption string `json:"decryption"`
  31. Fallbacks []*VLessInboundFallback `json:"fallbacks"`
  32. Flow string `json:"flow"`
  33. Testseed []uint32 `json:"testseed"`
  34. }
  35. // Build implements Buildable
  36. func (c *VLessInboundConfig) Build() (proto.Message, error) {
  37. config := new(inbound.Config)
  38. config.Clients = make([]*protocol.User, len(c.Clients))
  39. switch c.Flow {
  40. case "", vless.XRV:
  41. default:
  42. return nil, errors.New(`VLESS "settings.flow" doesn't support "` + c.Flow + `" in this version`)
  43. }
  44. for idx, rawUser := range c.Clients {
  45. user := new(protocol.User)
  46. if err := json.Unmarshal(rawUser, user); err != nil {
  47. return nil, errors.New(`VLESS clients: invalid user`).Base(err)
  48. }
  49. account := new(vless.Account)
  50. if err := json.Unmarshal(rawUser, account); err != nil {
  51. return nil, errors.New(`VLESS clients: invalid user`).Base(err)
  52. }
  53. u, err := uuid.ParseString(account.Id)
  54. if err != nil {
  55. return nil, err
  56. }
  57. account.Id = u.String()
  58. switch account.Flow {
  59. case "":
  60. account.Flow = c.Flow
  61. case vless.XRV:
  62. default:
  63. return nil, errors.New(`VLESS clients: "flow" doesn't support "` + account.Flow + `" in this version`)
  64. }
  65. if account.Flow == "" {
  66. errors.PrintNonRemovalDeprecatedFeatureWarning("VLESS (with no Flow, etc.)", "VLESS with Flow & Seed")
  67. }
  68. if len(account.Testseed) < 4 {
  69. account.Testseed = c.Testseed
  70. }
  71. if account.Encryption != "" {
  72. return nil, errors.New(`VLESS clients: "encryption" should not be in inbound settings`)
  73. }
  74. if account.Reverse != nil && account.Reverse.Tag == "" {
  75. return nil, errors.New(`VLESS clients: "tag" can't be empty for "reverse"`)
  76. }
  77. user.Account = serial.ToTypedMessage(account)
  78. config.Clients[idx] = user
  79. }
  80. config.Decryption = c.Decryption
  81. if !func() bool {
  82. s := strings.Split(config.Decryption, ".")
  83. if len(s) < 4 || s[0] != "mlkem768x25519plus" {
  84. return false
  85. }
  86. switch s[1] {
  87. case "native":
  88. case "xorpub":
  89. config.XorMode = 1
  90. case "random":
  91. config.XorMode = 2
  92. default:
  93. return false
  94. }
  95. t := strings.SplitN(strings.TrimSuffix(s[2], "s"), "-", 2)
  96. i, err := strconv.Atoi(t[0])
  97. if err != nil {
  98. return false
  99. }
  100. config.SecondsFrom = int64(i)
  101. if len(t) == 2 {
  102. i, err := strconv.Atoi(t[1])
  103. if err != nil {
  104. return false
  105. }
  106. config.SecondsTo = int64(i)
  107. }
  108. padding := 0
  109. for _, r := range s[3:] {
  110. if len(r) < 20 {
  111. padding += len(r) + 1
  112. continue
  113. }
  114. if b, _ := base64.RawURLEncoding.DecodeString(r); len(b) != 32 && len(b) != 64 {
  115. return false
  116. }
  117. }
  118. config.Decryption = config.Decryption[27+len(s[2]):]
  119. if padding > 0 {
  120. config.Padding = config.Decryption[:padding-1]
  121. config.Decryption = config.Decryption[padding:]
  122. }
  123. return true
  124. }() && config.Decryption != "none" {
  125. if config.Decryption == "" {
  126. return nil, errors.New(`VLESS settings: please add/set "decryption":"none" to every settings`)
  127. }
  128. return nil, errors.New(`VLESS settings: unsupported "decryption": ` + config.Decryption)
  129. }
  130. if config.Decryption != "none" && c.Fallbacks != nil {
  131. return nil, errors.New(`VLESS settings: "fallbacks" can not be used together with "decryption"`)
  132. }
  133. for _, fb := range c.Fallbacks {
  134. var i uint16
  135. var s string
  136. if err := json.Unmarshal(fb.Dest, &i); err == nil {
  137. s = strconv.Itoa(int(i))
  138. } else {
  139. _ = json.Unmarshal(fb.Dest, &s)
  140. }
  141. config.Fallbacks = append(config.Fallbacks, &inbound.Fallback{
  142. Name: fb.Name,
  143. Alpn: fb.Alpn,
  144. Path: fb.Path,
  145. Type: fb.Type,
  146. Dest: s,
  147. Xver: fb.Xver,
  148. })
  149. }
  150. for _, fb := range config.Fallbacks {
  151. /*
  152. if fb.Alpn == "h2" && fb.Path != "" {
  153. return nil, errors.New(`VLESS fallbacks: "alpn":"h2" doesn't support "path"`)
  154. }
  155. */
  156. if fb.Path != "" && fb.Path[0] != '/' {
  157. return nil, errors.New(`VLESS fallbacks: "path" must be empty or start with "/"`)
  158. }
  159. if fb.Type == "" && fb.Dest != "" {
  160. if fb.Dest == "serve-ws-none" {
  161. fb.Type = "serve"
  162. } else if filepath.IsAbs(fb.Dest) || fb.Dest[0] == '@' {
  163. fb.Type = "unix"
  164. if strings.HasPrefix(fb.Dest, "@@") && (runtime.GOOS == "linux" || runtime.GOOS == "android") {
  165. fullAddr := make([]byte, len(syscall.RawSockaddrUnix{}.Path)) // may need padding to work with haproxy
  166. copy(fullAddr, fb.Dest[1:])
  167. fb.Dest = string(fullAddr)
  168. }
  169. } else {
  170. if _, err := strconv.Atoi(fb.Dest); err == nil {
  171. fb.Dest = "localhost:" + fb.Dest
  172. }
  173. if _, _, err := net.SplitHostPort(fb.Dest); err == nil {
  174. fb.Type = "tcp"
  175. }
  176. }
  177. }
  178. if fb.Type == "" {
  179. return nil, errors.New(`VLESS fallbacks: please fill in a valid value for every "dest"`)
  180. }
  181. if fb.Xver > 2 {
  182. return nil, errors.New(`VLESS fallbacks: invalid PROXY protocol version, "xver" only accepts 0, 1, 2`)
  183. }
  184. }
  185. return config, nil
  186. }
  187. type VLessOutboundVnext struct {
  188. Address *Address `json:"address"`
  189. Port uint16 `json:"port"`
  190. Users []json.RawMessage `json:"users"`
  191. }
  192. type VLessOutboundConfig struct {
  193. Address *Address `json:"address"`
  194. Port uint16 `json:"port"`
  195. Level uint32 `json:"level"`
  196. Email string `json:"email"`
  197. Id string `json:"id"`
  198. Flow string `json:"flow"`
  199. Seed string `json:"seed"`
  200. Encryption string `json:"encryption"`
  201. Reverse *vless.Reverse `json:"reverse"`
  202. Testpre uint32 `json:"testpre"`
  203. Testseed []uint32 `json:"testseed"`
  204. Vnext []*VLessOutboundVnext `json:"vnext"`
  205. }
  206. // Build implements Buildable
  207. func (c *VLessOutboundConfig) Build() (proto.Message, error) {
  208. config := new(outbound.Config)
  209. if c.Address != nil {
  210. c.Vnext = []*VLessOutboundVnext{
  211. {
  212. Address: c.Address,
  213. Port: c.Port,
  214. Users: []json.RawMessage{{}},
  215. },
  216. }
  217. }
  218. if len(c.Vnext) != 1 {
  219. return nil, errors.New(`VLESS settings: "vnext" should have one and only one member. Multiple endpoints in "vnext" should use multiple VLESS outbounds and routing balancer instead`)
  220. }
  221. for _, rec := range c.Vnext {
  222. if rec.Address == nil {
  223. return nil, errors.New(`VLESS vnext: "address" is not set`)
  224. }
  225. if len(rec.Users) != 1 {
  226. return nil, errors.New(`VLESS vnext: "users" should have one and only one member. Multiple members in "users" should use multiple VLESS outbounds and routing balancer instead`)
  227. }
  228. spec := &protocol.ServerEndpoint{
  229. Address: rec.Address.Build(),
  230. Port: uint32(rec.Port),
  231. }
  232. for _, rawUser := range rec.Users {
  233. user := new(protocol.User)
  234. if c.Address != nil {
  235. user.Level = c.Level
  236. user.Email = c.Email
  237. } else {
  238. if err := json.Unmarshal(rawUser, user); err != nil {
  239. return nil, errors.New(`VLESS users: invalid user`).Base(err)
  240. }
  241. }
  242. account := new(vless.Account)
  243. if c.Address != nil {
  244. account.Id = c.Id
  245. account.Flow = c.Flow
  246. //account.Seed = c.Seed
  247. account.Encryption = c.Encryption
  248. account.Reverse = c.Reverse
  249. account.Testpre = c.Testpre
  250. account.Testseed = c.Testseed
  251. } else {
  252. if err := json.Unmarshal(rawUser, account); err != nil {
  253. return nil, errors.New(`VLESS users: invalid user`).Base(err)
  254. }
  255. }
  256. u, err := uuid.ParseString(account.Id)
  257. if err != nil {
  258. return nil, err
  259. }
  260. account.Id = u.String()
  261. switch account.Flow {
  262. case "":
  263. errors.PrintNonRemovalDeprecatedFeatureWarning("VLESS (with no Flow, etc.)", "VLESS with Flow & Seed")
  264. case vless.XRV, vless.XRV + "-udp443":
  265. default:
  266. return nil, errors.New(`VLESS users: "flow" doesn't support "` + account.Flow + `" in this version`)
  267. }
  268. if !func() bool {
  269. s := strings.Split(account.Encryption, ".")
  270. if len(s) < 4 || s[0] != "mlkem768x25519plus" {
  271. return false
  272. }
  273. switch s[1] {
  274. case "native":
  275. case "xorpub":
  276. account.XorMode = 1
  277. case "random":
  278. account.XorMode = 2
  279. default:
  280. return false
  281. }
  282. switch s[2] {
  283. case "1rtt":
  284. case "0rtt":
  285. account.Seconds = 1
  286. default:
  287. return false
  288. }
  289. padding := 0
  290. for _, r := range s[3:] {
  291. if len(r) < 20 {
  292. padding += len(r) + 1
  293. continue
  294. }
  295. if b, _ := base64.RawURLEncoding.DecodeString(r); len(b) != 32 && len(b) != 1184 {
  296. return false
  297. }
  298. }
  299. account.Encryption = account.Encryption[27+len(s[2]):]
  300. if padding > 0 {
  301. account.Padding = account.Encryption[:padding-1]
  302. account.Encryption = account.Encryption[padding:]
  303. }
  304. return true
  305. }() && account.Encryption != "none" {
  306. if account.Encryption == "" {
  307. return nil, errors.New(`VLESS users: please add/set "encryption":"none" for every user`)
  308. }
  309. return nil, errors.New(`VLESS users: unsupported "encryption": ` + account.Encryption)
  310. }
  311. if account.Reverse != nil && account.Reverse.Tag == "" {
  312. return nil, errors.New(`VLESS clients: "tag" can't be empty for "reverse"`)
  313. }
  314. user.Account = serial.ToTypedMessage(account)
  315. spec.User = user
  316. break
  317. }
  318. config.Vnext = spec
  319. break
  320. }
  321. return config, nil
  322. }