xray.js 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400
  1. const Protocols = {
  2. VMESS: 'vmess',
  3. VLESS: 'vless',
  4. TROJAN: 'trojan',
  5. SHADOWSOCKS: 'shadowsocks',
  6. DOKODEMO: 'dokodemo-door',
  7. MTPROTO: 'mtproto',
  8. SOCKS: 'socks',
  9. HTTP: 'http',
  10. };
  11. const VmessMethods = {
  12. AES_128_GCM: 'aes-128-gcm',
  13. CHACHA20_POLY1305: 'chacha20-poly1305',
  14. AUTO: 'auto',
  15. NONE: 'none',
  16. };
  17. const SSMethods = {
  18. // AES_256_CFB: 'aes-256-cfb',
  19. // AES_128_CFB: 'aes-128-cfb',
  20. // CHACHA20: 'chacha20',
  21. // CHACHA20_IETF: 'chacha20-ietf',
  22. CHACHA20_POLY1305: 'chacha20-poly1305',
  23. AES_256_GCM: 'aes-256-gcm',
  24. AES_128_GCM: 'aes-128-gcm',
  25. };
  26. const RULE_IP = {
  27. PRIVATE: 'geoip:private',
  28. CN: 'geoip:cn',
  29. };
  30. const RULE_DOMAIN = {
  31. ADS: 'geosite:category-ads',
  32. ADS_ALL: 'geosite:category-ads-all',
  33. CN: 'geosite:cn',
  34. GOOGLE: 'geosite:google',
  35. FACEBOOK: 'geosite:facebook',
  36. SPEEDTEST: 'geosite:speedtest',
  37. };
  38. const VLESS_FLOW = {
  39. ORIGIN: "xtls-rprx-origin",
  40. DIRECT: "xtls-rprx-direct",
  41. };
  42. Object.freeze(Protocols);
  43. Object.freeze(VmessMethods);
  44. Object.freeze(SSMethods);
  45. Object.freeze(RULE_IP);
  46. Object.freeze(RULE_DOMAIN);
  47. Object.freeze(VLESS_FLOW);
  48. class XrayCommonClass {
  49. static toJsonArray(arr) {
  50. return arr.map(obj => obj.toJson());
  51. }
  52. static fromJson() {
  53. return new XrayCommonClass();
  54. }
  55. toJson() {
  56. return this;
  57. }
  58. toString(format=true) {
  59. return format ? JSON.stringify(this.toJson(), null, 2) : JSON.stringify(this.toJson());
  60. }
  61. static toHeaders(v2Headers) {
  62. let newHeaders = [];
  63. if (v2Headers) {
  64. Object.keys(v2Headers).forEach(key => {
  65. let values = v2Headers[key];
  66. if (typeof(values) === 'string') {
  67. newHeaders.push({ name: key, value: values });
  68. } else {
  69. for (let i = 0; i < values.length; ++i) {
  70. newHeaders.push({ name: key, value: values[i] });
  71. }
  72. }
  73. });
  74. }
  75. return newHeaders;
  76. }
  77. static toV2Headers(headers, arr=true) {
  78. let v2Headers = {};
  79. for (let i = 0; i < headers.length; ++i) {
  80. let name = headers[i].name;
  81. let value = headers[i].value;
  82. if (ObjectUtil.isEmpty(name) || ObjectUtil.isEmpty(value)) {
  83. continue;
  84. }
  85. if (!(name in v2Headers)) {
  86. v2Headers[name] = arr ? [value] : value;
  87. } else {
  88. if (arr) {
  89. v2Headers[name].push(value);
  90. } else {
  91. v2Headers[name] = value;
  92. }
  93. }
  94. }
  95. return v2Headers;
  96. }
  97. }
  98. class TcpStreamSettings extends XrayCommonClass {
  99. constructor(type='none',
  100. request=new TcpStreamSettings.TcpRequest(),
  101. response=new TcpStreamSettings.TcpResponse(),
  102. ) {
  103. super();
  104. this.type = type;
  105. this.request = request;
  106. this.response = response;
  107. }
  108. static fromJson(json={}) {
  109. let header = json.header;
  110. if (!header) {
  111. header = {};
  112. }
  113. return new TcpStreamSettings(
  114. header.type,
  115. TcpStreamSettings.TcpRequest.fromJson(header.request),
  116. TcpStreamSettings.TcpResponse.fromJson(header.response),
  117. );
  118. }
  119. toJson() {
  120. return {
  121. header: {
  122. type: this.type,
  123. request: this.type === 'http' ? this.request.toJson() : undefined,
  124. response: this.type === 'http' ? this.response.toJson() : undefined,
  125. },
  126. };
  127. }
  128. }
  129. TcpStreamSettings.TcpRequest = class extends XrayCommonClass {
  130. constructor(version='1.1',
  131. method='GET',
  132. path=['/'],
  133. headers=[],
  134. ) {
  135. super();
  136. this.version = version;
  137. this.method = method;
  138. this.path = path.length === 0 ? ['/'] : path;
  139. this.headers = headers;
  140. }
  141. addPath(path) {
  142. this.path.push(path);
  143. }
  144. removePath(index) {
  145. this.path.splice(index, 1);
  146. }
  147. addHeader(name, value) {
  148. this.headers.push({ name: name, value: value });
  149. }
  150. removeHeader(index) {
  151. this.headers.splice(index, 1);
  152. }
  153. static fromJson(json={}) {
  154. return new TcpStreamSettings.TcpRequest(
  155. json.version,
  156. json.method,
  157. json.path,
  158. XrayCommonClass.toHeaders(json.headers),
  159. );
  160. }
  161. toJson() {
  162. return {
  163. method: this.method,
  164. path: ObjectUtil.clone(this.path),
  165. headers: XrayCommonClass.toV2Headers(this.headers),
  166. };
  167. }
  168. };
  169. TcpStreamSettings.TcpResponse = class extends XrayCommonClass {
  170. constructor(version='1.1',
  171. status='200',
  172. reason='OK',
  173. headers=[],
  174. ) {
  175. super();
  176. this.version = version;
  177. this.status = status;
  178. this.reason = reason;
  179. this.headers = headers;
  180. }
  181. addHeader(name, value) {
  182. this.headers.push({ name: name, value: value });
  183. }
  184. removeHeader(index) {
  185. this.headers.splice(index, 1);
  186. }
  187. static fromJson(json={}) {
  188. return new TcpStreamSettings.TcpResponse(
  189. json.version,
  190. json.status,
  191. json.reason,
  192. XrayCommonClass.toHeaders(json.headers),
  193. );
  194. }
  195. toJson() {
  196. return {
  197. version: this.version,
  198. status: this.status,
  199. reason: this.reason,
  200. headers: XrayCommonClass.toV2Headers(this.headers),
  201. };
  202. }
  203. };
  204. class KcpStreamSettings extends XrayCommonClass {
  205. constructor(mtu=1350, tti=20,
  206. uplinkCapacity=5,
  207. downlinkCapacity=20,
  208. congestion=false,
  209. readBufferSize=2,
  210. writeBufferSize=2,
  211. type='none',
  212. seed=RandomUtil.randomSeq(10),
  213. ) {
  214. super();
  215. this.mtu = mtu;
  216. this.tti = tti;
  217. this.upCap = uplinkCapacity;
  218. this.downCap = downlinkCapacity;
  219. this.congestion = congestion;
  220. this.readBuffer = readBufferSize;
  221. this.writeBuffer = writeBufferSize;
  222. this.type = type;
  223. this.seed = seed;
  224. }
  225. static fromJson(json={}) {
  226. return new KcpStreamSettings(
  227. json.mtu,
  228. json.tti,
  229. json.uplinkCapacity,
  230. json.downlinkCapacity,
  231. json.congestion,
  232. json.readBufferSize,
  233. json.writeBufferSize,
  234. ObjectUtil.isEmpty(json.header) ? 'none' : json.header.type,
  235. json.seed,
  236. );
  237. }
  238. toJson() {
  239. return {
  240. mtu: this.mtu,
  241. tti: this.tti,
  242. uplinkCapacity: this.upCap,
  243. downlinkCapacity: this.downCap,
  244. congestion: this.congestion,
  245. readBufferSize: this.readBuffer,
  246. writeBufferSize: this.writeBuffer,
  247. header: {
  248. type: this.type,
  249. },
  250. seed: this.seed,
  251. };
  252. }
  253. }
  254. class WsStreamSettings extends XrayCommonClass {
  255. constructor(path='/', headers=[]) {
  256. super();
  257. this.path = path;
  258. this.headers = headers;
  259. }
  260. addHeader(name, value) {
  261. this.headers.push({ name: name, value: value });
  262. }
  263. removeHeader(index) {
  264. this.headers.splice(index, 1);
  265. }
  266. static fromJson(json={}) {
  267. return new WsStreamSettings(
  268. json.path,
  269. XrayCommonClass.toHeaders(json.headers),
  270. );
  271. }
  272. toJson() {
  273. return {
  274. path: this.path,
  275. headers: XrayCommonClass.toV2Headers(this.headers, false),
  276. };
  277. }
  278. }
  279. class HttpStreamSettings extends XrayCommonClass {
  280. constructor(path='/', host=['']) {
  281. super();
  282. this.path = path;
  283. this.host = host.length === 0 ? [''] : host;
  284. }
  285. addHost(host) {
  286. this.host.push(host);
  287. }
  288. removeHost(index) {
  289. this.host.splice(index, 1);
  290. }
  291. static fromJson(json={}) {
  292. return new HttpStreamSettings(json.path, json.host);
  293. }
  294. toJson() {
  295. let host = [];
  296. for (let i = 0; i < this.host.length; ++i) {
  297. if (!ObjectUtil.isEmpty(this.host[i])) {
  298. host.push(this.host[i]);
  299. }
  300. }
  301. return {
  302. path: this.path,
  303. host: host,
  304. }
  305. }
  306. }
  307. class QuicStreamSettings extends XrayCommonClass {
  308. constructor(security=VmessMethods.NONE,
  309. key='', type='none') {
  310. super();
  311. this.security = security;
  312. this.key = key;
  313. this.type = type;
  314. }
  315. static fromJson(json={}) {
  316. return new QuicStreamSettings(
  317. json.security,
  318. json.key,
  319. json.header ? json.header.type : 'none',
  320. );
  321. }
  322. toJson() {
  323. return {
  324. security: this.security,
  325. key: this.key,
  326. header: {
  327. type: this.type,
  328. }
  329. }
  330. }
  331. }
  332. class GrpcStreamSettings extends XrayCommonClass {
  333. constructor(serviceName="") {
  334. super();
  335. this.serviceName = serviceName;
  336. }
  337. static fromJson(json={}) {
  338. return new GrpcStreamSettings(json.serviceName);
  339. }
  340. toJson() {
  341. return {
  342. serviceName: this.serviceName,
  343. }
  344. }
  345. }
  346. class TlsStreamSettings extends XrayCommonClass {
  347. constructor(serverName='',
  348. certificates=[new TlsStreamSettings.Cert()]) {
  349. super();
  350. this.server = serverName;
  351. this.certs = certificates;
  352. }
  353. addCert(cert) {
  354. this.certs.push(cert);
  355. }
  356. removeCert(index) {
  357. this.certs.splice(index, 1);
  358. }
  359. static fromJson(json={}) {
  360. let certs;
  361. if (!ObjectUtil.isEmpty(json.certificates)) {
  362. certs = json.certificates.map(cert => TlsStreamSettings.Cert.fromJson(cert));
  363. }
  364. return new TlsStreamSettings(
  365. json.serverName,
  366. certs,
  367. );
  368. }
  369. toJson() {
  370. return {
  371. serverName: this.server,
  372. certificates: TlsStreamSettings.toJsonArray(this.certs),
  373. };
  374. }
  375. }
  376. TlsStreamSettings.Cert = class extends XrayCommonClass {
  377. constructor(useFile=true, certificateFile='', keyFile='', certificate='', key='') {
  378. super();
  379. this.useFile = useFile;
  380. this.certFile = certificateFile;
  381. this.keyFile = keyFile;
  382. this.cert = certificate instanceof Array ? certificate.join('\n') : certificate;
  383. this.key = key instanceof Array ? key.join('\n') : key;
  384. }
  385. static fromJson(json={}) {
  386. if ('certificateFile' in json && 'keyFile' in json) {
  387. return new TlsStreamSettings.Cert(
  388. true,
  389. json.certificateFile,
  390. json.keyFile,
  391. );
  392. } else {
  393. return new TlsStreamSettings.Cert(
  394. false, '', '',
  395. json.certificate.join('\n'),
  396. json.key.join('\n'),
  397. );
  398. }
  399. }
  400. toJson() {
  401. if (this.useFile) {
  402. return {
  403. certificateFile: this.certFile,
  404. keyFile: this.keyFile,
  405. };
  406. } else {
  407. return {
  408. certificate: this.cert.split('\n'),
  409. key: this.key.split('\n'),
  410. };
  411. }
  412. }
  413. };
  414. class StreamSettings extends XrayCommonClass {
  415. constructor(network='tcp',
  416. security='none',
  417. tlsSettings=new TlsStreamSettings(),
  418. tcpSettings=new TcpStreamSettings(),
  419. kcpSettings=new KcpStreamSettings(),
  420. wsSettings=new WsStreamSettings(),
  421. httpSettings=new HttpStreamSettings(),
  422. quicSettings=new QuicStreamSettings(),
  423. grpcSettings=new GrpcStreamSettings(),
  424. ) {
  425. super();
  426. this.network = network;
  427. this.security = security;
  428. this.tls = tlsSettings;
  429. this.tcp = tcpSettings;
  430. this.kcp = kcpSettings;
  431. this.ws = wsSettings;
  432. this.http = httpSettings;
  433. this.quic = quicSettings;
  434. this.grpc = grpcSettings;
  435. }
  436. get isTls() {
  437. return this.security === 'tls';
  438. }
  439. set isTls(isTls) {
  440. if (isTls) {
  441. this.security = 'tls';
  442. } else {
  443. this.security = 'none';
  444. }
  445. }
  446. get isXTls() {
  447. return this.security === "xtls";
  448. }
  449. set isXTls(isXTls) {
  450. if (isXTls) {
  451. this.security = 'xtls';
  452. } else {
  453. this.security = 'none';
  454. }
  455. }
  456. static fromJson(json={}) {
  457. let tls;
  458. if (json.security === "xtls") {
  459. tls = TlsStreamSettings.fromJson(json.xtlsSettings);
  460. } else {
  461. tls = TlsStreamSettings.fromJson(json.tlsSettings);
  462. }
  463. return new StreamSettings(
  464. json.network,
  465. json.security,
  466. tls,
  467. TcpStreamSettings.fromJson(json.tcpSettings),
  468. KcpStreamSettings.fromJson(json.kcpSettings),
  469. WsStreamSettings.fromJson(json.wsSettings),
  470. HttpStreamSettings.fromJson(json.httpSettings),
  471. QuicStreamSettings.fromJson(json.quicSettings),
  472. GrpcStreamSettings.fromJson(json.grpcSettings),
  473. );
  474. }
  475. toJson() {
  476. const network = this.network;
  477. return {
  478. network: network,
  479. security: this.security,
  480. tlsSettings: this.isTls ? this.tls.toJson() : undefined,
  481. xtlsSettings: this.isXTls ? this.tls.toJson() : undefined,
  482. tcpSettings: network === 'tcp' ? this.tcp.toJson() : undefined,
  483. kcpSettings: network === 'kcp' ? this.kcp.toJson() : undefined,
  484. wsSettings: network === 'ws' ? this.ws.toJson() : undefined,
  485. httpSettings: network === 'http' ? this.http.toJson() : undefined,
  486. quicSettings: network === 'quic' ? this.quic.toJson() : undefined,
  487. grpcSettings: network === 'grpc' ? this.grpc.toJson() : undefined,
  488. };
  489. }
  490. }
  491. class Sniffing extends XrayCommonClass {
  492. constructor(enabled=true, destOverride=['http', 'tls']) {
  493. super();
  494. this.enabled = enabled;
  495. this.destOverride = destOverride;
  496. }
  497. static fromJson(json={}) {
  498. let destOverride = ObjectUtil.clone(json.destOverride);
  499. if (!ObjectUtil.isEmpty(destOverride) && !ObjectUtil.isArrEmpty(destOverride)) {
  500. if (ObjectUtil.isEmpty(destOverride[0])) {
  501. destOverride = ['http', 'tls'];
  502. }
  503. }
  504. return new Sniffing(
  505. !!json.enabled,
  506. destOverride,
  507. );
  508. }
  509. }
  510. class Inbound extends XrayCommonClass {
  511. constructor(port=RandomUtil.randomIntRange(10000, 60000),
  512. listen='',
  513. protocol=Protocols.VMESS,
  514. settings=null,
  515. streamSettings=new StreamSettings(),
  516. tag='',
  517. sniffing=new Sniffing(),
  518. ) {
  519. super();
  520. this.port = port;
  521. this.listen = listen;
  522. this._protocol = protocol;
  523. this.settings = ObjectUtil.isEmpty(settings) ? Inbound.Settings.getSettings(protocol) : settings;
  524. this.stream = streamSettings;
  525. this.tag = tag;
  526. this.sniffing = sniffing;
  527. }
  528. get protocol() {
  529. return this._protocol;
  530. }
  531. set protocol(protocol) {
  532. this._protocol = protocol;
  533. this.settings = Inbound.Settings.getSettings(protocol);
  534. if (protocol === Protocols.TROJAN) {
  535. this.tls = true;
  536. }
  537. }
  538. get tls() {
  539. return this.stream.security === 'tls';
  540. }
  541. set tls(isTls) {
  542. if (isTls) {
  543. this.stream.security = 'tls';
  544. } else {
  545. if (this.protocol === Protocols.TROJAN) {
  546. this.xtls = true;
  547. } else {
  548. this.stream.security = 'none';
  549. }
  550. }
  551. }
  552. get xtls() {
  553. return this.stream.security === 'xtls';
  554. }
  555. set xtls(isXTls) {
  556. if (isXTls) {
  557. this.stream.security = 'xtls';
  558. } else {
  559. if (this.protocol === Protocols.TROJAN) {
  560. this.tls = true;
  561. } else {
  562. this.stream.security = 'none';
  563. }
  564. }
  565. }
  566. get network() {
  567. return this.stream.network;
  568. }
  569. set network(network) {
  570. this.stream.network = network;
  571. }
  572. // VMess & VLess
  573. get uuid() {
  574. switch (this.protocol) {
  575. case Protocols.VMESS:
  576. return this.settings.vmesses[0].id;
  577. case Protocols.VLESS:
  578. return this.settings.vlesses[0].id;
  579. default:
  580. return "";
  581. }
  582. }
  583. // VLess
  584. get flow() {
  585. switch (this.protocol) {
  586. case Protocols.VLESS:
  587. return this.settings.vlesses[0].flow;
  588. default:
  589. return "";
  590. }
  591. }
  592. // VMess
  593. get alterId() {
  594. switch (this.protocol) {
  595. case Protocols.VMESS:
  596. return this.settings.vmesses[0].alterId;
  597. default:
  598. return "";
  599. }
  600. }
  601. // Socks & HTTP
  602. get username() {
  603. switch (this.protocol) {
  604. case Protocols.SOCKS:
  605. case Protocols.HTTP:
  606. return this.settings.accounts[0].user;
  607. default:
  608. return "";
  609. }
  610. }
  611. // Trojan & Shadowsocks & Socks & HTTP
  612. get password() {
  613. switch (this.protocol) {
  614. case Protocols.TROJAN:
  615. return this.settings.clients[0].password;
  616. case Protocols.SHADOWSOCKS:
  617. return this.settings.password;
  618. case Protocols.SOCKS:
  619. case Protocols.HTTP:
  620. return this.settings.accounts[0].pass;
  621. default:
  622. return "";
  623. }
  624. }
  625. // Shadowsocks
  626. get method() {
  627. switch (this.protocol) {
  628. case Protocols.SHADOWSOCKS:
  629. return this.settings.method;
  630. default:
  631. return "";
  632. }
  633. }
  634. get serverName() {
  635. if (this.stream.isTls || this.stream.isXTls) {
  636. return this.stream.tls.server;
  637. }
  638. return "";
  639. }
  640. canEnableTls() {
  641. switch (this.protocol) {
  642. case Protocols.VMESS:
  643. case Protocols.VLESS:
  644. case Protocols.TROJAN:
  645. case Protocols.SHADOWSOCKS:
  646. break;
  647. default:
  648. return false;
  649. }
  650. switch (this.network) {
  651. case "tcp":
  652. case "ws":
  653. case "http":
  654. case "quic":
  655. case "grpc":
  656. return true;
  657. default:
  658. return false;
  659. }
  660. }
  661. canSetTls() {
  662. return this.canEnableTls();
  663. }
  664. canEnableXTls() {
  665. switch (this.protocol) {
  666. case Protocols.VLESS:
  667. case Protocols.TROJAN:
  668. break;
  669. default:
  670. return false;
  671. }
  672. return this.network === "tcp";
  673. }
  674. canEnableStream() {
  675. switch (this.protocol) {
  676. case Protocols.VMESS:
  677. case Protocols.VLESS:
  678. case Protocols.SHADOWSOCKS:
  679. return true;
  680. default:
  681. return false;
  682. }
  683. }
  684. canSniffing() {
  685. switch (this.protocol) {
  686. case Protocols.VMESS:
  687. case Protocols.VLESS:
  688. case Protocols.TROJAN:
  689. case Protocols.SHADOWSOCKS:
  690. return true;
  691. default:
  692. return false;
  693. }
  694. }
  695. reset() {
  696. this.port = RandomUtil.randomIntRange(10000, 60000);
  697. this.listen = '';
  698. this.protocol = Protocols.VMESS;
  699. this.settings = Inbound.Settings.getSettings(Protocols.VMESS);
  700. this.stream = new StreamSettings();
  701. this.tag = '';
  702. this.sniffing = new Sniffing();
  703. }
  704. genVmessLink(address='', remark='') {
  705. if (this.protocol !== Protocols.VMESS) {
  706. return '';
  707. }
  708. let network = this.stream.network;
  709. let type = 'none';
  710. let host = '';
  711. let path = '';
  712. if (network === 'tcp') {
  713. let tcp = this.stream.tcp;
  714. type = tcp.type;
  715. if (type === 'http') {
  716. let request = tcp.request;
  717. path = request.path.join(',');
  718. let index = request.headers.findIndex(header => header.name.toLowerCase() === 'host');
  719. if (index >= 0) {
  720. host = request.headers[index].value;
  721. }
  722. }
  723. } else if (network === 'kcp') {
  724. let kcp = this.stream.kcp;
  725. type = kcp.type;
  726. path = kcp.seed;
  727. } else if (network === 'ws') {
  728. let ws = this.stream.ws;
  729. path = ws.path;
  730. let index = ws.headers.findIndex(header => header.name.toLowerCase() === 'host');
  731. if (index >= 0) {
  732. host = ws.headers[index].value;
  733. }
  734. } else if (network === 'http') {
  735. network = 'h2';
  736. path = this.stream.http.path;
  737. host = this.stream.http.host.join(',');
  738. } else if (network === 'quic') {
  739. type = this.stream.quic.type;
  740. host = this.stream.quic.security;
  741. path = this.stream.quic.key;
  742. } else if (network === 'grpc') {
  743. path = this.stream.grpc.serviceName;
  744. }
  745. if (this.stream.security === 'tls') {
  746. if (!ObjectUtil.isEmpty(this.stream.tls.server)) {
  747. address = this.stream.tls.server;
  748. }
  749. }
  750. let obj = {
  751. v: '2',
  752. ps: remark,
  753. add: address,
  754. port: this.port,
  755. id: this.settings.vmesses[0].id,
  756. aid: this.settings.vmesses[0].alterId,
  757. net: network,
  758. type: type,
  759. host: host,
  760. path: path,
  761. tls: this.stream.security,
  762. };
  763. return 'vmess://' + base64(JSON.stringify(obj, null, 2));
  764. }
  765. genVLESSLink(address = '', remark='') {
  766. const settings = this.settings;
  767. const uuid = settings.vlesses[0].id;
  768. const port = this.port;
  769. const type = this.stream.network;
  770. const params = new Map();
  771. params.set("type", this.stream.network);
  772. if (this.xtls) {
  773. params.set("security", "xtls");
  774. } else {
  775. params.set("security", this.stream.security);
  776. }
  777. switch (type) {
  778. case "tcp":
  779. const tcp = this.stream.tcp;
  780. if (tcp.type === 'http') {
  781. const request = tcp.request;
  782. params.set("path", request.path.join(','));
  783. const index = request.headers.findIndex(header => header.name.toLowerCase() === 'host');
  784. if (index >= 0) {
  785. const host = request.headers[index].value;
  786. params.set("host", host);
  787. }
  788. }
  789. break;
  790. case "kcp":
  791. const kcp = this.stream.kcp;
  792. params.set("headerType", kcp.type);
  793. params.set("seed", kcp.seed);
  794. break;
  795. case "ws":
  796. const ws = this.stream.ws;
  797. params.set("path", ws.path);
  798. const index = ws.headers.findIndex(header => header.name.toLowerCase() === 'host');
  799. if (index >= 0) {
  800. const host = ws.headers[index].value;
  801. params.set("host", host);
  802. }
  803. break;
  804. case "http":
  805. const http = this.stream.http;
  806. params.set("path", http.path);
  807. params.set("host", http.host);
  808. break;
  809. case "quic":
  810. const quic = this.stream.quic;
  811. params.set("quicSecurity", quic.security);
  812. params.set("key", quic.key);
  813. params.set("headerType", quic.type);
  814. break;
  815. case "grpc":
  816. const grpc = this.stream.grpc;
  817. params.set("serviceName", grpc.serviceName);
  818. break;
  819. }
  820. if (this.stream.security === 'tls') {
  821. if (!ObjectUtil.isEmpty(this.stream.tls.server)) {
  822. address = this.stream.tls.server;
  823. params.set("sni", address);
  824. }
  825. }
  826. if (this.xtls) {
  827. params.set("flow", this.settings.vlesses[0].flow);
  828. }
  829. for (const [key, value] of params) {
  830. switch (key) {
  831. case "host":
  832. case "path":
  833. case "seed":
  834. case "key":
  835. case "alpn":
  836. params.set(key, encodeURIComponent(value));
  837. break;
  838. }
  839. }
  840. const link = `vless://${uuid}@${address}:${port}`;
  841. const url = new URL(link);
  842. for (const [key, value] of params) {
  843. url.searchParams.set(key, value)
  844. }
  845. url.hash = encodeURIComponent(remark);
  846. return url.toString();
  847. }
  848. genSSLink(address='', remark='') {
  849. let settings = this.settings;
  850. const server = this.stream.tls.server;
  851. if (!ObjectUtil.isEmpty(server)) {
  852. address = server;
  853. }
  854. return 'ss://' + safeBase64(settings.method + ':' + settings.password + '@' + address + ':' + this.port)
  855. + '#' + encodeURIComponent(remark);
  856. }
  857. genTrojanLink(address='', remark='') {
  858. let settings = this.settings;
  859. return `trojan://${settings.clients[0].password}@${address}:${this.port}#${encodeURIComponent(remark)}`;
  860. }
  861. genLink(address='', remark='') {
  862. switch (this.protocol) {
  863. case Protocols.VMESS: return this.genVmessLink(address, remark);
  864. case Protocols.VLESS: return this.genVLESSLink(address, remark);
  865. case Protocols.SHADOWSOCKS: return this.genSSLink(address, remark);
  866. case Protocols.TROJAN: return this.genTrojanLink(address, remark);
  867. default: return '';
  868. }
  869. }
  870. static fromJson(json={}) {
  871. return new Inbound(
  872. json.port,
  873. json.listen,
  874. json.protocol,
  875. Inbound.Settings.fromJson(json.protocol, json.settings),
  876. StreamSettings.fromJson(json.streamSettings),
  877. json.tag,
  878. Sniffing.fromJson(json.sniffing),
  879. )
  880. }
  881. toJson() {
  882. let streamSettings;
  883. if (this.canEnableStream() || this.protocol === Protocols.TROJAN) {
  884. streamSettings = this.stream.toJson();
  885. }
  886. return {
  887. port: this.port,
  888. listen: this.listen,
  889. protocol: this.protocol,
  890. settings: this.settings instanceof XrayCommonClass ? this.settings.toJson() : this.settings,
  891. streamSettings: streamSettings,
  892. tag: this.tag,
  893. sniffing: this.sniffing.toJson(),
  894. };
  895. }
  896. }
  897. Inbound.Settings = class extends XrayCommonClass {
  898. constructor(protocol) {
  899. super();
  900. this.protocol = protocol;
  901. }
  902. static getSettings(protocol) {
  903. switch (protocol) {
  904. case Protocols.VMESS: return new Inbound.VmessSettings(protocol);
  905. case Protocols.VLESS: return new Inbound.VLESSSettings(protocol);
  906. case Protocols.TROJAN: return new Inbound.TrojanSettings(protocol);
  907. case Protocols.SHADOWSOCKS: return new Inbound.ShadowsocksSettings(protocol);
  908. case Protocols.DOKODEMO: return new Inbound.DokodemoSettings(protocol);
  909. case Protocols.MTPROTO: return new Inbound.MtprotoSettings(protocol);
  910. case Protocols.SOCKS: return new Inbound.SocksSettings(protocol);
  911. case Protocols.HTTP: return new Inbound.HttpSettings(protocol);
  912. default: return null;
  913. }
  914. }
  915. static fromJson(protocol, json) {
  916. switch (protocol) {
  917. case Protocols.VMESS: return Inbound.VmessSettings.fromJson(json);
  918. case Protocols.VLESS: return Inbound.VLESSSettings.fromJson(json);
  919. case Protocols.TROJAN: return Inbound.TrojanSettings.fromJson(json);
  920. case Protocols.SHADOWSOCKS: return Inbound.ShadowsocksSettings.fromJson(json);
  921. case Protocols.DOKODEMO: return Inbound.DokodemoSettings.fromJson(json);
  922. case Protocols.MTPROTO: return Inbound.MtprotoSettings.fromJson(json);
  923. case Protocols.SOCKS: return Inbound.SocksSettings.fromJson(json);
  924. case Protocols.HTTP: return Inbound.HttpSettings.fromJson(json);
  925. default: return null;
  926. }
  927. }
  928. toJson() {
  929. return {};
  930. }
  931. };
  932. Inbound.VmessSettings = class extends Inbound.Settings {
  933. constructor(protocol,
  934. vmesses=[new Inbound.VmessSettings.Vmess()],
  935. disableInsecureEncryption=false) {
  936. super(protocol);
  937. this.vmesses = vmesses;
  938. this.disableInsecure = disableInsecureEncryption;
  939. }
  940. indexOfVmessById(id) {
  941. return this.vmesses.findIndex(vmess => vmess.id === id);
  942. }
  943. addVmess(vmess) {
  944. if (this.indexOfVmessById(vmess.id) >= 0) {
  945. return false;
  946. }
  947. this.vmesses.push(vmess);
  948. }
  949. delVmess(vmess) {
  950. const i = this.indexOfVmessById(vmess.id);
  951. if (i >= 0) {
  952. this.vmesses.splice(i, 1);
  953. }
  954. }
  955. static fromJson(json={}) {
  956. return new Inbound.VmessSettings(
  957. Protocols.VMESS,
  958. json.clients.map(client => Inbound.VmessSettings.Vmess.fromJson(client)),
  959. ObjectUtil.isEmpty(json.disableInsecureEncryption) ? false : json.disableInsecureEncryption,
  960. );
  961. }
  962. toJson() {
  963. return {
  964. clients: Inbound.VmessSettings.toJsonArray(this.vmesses),
  965. disableInsecureEncryption: this.disableInsecure,
  966. };
  967. }
  968. };
  969. Inbound.VmessSettings.Vmess = class extends XrayCommonClass {
  970. constructor(id=RandomUtil.randomUUID(), alterId=64) {
  971. super();
  972. this.id = id;
  973. this.alterId = alterId;
  974. }
  975. static fromJson(json={}) {
  976. return new Inbound.VmessSettings.Vmess(
  977. json.id,
  978. json.alterId,
  979. );
  980. }
  981. };
  982. Inbound.VLESSSettings = class extends Inbound.Settings {
  983. constructor(protocol,
  984. vlesses=[new Inbound.VLESSSettings.VLESS()],
  985. decryption='none',
  986. fallbacks=[],) {
  987. super(protocol);
  988. this.vlesses = vlesses;
  989. this.decryption = decryption;
  990. this.fallbacks = fallbacks;
  991. }
  992. addFallback() {
  993. this.fallbacks.push(new Inbound.VLESSSettings.Fallback());
  994. }
  995. delFallback(index) {
  996. this.fallbacks.splice(index, 1);
  997. }
  998. static fromJson(json={}) {
  999. return new Inbound.VLESSSettings(
  1000. Protocols.VLESS,
  1001. json.clients.map(client => Inbound.VLESSSettings.VLESS.fromJson(client)),
  1002. json.decryption,
  1003. Inbound.VLESSSettings.Fallback.fromJson(json.fallbacks),
  1004. );
  1005. }
  1006. toJson() {
  1007. return {
  1008. clients: Inbound.VLESSSettings.toJsonArray(this.vlesses),
  1009. decryption: this.decryption,
  1010. fallbacks: Inbound.VLESSSettings.toJsonArray(this.fallbacks),
  1011. };
  1012. }
  1013. };
  1014. Inbound.VLESSSettings.VLESS = class extends XrayCommonClass {
  1015. constructor(id=RandomUtil.randomUUID(), flow=VLESS_FLOW.DIRECT) {
  1016. super();
  1017. this.id = id;
  1018. this.flow = flow;
  1019. }
  1020. static fromJson(json={}) {
  1021. return new Inbound.VLESSSettings.VLESS(
  1022. json.id,
  1023. json.flow,
  1024. );
  1025. }
  1026. };
  1027. Inbound.VLESSSettings.Fallback = class extends XrayCommonClass {
  1028. constructor(name="", alpn='', path='', dest='', xver=0) {
  1029. super();
  1030. this.name = name;
  1031. this.alpn = alpn;
  1032. this.path = path;
  1033. this.dest = dest;
  1034. this.xver = xver;
  1035. }
  1036. toJson() {
  1037. let xver = this.xver;
  1038. if (!Number.isInteger(xver)) {
  1039. xver = 0;
  1040. }
  1041. return {
  1042. name: this.name,
  1043. alpn: this.alpn,
  1044. path: this.path,
  1045. dest: this.dest,
  1046. xver: xver,
  1047. }
  1048. }
  1049. static fromJson(json=[]) {
  1050. const fallbacks = [];
  1051. for (let fallback of json) {
  1052. fallbacks.push(new Inbound.VLESSSettings.Fallback(
  1053. fallback.name,
  1054. fallback.alpn,
  1055. fallback.path,
  1056. fallback.dest,
  1057. fallback.xver,
  1058. ))
  1059. }
  1060. return fallbacks;
  1061. }
  1062. };
  1063. Inbound.TrojanSettings = class extends Inbound.Settings {
  1064. constructor(protocol, clients=[new Inbound.TrojanSettings.Client()]) {
  1065. super(protocol);
  1066. this.clients = clients;
  1067. }
  1068. toJson() {
  1069. return {
  1070. clients: Inbound.TrojanSettings.toJsonArray(this.clients),
  1071. };
  1072. }
  1073. static fromJson(json={}) {
  1074. const clients = [];
  1075. for (const c of json.clients) {
  1076. clients.push(Inbound.TrojanSettings.Client.fromJson(c));
  1077. }
  1078. return new Inbound.TrojanSettings(Protocols.TROJAN, clients);
  1079. }
  1080. };
  1081. Inbound.TrojanSettings.Client = class extends XrayCommonClass {
  1082. constructor(password=RandomUtil.randomSeq(10)) {
  1083. super();
  1084. this.password = password;
  1085. }
  1086. toJson() {
  1087. return {
  1088. password: this.password,
  1089. };
  1090. }
  1091. static fromJson(json={}) {
  1092. return new Inbound.TrojanSettings.Client(json.password);
  1093. }
  1094. };
  1095. Inbound.ShadowsocksSettings = class extends Inbound.Settings {
  1096. constructor(protocol,
  1097. method=SSMethods.AES_256_GCM,
  1098. password=RandomUtil.randomSeq(10),
  1099. network='tcp,udp'
  1100. ) {
  1101. super(protocol);
  1102. this.method = method;
  1103. this.password = password;
  1104. this.network = network;
  1105. }
  1106. static fromJson(json={}) {
  1107. return new Inbound.ShadowsocksSettings(
  1108. Protocols.SHADOWSOCKS,
  1109. json.method,
  1110. json.password,
  1111. json.network,
  1112. );
  1113. }
  1114. toJson() {
  1115. return {
  1116. method: this.method,
  1117. password: this.password,
  1118. network: this.network,
  1119. };
  1120. }
  1121. };
  1122. Inbound.DokodemoSettings = class extends Inbound.Settings {
  1123. constructor(protocol, address, port, network='tcp,udp') {
  1124. super(protocol);
  1125. this.address = address;
  1126. this.port = port;
  1127. this.network = network;
  1128. }
  1129. static fromJson(json={}) {
  1130. return new Inbound.DokodemoSettings(
  1131. Protocols.DOKODEMO,
  1132. json.address,
  1133. json.port,
  1134. json.network,
  1135. );
  1136. }
  1137. toJson() {
  1138. return {
  1139. address: this.address,
  1140. port: this.port,
  1141. network: this.network,
  1142. };
  1143. }
  1144. };
  1145. Inbound.MtprotoSettings = class extends Inbound.Settings {
  1146. constructor(protocol, users=[new Inbound.MtprotoSettings.MtUser()]) {
  1147. super(protocol);
  1148. this.users = users;
  1149. }
  1150. static fromJson(json={}) {
  1151. return new Inbound.MtprotoSettings(
  1152. Protocols.MTPROTO,
  1153. json.users.map(user => Inbound.MtprotoSettings.MtUser.fromJson(user)),
  1154. );
  1155. }
  1156. toJson() {
  1157. return {
  1158. users: XrayCommonClass.toJsonArray(this.users),
  1159. };
  1160. }
  1161. };
  1162. Inbound.MtprotoSettings.MtUser = class extends XrayCommonClass {
  1163. constructor(secret=RandomUtil.randomMTSecret()) {
  1164. super();
  1165. this.secret = secret;
  1166. }
  1167. static fromJson(json={}) {
  1168. return new Inbound.MtprotoSettings.MtUser(json.secret);
  1169. }
  1170. };
  1171. Inbound.SocksSettings = class extends Inbound.Settings {
  1172. constructor(protocol, auth='password', accounts=[new Inbound.SocksSettings.SocksAccount()], udp=false, ip='127.0.0.1') {
  1173. super(protocol);
  1174. this.auth = auth;
  1175. this.accounts = accounts;
  1176. this.udp = udp;
  1177. this.ip = ip;
  1178. }
  1179. addAccount(account) {
  1180. this.accounts.push(account);
  1181. }
  1182. delAccount(index) {
  1183. this.accounts.splice(index, 1);
  1184. }
  1185. static fromJson(json={}) {
  1186. let accounts;
  1187. if (json.auth === 'password') {
  1188. accounts = json.accounts.map(
  1189. account => Inbound.SocksSettings.SocksAccount.fromJson(account)
  1190. )
  1191. }
  1192. return new Inbound.SocksSettings(
  1193. Protocols.SOCKS,
  1194. json.auth,
  1195. accounts,
  1196. json.udp,
  1197. json.ip,
  1198. );
  1199. }
  1200. toJson() {
  1201. return {
  1202. auth: this.auth,
  1203. accounts: this.auth === 'password' ? this.accounts.map(account => account.toJson()) : undefined,
  1204. udp: this.udp,
  1205. ip: this.ip,
  1206. };
  1207. }
  1208. };
  1209. Inbound.SocksSettings.SocksAccount = class extends XrayCommonClass {
  1210. constructor(user=RandomUtil.randomSeq(10), pass=RandomUtil.randomSeq(10)) {
  1211. super();
  1212. this.user = user;
  1213. this.pass = pass;
  1214. }
  1215. static fromJson(json={}) {
  1216. return new Inbound.SocksSettings.SocksAccount(json.user, json.pass);
  1217. }
  1218. };
  1219. Inbound.HttpSettings = class extends Inbound.Settings {
  1220. constructor(protocol, accounts=[new Inbound.HttpSettings.HttpAccount()]) {
  1221. super(protocol);
  1222. this.accounts = accounts;
  1223. }
  1224. addAccount(account) {
  1225. this.accounts.push(account);
  1226. }
  1227. delAccount(index) {
  1228. this.accounts.splice(index, 1);
  1229. }
  1230. static fromJson(json={}) {
  1231. return new Inbound.HttpSettings(
  1232. Protocols.HTTP,
  1233. json.accounts.map(account => Inbound.HttpSettings.HttpAccount.fromJson(account)),
  1234. );
  1235. }
  1236. toJson() {
  1237. return {
  1238. accounts: Inbound.HttpSettings.toJsonArray(this.accounts),
  1239. };
  1240. }
  1241. };
  1242. Inbound.HttpSettings.HttpAccount = class extends XrayCommonClass {
  1243. constructor(user=RandomUtil.randomSeq(10), pass=RandomUtil.randomSeq(10)) {
  1244. super();
  1245. this.user = user;
  1246. this.pass = pass;
  1247. }
  1248. static fromJson(json={}) {
  1249. return new Inbound.HttpSettings.HttpAccount(json.user, json.pass);
  1250. }
  1251. };