xray.js 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325
  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. canEnableTls() {
  573. switch (this.protocol) {
  574. case Protocols.VMESS:
  575. case Protocols.VLESS:
  576. case Protocols.TROJAN:
  577. case Protocols.SHADOWSOCKS:
  578. break;
  579. default:
  580. return false;
  581. }
  582. switch (this.network) {
  583. case "tcp":
  584. case "ws":
  585. case "http":
  586. case "quic":
  587. case "grpc":
  588. return true;
  589. default:
  590. return false;
  591. }
  592. }
  593. canSetTls() {
  594. return this.canEnableTls();
  595. }
  596. canEnableXTls() {
  597. switch (this.protocol) {
  598. case Protocols.VLESS:
  599. case Protocols.TROJAN:
  600. break;
  601. default:
  602. return false;
  603. }
  604. return this.network === "tcp";
  605. }
  606. canEnableStream() {
  607. switch (this.protocol) {
  608. case Protocols.VMESS:
  609. case Protocols.VLESS:
  610. case Protocols.SHADOWSOCKS:
  611. return true;
  612. default:
  613. return false;
  614. }
  615. }
  616. canSniffing() {
  617. switch (this.protocol) {
  618. case Protocols.VMESS:
  619. case Protocols.VLESS:
  620. case Protocols.TROJAN:
  621. case Protocols.SHADOWSOCKS:
  622. return true;
  623. default:
  624. return false;
  625. }
  626. }
  627. reset() {
  628. this.port = RandomUtil.randomIntRange(10000, 60000);
  629. this.listen = '';
  630. this.protocol = Protocols.VMESS;
  631. this.settings = Inbound.Settings.getSettings(Protocols.VMESS);
  632. this.stream = new StreamSettings();
  633. this.tag = '';
  634. this.sniffing = new Sniffing();
  635. }
  636. genVmessLink(address='', remark='') {
  637. if (this.protocol !== Protocols.VMESS) {
  638. return '';
  639. }
  640. let network = this.stream.network;
  641. let type = 'none';
  642. let host = '';
  643. let path = '';
  644. if (network === 'tcp') {
  645. let tcp = this.stream.tcp;
  646. type = tcp.type;
  647. if (type === 'http') {
  648. let request = tcp.request;
  649. path = request.path.join(',');
  650. let index = request.headers.findIndex(header => header.name.toLowerCase() === 'host');
  651. if (index >= 0) {
  652. host = request.headers[index].value;
  653. }
  654. }
  655. } else if (network === 'kcp') {
  656. let kcp = this.stream.kcp;
  657. type = kcp.type;
  658. path = kcp.seed;
  659. } else if (network === 'ws') {
  660. let ws = this.stream.ws;
  661. path = ws.path;
  662. let index = ws.headers.findIndex(header => header.name.toLowerCase() === 'host');
  663. if (index >= 0) {
  664. host = ws.headers[index].value;
  665. }
  666. } else if (network === 'http') {
  667. network = 'h2';
  668. path = this.stream.http.path;
  669. host = this.stream.http.host.join(',');
  670. } else if (network === 'quic') {
  671. type = this.stream.quic.type;
  672. host = this.stream.quic.security;
  673. path = this.stream.quic.key;
  674. } else if (network === 'grpc') {
  675. path = this.stream.grpc.serviceName;
  676. }
  677. if (this.stream.security === 'tls') {
  678. if (!ObjectUtil.isEmpty(this.stream.tls.server)) {
  679. address = this.stream.tls.server;
  680. }
  681. }
  682. let obj = {
  683. v: '2',
  684. ps: remark,
  685. add: address,
  686. port: this.port,
  687. id: this.settings.vmesses[0].id,
  688. aid: this.settings.vmesses[0].alterId,
  689. net: network,
  690. type: type,
  691. host: host,
  692. path: path,
  693. tls: this.stream.security,
  694. };
  695. return 'vmess://' + base64(JSON.stringify(obj, null, 2));
  696. }
  697. genVLESSLink(address = '', remark='') {
  698. const settings = this.settings;
  699. const uuid = settings.vlesses[0].id;
  700. const port = this.port;
  701. const type = this.stream.network;
  702. const params = new Map();
  703. params.set("type", this.stream.network);
  704. if (this.isXTls) {
  705. params.set("security", "xtls");
  706. } else {
  707. params.set("security", this.stream.security);
  708. }
  709. switch (type) {
  710. case "tcp":
  711. const tcp = this.stream.tcp;
  712. if (tcp.type === 'http') {
  713. const request = tcp.request;
  714. params.set("path", request.path.join(','));
  715. const index = request.headers.findIndex(header => header.name.toLowerCase() === 'host');
  716. if (index >= 0) {
  717. const host = request.headers[index].value;
  718. params.set("host", host);
  719. }
  720. }
  721. break;
  722. case "kcp":
  723. const kcp = this.stream.kcp;
  724. params.set("headerType", kcp.type);
  725. params.set("seed", kcp.seed);
  726. break;
  727. case "ws":
  728. const ws = this.stream.ws;
  729. params.set("path", ws.path);
  730. const index = ws.headers.findIndex(header => header.name.toLowerCase() === 'host');
  731. if (index >= 0) {
  732. const host = ws.headers[index].value;
  733. params.set("host", host);
  734. }
  735. break;
  736. case "http":
  737. const http = this.stream.http;
  738. params.set("path", http.path);
  739. params.set("host", http.host);
  740. break;
  741. case "quic":
  742. const quic = this.stream.quic;
  743. params.set("quicSecurity", quic.security);
  744. params.set("key", quic.key);
  745. params.set("headerType", quic.type);
  746. break;
  747. case "grpc":
  748. const grpc = this.stream.grpc;
  749. params.set("serviceName", grpc.serviceName);
  750. break;
  751. }
  752. if (this.stream.security === 'tls') {
  753. if (!ObjectUtil.isEmpty(this.stream.tls.server)) {
  754. address = this.stream.tls.server;
  755. params.set("sni", address);
  756. }
  757. }
  758. if (this.isXTls) {
  759. params.set("flow", this.settings.vlesses[0].flow);
  760. }
  761. for (const [key, value] of params) {
  762. switch (key) {
  763. case "host":
  764. case "path":
  765. case "seed":
  766. case "key":
  767. case "alpn":
  768. params.set(key, encodeURIComponent(value));
  769. break;
  770. }
  771. }
  772. const link = `vless://${uuid}@${address}:${port}`;
  773. const url = new URL(link);
  774. for (const [key, value] of params) {
  775. url.searchParams.set(key, value)
  776. }
  777. url.hash = encodeURIComponent(remark);
  778. return url.toString();
  779. }
  780. genSSLink(address='', remark='') {
  781. let settings = this.settings;
  782. const server = this.stream.tls.server;
  783. if (!ObjectUtil.isEmpty(server)) {
  784. address = server;
  785. }
  786. return 'ss://' + safeBase64(settings.method + ':' + settings.password + '@' + address + ':' + this.port)
  787. + '#' + encodeURIComponent(remark);
  788. }
  789. genTrojanLink(address='', remark='') {
  790. let settings = this.settings;
  791. return `trojan://${settings.clients[0].password}@${address}:${this.port}#${encodeURIComponent(remark)}`;
  792. }
  793. genLink(address='', remark='') {
  794. switch (this.protocol) {
  795. case Protocols.VMESS: return this.genVmessLink(address, remark);
  796. case Protocols.VLESS: return this.genVLESSLink(address, remark);
  797. case Protocols.SHADOWSOCKS: return this.genSSLink(address, remark);
  798. case Protocols.TROJAN: return this.genTrojanLink(address, remark);
  799. default: return '';
  800. }
  801. }
  802. static fromJson(json={}) {
  803. return new Inbound(
  804. json.port,
  805. json.listen,
  806. json.protocol,
  807. Inbound.Settings.fromJson(json.protocol, json.settings),
  808. StreamSettings.fromJson(json.streamSettings),
  809. json.tag,
  810. Sniffing.fromJson(json.sniffing),
  811. )
  812. }
  813. toJson() {
  814. let streamSettings;
  815. if (this.canEnableStream() || this.protocol === Protocols.TROJAN) {
  816. streamSettings = this.stream.toJson();
  817. }
  818. return {
  819. port: this.port,
  820. listen: this.listen,
  821. protocol: this.protocol,
  822. settings: this.settings instanceof XrayCommonClass ? this.settings.toJson() : this.settings,
  823. streamSettings: streamSettings,
  824. tag: this.tag,
  825. sniffing: this.sniffing.toJson(),
  826. };
  827. }
  828. }
  829. Inbound.Settings = class extends XrayCommonClass {
  830. constructor(protocol) {
  831. super();
  832. this.protocol = protocol;
  833. }
  834. static getSettings(protocol) {
  835. switch (protocol) {
  836. case Protocols.VMESS: return new Inbound.VmessSettings(protocol);
  837. case Protocols.VLESS: return new Inbound.VLESSSettings(protocol);
  838. case Protocols.TROJAN: return new Inbound.TrojanSettings(protocol);
  839. case Protocols.SHADOWSOCKS: return new Inbound.ShadowsocksSettings(protocol);
  840. case Protocols.DOKODEMO: return new Inbound.DokodemoSettings(protocol);
  841. case Protocols.MTPROTO: return new Inbound.MtprotoSettings(protocol);
  842. case Protocols.SOCKS: return new Inbound.SocksSettings(protocol);
  843. case Protocols.HTTP: return new Inbound.HttpSettings(protocol);
  844. default: return null;
  845. }
  846. }
  847. static fromJson(protocol, json) {
  848. switch (protocol) {
  849. case Protocols.VMESS: return Inbound.VmessSettings.fromJson(json);
  850. case Protocols.VLESS: return Inbound.VLESSSettings.fromJson(json);
  851. case Protocols.TROJAN: return Inbound.TrojanSettings.fromJson(json);
  852. case Protocols.SHADOWSOCKS: return Inbound.ShadowsocksSettings.fromJson(json);
  853. case Protocols.DOKODEMO: return Inbound.DokodemoSettings.fromJson(json);
  854. case Protocols.MTPROTO: return Inbound.MtprotoSettings.fromJson(json);
  855. case Protocols.SOCKS: return Inbound.SocksSettings.fromJson(json);
  856. case Protocols.HTTP: return Inbound.HttpSettings.fromJson(json);
  857. default: return null;
  858. }
  859. }
  860. toJson() {
  861. return {};
  862. }
  863. };
  864. Inbound.VmessSettings = class extends Inbound.Settings {
  865. constructor(protocol,
  866. vmesses=[new Inbound.VmessSettings.Vmess()],
  867. disableInsecureEncryption=false) {
  868. super(protocol);
  869. this.vmesses = vmesses;
  870. this.disableInsecure = disableInsecureEncryption;
  871. }
  872. indexOfVmessById(id) {
  873. return this.vmesses.findIndex(vmess => vmess.id === id);
  874. }
  875. addVmess(vmess) {
  876. if (this.indexOfVmessById(vmess.id) >= 0) {
  877. return false;
  878. }
  879. this.vmesses.push(vmess);
  880. }
  881. delVmess(vmess) {
  882. const i = this.indexOfVmessById(vmess.id);
  883. if (i >= 0) {
  884. this.vmesses.splice(i, 1);
  885. }
  886. }
  887. static fromJson(json={}) {
  888. return new Inbound.VmessSettings(
  889. Protocols.VMESS,
  890. json.clients.map(client => Inbound.VmessSettings.Vmess.fromJson(client)),
  891. ObjectUtil.isEmpty(json.disableInsecureEncryption) ? false : json.disableInsecureEncryption,
  892. );
  893. }
  894. toJson() {
  895. return {
  896. clients: Inbound.VmessSettings.toJsonArray(this.vmesses),
  897. disableInsecureEncryption: this.disableInsecure,
  898. };
  899. }
  900. };
  901. Inbound.VmessSettings.Vmess = class extends XrayCommonClass {
  902. constructor(id=RandomUtil.randomUUID(), alterId=64) {
  903. super();
  904. this.id = id;
  905. this.alterId = alterId;
  906. }
  907. static fromJson(json={}) {
  908. return new Inbound.VmessSettings.Vmess(
  909. json.id,
  910. json.alterId,
  911. );
  912. }
  913. };
  914. Inbound.VLESSSettings = class extends Inbound.Settings {
  915. constructor(protocol,
  916. vlesses=[new Inbound.VLESSSettings.VLESS()],
  917. decryption='none',
  918. fallbacks=[],) {
  919. super(protocol);
  920. this.vlesses = vlesses;
  921. this.decryption = decryption;
  922. this.fallbacks = fallbacks;
  923. }
  924. addFallback() {
  925. this.fallbacks.push(new Inbound.VLESSSettings.Fallback());
  926. }
  927. delFallback(index) {
  928. this.fallbacks.splice(index, 1);
  929. }
  930. static fromJson(json={}) {
  931. return new Inbound.VLESSSettings(
  932. Protocols.VLESS,
  933. json.clients.map(client => Inbound.VLESSSettings.VLESS.fromJson(client)),
  934. json.decryption,
  935. Inbound.VLESSSettings.Fallback.fromJson(json.fallbacks),
  936. );
  937. }
  938. toJson() {
  939. return {
  940. clients: Inbound.VLESSSettings.toJsonArray(this.vlesses),
  941. decryption: this.decryption,
  942. fallbacks: Inbound.VLESSSettings.toJsonArray(this.fallbacks),
  943. };
  944. }
  945. };
  946. Inbound.VLESSSettings.VLESS = class extends XrayCommonClass {
  947. constructor(id=RandomUtil.randomUUID(), flow=VLESS_FLOW.DIRECT) {
  948. super();
  949. this.id = id;
  950. this.flow = flow;
  951. }
  952. static fromJson(json={}) {
  953. return new Inbound.VLESSSettings.VLESS(
  954. json.id,
  955. json.flow,
  956. );
  957. }
  958. };
  959. Inbound.VLESSSettings.Fallback = class extends XrayCommonClass {
  960. constructor(name="", alpn='', path='', dest='', xver=0) {
  961. super();
  962. this.name = name;
  963. this.alpn = alpn;
  964. this.path = path;
  965. this.dest = dest;
  966. this.xver = xver;
  967. }
  968. toJson() {
  969. let xver = this.xver;
  970. if (!Number.isInteger(xver)) {
  971. xver = 0;
  972. }
  973. return {
  974. name: this.name,
  975. alpn: this.alpn,
  976. path: this.path,
  977. dest: this.dest,
  978. xver: xver,
  979. }
  980. }
  981. static fromJson(json=[]) {
  982. const fallbacks = [];
  983. for (let fallback of json) {
  984. fallbacks.push(new Inbound.VLESSSettings.Fallback(
  985. fallback.name,
  986. fallback.alpn,
  987. fallback.path,
  988. fallback.dest,
  989. fallback.xver,
  990. ))
  991. }
  992. return fallbacks;
  993. }
  994. };
  995. Inbound.TrojanSettings = class extends Inbound.Settings {
  996. constructor(protocol, clients=[new Inbound.TrojanSettings.Client()]) {
  997. super(protocol);
  998. this.clients = clients;
  999. }
  1000. toJson() {
  1001. return {
  1002. clients: Inbound.TrojanSettings.toJsonArray(this.clients),
  1003. };
  1004. }
  1005. static fromJson(json={}) {
  1006. const clients = [];
  1007. for (const c of json.clients) {
  1008. clients.push(Inbound.TrojanSettings.Client.fromJson(c));
  1009. }
  1010. return new Inbound.TrojanSettings(Protocols.TROJAN, clients);
  1011. }
  1012. };
  1013. Inbound.TrojanSettings.Client = class extends XrayCommonClass {
  1014. constructor(password=RandomUtil.randomSeq(10)) {
  1015. super();
  1016. this.password = password;
  1017. }
  1018. toJson() {
  1019. return {
  1020. password: this.password,
  1021. };
  1022. }
  1023. static fromJson(json={}) {
  1024. return new Inbound.TrojanSettings.Client(json.password);
  1025. }
  1026. };
  1027. Inbound.ShadowsocksSettings = class extends Inbound.Settings {
  1028. constructor(protocol,
  1029. method=SSMethods.AES_256_GCM,
  1030. password=RandomUtil.randomSeq(10),
  1031. network='tcp,udp'
  1032. ) {
  1033. super(protocol);
  1034. this.method = method;
  1035. this.password = password;
  1036. this.network = network;
  1037. }
  1038. static fromJson(json={}) {
  1039. return new Inbound.ShadowsocksSettings(
  1040. Protocols.SHADOWSOCKS,
  1041. json.method,
  1042. json.password,
  1043. json.network,
  1044. );
  1045. }
  1046. toJson() {
  1047. return {
  1048. method: this.method,
  1049. password: this.password,
  1050. network: this.network,
  1051. };
  1052. }
  1053. };
  1054. Inbound.DokodemoSettings = class extends Inbound.Settings {
  1055. constructor(protocol, address, port, network='tcp,udp') {
  1056. super(protocol);
  1057. this.address = address;
  1058. this.port = port;
  1059. this.network = network;
  1060. }
  1061. static fromJson(json={}) {
  1062. return new Inbound.DokodemoSettings(
  1063. Protocols.DOKODEMO,
  1064. json.address,
  1065. json.port,
  1066. json.network,
  1067. );
  1068. }
  1069. toJson() {
  1070. return {
  1071. address: this.address,
  1072. port: this.port,
  1073. network: this.network,
  1074. };
  1075. }
  1076. };
  1077. Inbound.MtprotoSettings = class extends Inbound.Settings {
  1078. constructor(protocol, users=[new Inbound.MtprotoSettings.MtUser()]) {
  1079. super(protocol);
  1080. this.users = users;
  1081. }
  1082. static fromJson(json={}) {
  1083. return new Inbound.MtprotoSettings(
  1084. Protocols.MTPROTO,
  1085. json.users.map(user => Inbound.MtprotoSettings.MtUser.fromJson(user)),
  1086. );
  1087. }
  1088. toJson() {
  1089. return {
  1090. users: XrayCommonClass.toJsonArray(this.users),
  1091. };
  1092. }
  1093. };
  1094. Inbound.MtprotoSettings.MtUser = class extends XrayCommonClass {
  1095. constructor(secret=RandomUtil.randomMTSecret()) {
  1096. super();
  1097. this.secret = secret;
  1098. }
  1099. static fromJson(json={}) {
  1100. return new Inbound.MtprotoSettings.MtUser(json.secret);
  1101. }
  1102. };
  1103. Inbound.SocksSettings = class extends Inbound.Settings {
  1104. constructor(protocol, auth='password', accounts=[new Inbound.SocksSettings.SocksAccount()], udp=false, ip='127.0.0.1') {
  1105. super(protocol);
  1106. this.auth = auth;
  1107. this.accounts = accounts;
  1108. this.udp = udp;
  1109. this.ip = ip;
  1110. }
  1111. addAccount(account) {
  1112. this.accounts.push(account);
  1113. }
  1114. delAccount(index) {
  1115. this.accounts.splice(index, 1);
  1116. }
  1117. static fromJson(json={}) {
  1118. let accounts;
  1119. if (json.auth === 'password') {
  1120. accounts = json.accounts.map(
  1121. account => Inbound.SocksSettings.SocksAccount.fromJson(account)
  1122. )
  1123. }
  1124. return new Inbound.SocksSettings(
  1125. Protocols.SOCKS,
  1126. json.auth,
  1127. accounts,
  1128. json.udp,
  1129. json.ip,
  1130. );
  1131. }
  1132. toJson() {
  1133. return {
  1134. auth: this.auth,
  1135. accounts: this.auth === 'password' ? this.accounts.map(account => account.toJson()) : undefined,
  1136. udp: this.udp,
  1137. ip: this.ip,
  1138. };
  1139. }
  1140. };
  1141. Inbound.SocksSettings.SocksAccount = class extends XrayCommonClass {
  1142. constructor(user=RandomUtil.randomSeq(10), pass=RandomUtil.randomSeq(10)) {
  1143. super();
  1144. this.user = user;
  1145. this.pass = pass;
  1146. }
  1147. static fromJson(json={}) {
  1148. return new Inbound.SocksSettings.SocksAccount(json.user, json.pass);
  1149. }
  1150. };
  1151. Inbound.HttpSettings = class extends Inbound.Settings {
  1152. constructor(protocol, accounts=[new Inbound.HttpSettings.HttpAccount()]) {
  1153. super(protocol);
  1154. this.accounts = accounts;
  1155. }
  1156. addAccount(account) {
  1157. this.accounts.push(account);
  1158. }
  1159. delAccount(index) {
  1160. this.accounts.splice(index, 1);
  1161. }
  1162. static fromJson(json={}) {
  1163. return new Inbound.HttpSettings(
  1164. Protocols.HTTP,
  1165. json.accounts.map(account => Inbound.HttpSettings.HttpAccount.fromJson(account)),
  1166. );
  1167. }
  1168. toJson() {
  1169. return {
  1170. accounts: Inbound.HttpSettings.toJsonArray(this.accounts),
  1171. };
  1172. }
  1173. };
  1174. Inbound.HttpSettings.HttpAccount = class extends XrayCommonClass {
  1175. constructor(user=RandomUtil.randomSeq(10), pass=RandomUtil.randomSeq(10)) {
  1176. super();
  1177. this.user = user;
  1178. this.pass = pass;
  1179. }
  1180. static fromJson(json={}) {
  1181. return new Inbound.HttpSettings.HttpAccount(json.user, json.pass);
  1182. }
  1183. };