diff --git a/backend/src/core/proxy-utils/parsers/peggy/qx.js b/backend/src/core/proxy-utils/parsers/peggy/qx.js index 8053a0c..2b2c70a 100644 --- a/backend/src/core/proxy-utils/parsers/peggy/qx.js +++ b/backend/src/core/proxy-utils/parsers/peggy/qx.js @@ -29,7 +29,7 @@ const grammars = String.raw` $set(proxy, "ws-opts.path", obfs.path); $set(proxy, "ws-opts.headers.Host", obfs.host); } else if (obfs.type === "over-tls") { - throw new Error("over-tls is not supported"); + proxy.tls = true; } else if (obfs.type === "http") { proxy.network = "http"; $set(proxy, "http-opts.path", obfs.path); @@ -83,7 +83,11 @@ vmess = "vmess" equals address (uuid/method/over_tls/tls_host/tls_fingerprint/tls_verification/tag/obfs/obfs_host/obfs_uri/udp_relay/udp_over_tcp/fast_open/aead/others)* { proxy.type = "vmess"; proxy.cipher = proxy.cipher || "auto"; - proxy.alterId = proxy.alterId || 0; + if (proxy.aead) { + proxy.alterId = 0; + } else { + proxy.alterId = proxy.alterId || 0; + } handleObfs(); } @@ -140,7 +144,7 @@ method = comma "method" equals cipher:cipher { else proxy.cipher = 'auto'; }; cipher = ("aes-128-gcm"/"aes-192-gcm"/"aes-256-gcm"/"aes-128-cfb"/"aes-192-cfb"/"aes-256-cfb"/"aes-128-ctr"/"aes-192-ctr"/"aes-256-ctr"/"rc4-md5"/"chacha20-ietf-poly1305"/"chacha20-ietf"/"chacha20-poly1305"/"chacha20"/"none"); -aead = comma "aead" equals flag:bool { proxy.alterId = 0; } +aead = comma "aead" equals flag:bool { proxy.aead = flag; } udp_relay = comma "udp-relay" equals flag:bool { proxy.udp = flag; } udp_over_tcp = comma "udp-over-tcp" equals flag:bool { throw new Error("UDP over TCP is not supported"); } diff --git a/backend/src/core/proxy-utils/parsers/peggy/qx.peg b/backend/src/core/proxy-utils/parsers/peggy/qx.peg index 4ad9da6..4d207ea 100644 --- a/backend/src/core/proxy-utils/parsers/peggy/qx.peg +++ b/backend/src/core/proxy-utils/parsers/peggy/qx.peg @@ -27,7 +27,7 @@ $set(proxy, "ws-opts.path", obfs.path); $set(proxy, "ws-opts.headers.Host", obfs.host); } else if (obfs.type === "over-tls") { - throw new Error("over-tls is not supported"); + proxy.tls = true; } else if (obfs.type === "http") { proxy.network = "http"; $set(proxy, "http-opts.path", obfs.path); @@ -81,7 +81,11 @@ vmess = "vmess" equals address (uuid/method/over_tls/tls_host/tls_fingerprint/tls_verification/tag/obfs/obfs_host/obfs_uri/udp_relay/udp_over_tcp/fast_open/aead/others)* { proxy.type = "vmess"; proxy.cipher = proxy.cipher || "auto"; - proxy.alterId = proxy.alterId || 0; + if (proxy.aead) { + proxy.alterId = 0; + } else { + proxy.alterId = proxy.alterId || 0; + } handleObfs(); } @@ -138,7 +142,7 @@ method = comma "method" equals cipher:cipher { else proxy.cipher = 'auto'; }; cipher = ("aes-128-gcm"/"aes-192-gcm"/"aes-256-gcm"/"aes-128-cfb"/"aes-192-cfb"/"aes-256-cfb"/"aes-128-ctr"/"aes-192-ctr"/"aes-256-ctr"/"rc4-md5"/"chacha20-ietf-poly1305"/"chacha20-ietf"/"chacha20-poly1305"/"chacha20"/"none"); -aead = comma "aead" equals flag:bool { proxy.alterId = 0; } +aead = comma "aead" equals flag:bool { proxy.aead = flag; } udp_relay = comma "udp-relay" equals flag:bool { proxy.udp = flag; } udp_over_tcp = comma "udp-over-tcp" equals flag:bool { throw new Error("UDP over TCP is not supported"); } diff --git a/backend/src/core/proxy-utils/parsers/peggy/surge.js b/backend/src/core/proxy-utils/parsers/peggy/surge.js index e5e87ff..2b2bb72 100644 --- a/backend/src/core/proxy-utils/parsers/peggy/surge.js +++ b/backend/src/core/proxy-utils/parsers/peggy/surge.js @@ -46,7 +46,11 @@ shadowsocks = tag equals "ss" address (method/passwordk/obfs/obfs_host/obfs_uri/ vmess = tag equals "vmess" address (vmess_uuid/vmess_aead/ws/ws_path/ws_headers/method/tls/sni/tls_fingerprint/tls_verification/fast_open/udp_relay/others)* { proxy.type = "vmess"; proxy.cipher = proxy.cipher || "auto"; - proxy.alterId = proxy.alterId || 0; + if (proxy.aead) { + proxy.alterId = 0; + } else { + proxy.alterId = proxy.alterId || 0; + } handleWebsocket(); } trojan = tag equals "trojan" address (passwordk/ws/ws_path/ws_headers/tls/sni/tls_fingerprint/tls_verification/fast_open/udp_relay/others)* { @@ -145,7 +149,7 @@ snell_version = comma "version" equals match:$[0-9]+ { proxy.version = parseInt( passwordk = comma "password" equals match:[^,]+ { proxy.password = match.join(""); } vmess_uuid = comma "username" equals match:[^,]+ { proxy.uuid = match.join(""); } -vmess_aead = comma "vmess-aead" equals flag:bool { proxy.alterId = 0; } +vmess_aead = comma "vmess-aead" equals flag:bool { proxy.aead = flag; } method = comma "encrypt-method" equals cipher:cipher { if (cipher !== 'none') proxy.cipher = cipher; diff --git a/backend/src/core/proxy-utils/parsers/peggy/surge.peg b/backend/src/core/proxy-utils/parsers/peggy/surge.peg index 8478e81..c569afd 100644 --- a/backend/src/core/proxy-utils/parsers/peggy/surge.peg +++ b/backend/src/core/proxy-utils/parsers/peggy/surge.peg @@ -44,7 +44,11 @@ shadowsocks = tag equals "ss" address (method/passwordk/obfs/obfs_host/obfs_uri/ vmess = tag equals "vmess" address (vmess_uuid/vmess_aead/ws/ws_path/ws_headers/method/tls/sni/tls_fingerprint/tls_verification/fast_open/udp_relay/others)* { proxy.type = "vmess"; proxy.cipher = proxy.cipher || "auto"; - proxy.alterId = proxy.alterId || 0; + if (proxy.aead) { + proxy.alterId = 0; + } else { + proxy.alterId = proxy.alterId || 0; + } handleWebsocket(); } trojan = tag equals "trojan" address (passwordk/ws/ws_path/ws_headers/tls/sni/tls_fingerprint/tls_verification/fast_open/udp_relay/others)* { @@ -143,7 +147,7 @@ snell_version = comma "version" equals match:$[0-9]+ { proxy.version = parseInt( passwordk = comma "password" equals match:[^,]+ { proxy.password = match.join(""); } vmess_uuid = comma "username" equals match:[^,]+ { proxy.uuid = match.join(""); } -vmess_aead = comma "vmess-aead" equals flag:bool { proxy.alterId = 0; } +vmess_aead = comma "vmess-aead" equals flag:bool { proxy.aead = flag; } method = comma "encrypt-method" equals cipher:cipher { if (cipher !== 'none') proxy.cipher = cipher; diff --git a/backend/src/core/proxy-utils/processors/index.js b/backend/src/core/proxy-utils/processors/index.js index 1d5e50c..aa149b6 100644 --- a/backend/src/core/proxy-utils/processors/index.js +++ b/backend/src/core/proxy-utils/processors/index.js @@ -10,7 +10,9 @@ function SetPropertyOperator({ key, value }) { name: 'Set Property Operator', func: (proxies) => { return proxies.map((p) => { - p[key] = value; + if ((key == 'aead' && p.type === 'vmess') || key !== 'aead') { + p[key] = value; + } return p; }); }, diff --git a/backend/src/core/proxy-utils/producers/clash.js b/backend/src/core/proxy-utils/producers/clash.js index b73116c..82acfaa 100644 --- a/backend/src/core/proxy-utils/producers/clash.js +++ b/backend/src/core/proxy-utils/producers/clash.js @@ -10,7 +10,7 @@ export default function Clash_Producer() { proxies .map((proxy) => { delete proxy['tls-fingerprint']; - delete proxy['vmess-aead']; + delete proxy['aead']; return ' - ' + JSON.stringify(proxy) + '\n'; }) .join('') diff --git a/backend/src/core/proxy-utils/producers/loon.js b/backend/src/core/proxy-utils/producers/loon.js index 75d196e..8ed88f2 100644 --- a/backend/src/core/proxy-utils/producers/loon.js +++ b/backend/src/core/proxy-utils/producers/loon.js @@ -174,7 +174,11 @@ function vmess(proxy) { result.appendIfPresent(`,tls-name=${proxy.sni}`, 'sni'); // AEAD - result.appendIfPresent(`,alterId=${proxy.alterId}`, 'alterId'); + if (isPresent(proxy, 'aead')) { + result.append(`,alterId=0`); + } else { + result.append(`,alterId=${proxy.alterId}`); + } // tfo result.appendIfPresent(`,fast-open=${proxy.tfo}`, 'tfo'); diff --git a/backend/src/core/proxy-utils/producers/qx.js b/backend/src/core/proxy-utils/producers/qx.js index c190754..6fc70bc 100644 --- a/backend/src/core/proxy-utils/producers/qx.js +++ b/backend/src/core/proxy-utils/producers/qx.js @@ -180,12 +180,7 @@ function vmess(proxy) { const appendIfPresent = result.appendIfPresent.bind(result); append(`vmess=${proxy.server}:${proxy.port}`); - if (proxy.cipher === 'auto') { - append(`,method=none`); - } else { - append(`,method=${proxy.cipher}`); - } - + append(`,method=${proxy.cipher === 'auto' ? 'none' : proxy.cipher}`); append(`,password=${proxy.uuid}`); // obfs @@ -196,27 +191,19 @@ function vmess(proxy) { if (proxy.network === 'ws') { if (proxy.tls) append(`,obfs=wss`); else append(`,obfs=ws`); - appendIfPresent( - `,obfs-uri=${proxy['ws-opts'].path}`, - 'ws-opts.path', - ); - appendIfPresent( - `,obfs-host=${proxy['ws-opts'].headers.Host}`, - 'ws-opts.headers.Host', - ); } else if (proxy.network === 'http') { append(`,obfs=http`); - appendIfPresent( - `,obfs-uri=${proxy['http-opts'].path}`, - 'http-opts.path', - ); - appendIfPresent( - `,obfs-host=${proxy['http-opts'].headers.Host}`, - 'http-opts.headers.Host', - ); } else { throw new Error(`network ${proxy.network} is unsupported`); } + appendIfPresent(`,obfs-uri=${proxy['ws-opts'].path}`, 'ws-opts.path'); + appendIfPresent( + `,obfs-host=${proxy[`${proxy.network}-opts`].headers.Host}`, + `${proxy.network}-opts.headers.Host`, + ); + } else { + // over-tls + if (proxy.tls) append(`,obfs=over-tls`); } // tls fingerprint @@ -233,7 +220,11 @@ function vmess(proxy) { appendIfPresent(`,tls-host=${proxy.sni}`, 'sni'); // AEAD - appendIfPresent(`,aead=${proxy.alterId === 0}`, 'alterId'); + if (isPresent(proxy, 'aead')) { + append(`,aead=${proxy.aead}`); + } else { + append(`,aead=${proxy.alterId === 0}`); + } // tfo appendIfPresent(`,fast-open=${proxy.tfo}`, 'tfo'); diff --git a/backend/src/core/proxy-utils/producers/stash.js b/backend/src/core/proxy-utils/producers/stash.js index 6e0380f..ede72a4 100644 --- a/backend/src/core/proxy-utils/producers/stash.js +++ b/backend/src/core/proxy-utils/producers/stash.js @@ -6,7 +6,7 @@ export default function Stash_Producer() { proxies .map((proxy) => { delete proxy['tls-fingerprint']; - delete proxy['vmess-aead']; + delete proxy['aead']; return ' - ' + JSON.stringify(proxy) + '\n'; }) .join('') diff --git a/backend/src/core/proxy-utils/producers/surge.js b/backend/src/core/proxy-utils/producers/surge.js index 9d7b8ed..462e16c 100644 --- a/backend/src/core/proxy-utils/producers/surge.js +++ b/backend/src/core/proxy-utils/producers/surge.js @@ -124,7 +124,11 @@ function vmess(proxy) { } // AEAD - result.appendIfPresent(`,vmess-aead=${proxy.alterId === 0}`, 'alterId'); + if (isPresent(proxy, 'aead')) { + result.append(`,vmess-aead=${proxy.aead}`); + } else { + result.append(`,vmess-aead=${proxy.alterId === 0}`); + } // tls fingerprint result.appendIfPresent( diff --git a/backend/src/test/proxy-parsers/testcases.js b/backend/src/test/proxy-parsers/testcases.js index b2aa24f..a628e4b 100644 --- a/backend/src/test/proxy-parsers/testcases.js +++ b/backend/src/test/proxy-parsers/testcases.js @@ -214,6 +214,7 @@ function createTestCases() { port, uuid, cipher, + alterId: 0 }, Loon: { type: 'vmess', @@ -222,13 +223,16 @@ function createTestCases() { port, uuid, cipher, + alterId: 0 }, Surge: { type: 'vmess', name, server, port, - uuid, // Surge lacks support for specifying cipher for vmess protocol! + uuid, + cipher: 'auto', // Surge lacks support for specifying cipher for vmess protocol! + alterId: 0 }, }, }, @@ -246,6 +250,7 @@ function createTestCases() { port, uuid, cipher, + aead: true, alterId: 0, }, Loon: { @@ -262,8 +267,10 @@ function createTestCases() { name, server, port, - uuid, // Surge lacks support for specifying cipher for vmess protocol! + uuid, + cipher: 'auto', // Surge lacks support for specifying cipher for vmess protocol! alterId: 0, + aead: true, }, }, }, @@ -288,6 +295,7 @@ function createTestCases() { Host: obfs_host, }, }, + alterId: 0, }, Loon: { type: 'vmess', @@ -303,13 +311,15 @@ function createTestCases() { Host: obfs_host, }, }, + alterId: 0, }, Surge: { type: 'vmess', name, server, port, - uuid, // Surge lacks support for specifying cipher for vmess protocol! + uuid, + cipher: 'auto', // Surge lacks support for specifying cipher for vmess protocol! network: 'ws', 'ws-opts': { path: obfs_path, @@ -317,6 +327,7 @@ function createTestCases() { Host: obfs_host, }, }, + alterId: 0, }, }, }, @@ -344,6 +355,7 @@ function createTestCases() { tls: true, 'skip-cert-verify': true, sni, + alterId: 0, }, Loon: { type: 'vmess', @@ -362,13 +374,15 @@ function createTestCases() { tls: true, 'skip-cert-verify': true, sni, + alterId: 0, }, Surge: { type: 'vmess', name, server, port, - uuid, // Surge lacks support for specifying cipher for vmess protocol! + uuid, + cipher: 'auto', // Surge lacks support for specifying cipher for vmess protocol! network: 'ws', 'ws-opts': { path: obfs_path, @@ -379,6 +393,7 @@ function createTestCases() { tls: true, 'skip-cert-verify': true, sni, + alterId: 0, }, }, }, @@ -402,6 +417,7 @@ function createTestCases() { Host: obfs_host, }, }, + alterId: 0, }, Loon: { type: 'vmess', @@ -417,6 +433,7 @@ function createTestCases() { Host: obfs_host, }, }, + alterId: 0, }, }, }, @@ -442,6 +459,7 @@ function createTestCases() { tls: true, 'skip-cert-verify': true, sni, + alterId: 0, }, }, }, diff --git a/web/src/views/SubEditor.vue b/web/src/views/SubEditor.vue index 6c73769..765c0e7 100644 --- a/web/src/views/SubEditor.vue +++ b/web/src/views/SubEditor.vue @@ -137,7 +137,7 @@ - + Vmess AEAD @@ -329,7 +329,7 @@ export default { "skip-cert-verify": "DEFAULT", tfo: "DEFAULT", "surge-hybrid": "DEFAULT", - "vmess-aead": "DEFAULT", + "aead": "DEFAULT", }, process: [], selected: [] @@ -399,8 +399,8 @@ export default { type: "Useless Filter" }); } - // udp, tfo, scert, surge-hybrid, vmess-aead - for (const opt of ['udp', 'tfo', 'skip-cert-verify', 'surge-hybrid', 'vmess-aead']) { + // udp, tfo, scert, surge-hybrid, aead + for (const opt of ['udp', 'tfo', 'skip-cert-verify', 'surge-hybrid', 'aead']) { if (this.options[opt] !== 'DEFAULT') { output.process.push({ type: "Set Property Operator",