From a8dff126c73ca142e2aab66845aa54d585aafee8 Mon Sep 17 00:00:00 2001 From: MHSanaei Date: Wed, 6 May 2026 08:17:27 +0200 Subject: [PATCH] outbound: reverse Sniffing --- web/assets/js/model/inbound.js | 7 +++- web/assets/js/model/outbound.js | 63 +++++++++++++++++++++++++++++++-- web/html/form/outbound.html | 35 ++++++++++++++++++ 3 files changed, 102 insertions(+), 3 deletions(-) diff --git a/web/assets/js/model/inbound.js b/web/assets/js/model/inbound.js index bb30dbcc..263091d9 100644 --- a/web/assets/js/model/inbound.js +++ b/web/assets/js/model/inbound.js @@ -2617,12 +2617,14 @@ Inbound.VLESSSettings.VLESS = class extends Inbound.ClientBase { id = RandomUtil.randomUUID(), flow = '', reverseTag = '', + reverseSniffing = new Sniffing(), email, limitIp, totalGB, expiryTime, enable, tgId, subId, comment, reset, created_at, updated_at, ) { super(email, limitIp, totalGB, expiryTime, enable, tgId, subId, comment, reset, created_at, updated_at); this.id = id; this.flow = flow; this.reverseTag = reverseTag; + this.reverseSniffing = reverseSniffing; } static fromJson(json = {}) { @@ -2630,6 +2632,7 @@ Inbound.VLESSSettings.VLESS = class extends Inbound.ClientBase { json.id, json.flow, json.reverse?.tag ?? '', + Sniffing.fromJson(json.reverse?.sniffing || {}), ...Inbound.ClientBase.commonArgsFromJson(json), ); } @@ -2641,7 +2644,9 @@ Inbound.VLESSSettings.VLESS = class extends Inbound.ClientBase { ...this._clientBaseToJson(), }; if (this.reverseTag) { - json.reverse = { tag: this.reverseTag }; + json.reverse = { + tag: this.reverseTag, + }; } return json; } diff --git a/web/assets/js/model/outbound.js b/web/assets/js/model/outbound.js index 9b740297..f312ed96 100644 --- a/web/assets/js/model/outbound.js +++ b/web/assets/js/model/outbound.js @@ -50,6 +50,13 @@ const ALPN_OPTION = { HTTP1: "http/1.1", }; +const SNIFFING_OPTION = { + HTTP: "http", + TLS: "tls", + QUIC: "quic", + FAKEDNS: "fakedns" +}; + const OutboundDomainStrategies = [ "AsIs", "UseIP", @@ -170,6 +177,7 @@ Object.freeze(SSMethods); Object.freeze(TLS_FLOW_CONTROL); Object.freeze(UTLS_FINGERPRINT); Object.freeze(ALPN_OPTION); +Object.freeze(SNIFFING_OPTION); Object.freeze(OutboundDomainStrategies); Object.freeze(WireguardDomainStrategy); Object.freeze(USERS_SECURITY); @@ -196,6 +204,50 @@ class CommonClass { } } +class ReverseSniffing extends CommonClass { + constructor( + enabled = false, + destOverride = ['http', 'tls', 'quic', 'fakedns'], + metadataOnly = false, + routeOnly = false, + ipsExcluded = [], + domainsExcluded = [], + ) { + super(); + this.enabled = enabled; + this.destOverride = Array.isArray(destOverride) && destOverride.length > 0 ? destOverride : ['http', 'tls', 'quic', 'fakedns']; + this.metadataOnly = metadataOnly; + this.routeOnly = routeOnly; + this.ipsExcluded = Array.isArray(ipsExcluded) ? ipsExcluded : []; + this.domainsExcluded = Array.isArray(domainsExcluded) ? domainsExcluded : []; + } + + static fromJson(json = {}) { + if (!json || Object.keys(json).length === 0) { + return new ReverseSniffing(); + } + return new ReverseSniffing( + !!json.enabled, + json.destOverride, + json.metadataOnly, + json.routeOnly, + json.ipsExcluded || [], + json.domainsExcluded || [], + ); + } + + toJson() { + return { + enabled: this.enabled, + destOverride: this.destOverride, + metadataOnly: this.metadataOnly, + routeOnly: this.routeOnly, + ipsExcluded: this.ipsExcluded.length > 0 ? this.ipsExcluded : undefined, + domainsExcluded: this.domainsExcluded.length > 0 ? this.domainsExcluded : undefined, + }; + } +} + class TcpStreamSettings extends CommonClass { constructor(type = 'none', host, path) { super(); @@ -1747,7 +1799,7 @@ Outbound.VmessSettings = class extends CommonClass { } }; Outbound.VLESSSettings = class extends CommonClass { - constructor(address, port, id, flow, encryption, reverseTag = '', testpre = 0, testseed = [900, 500, 900, 256]) { + constructor(address, port, id, flow, encryption, reverseTag = '', reverseSniffing = new ReverseSniffing(), testpre = 0, testseed = [900, 500, 900, 256]) { super(); this.address = address; this.port = port; @@ -1755,6 +1807,7 @@ Outbound.VLESSSettings = class extends CommonClass { this.flow = flow; this.encryption = encryption; this.reverseTag = reverseTag; + this.reverseSniffing = reverseSniffing; this.testpre = testpre; this.testseed = testseed; } @@ -1768,6 +1821,7 @@ Outbound.VLESSSettings = class extends CommonClass { json.flow, json.encryption, json.reverse?.tag || '', + ReverseSniffing.fromJson(json.reverse?.sniffing || {}), json.testpre || 0, json.testseed && json.testseed.length >= 4 ? json.testseed : [900, 500, 900, 256] ); @@ -1782,7 +1836,12 @@ Outbound.VLESSSettings = class extends CommonClass { encryption: this.encryption, }; if (!ObjectUtil.isEmpty(this.reverseTag)) { - result.reverse = { tag: this.reverseTag }; + const reverseSniffing = this.reverseSniffing ? this.reverseSniffing.toJson() : {}; + const defaultReverseSniffing = new ReverseSniffing().toJson(); + result.reverse = { + tag: this.reverseTag, + sniffing: JSON.stringify(reverseSniffing) === JSON.stringify(defaultReverseSniffing) ? {} : reverseSniffing, + }; } // Only include Vision settings when flow is set if (this.flow && this.flow !== '') { diff --git a/web/html/form/outbound.html b/web/html/form/outbound.html index 96891b04..53f8fae4 100644 --- a/web/html/form/outbound.html +++ b/web/html/form/outbound.html @@ -354,6 +354,41 @@ +