Skip to content

Commit fede003

Browse files
committed
feat: Surge 支持 anytls. 根据请求的 User-Agent 中的版本号自动开启, 或使用 includeUnsupportedProxy 参数或开启 包含官方/商店版不支持的协议 开关
1 parent ff614b6 commit fede003

File tree

7 files changed

+135
-42
lines changed

7 files changed

+135
-42
lines changed

backend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "sub-store",
3-
"version": "2.20.48",
3+
"version": "2.20.50",
44
"description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and Shadowrocket.",
55
"main": "src/main.js",
66
"scripts": {

backend/src/core/proxy-utils/parsers/index.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1498,6 +1498,14 @@ function Surge_Direct() {
14981498
const parse = (line) => getSurgeParser().parse(line);
14991499
return { name, test, parse };
15001500
}
1501+
function Surge_Anytls() {
1502+
const name = 'Surge Anytls Parser';
1503+
const test = (line) => {
1504+
return /^.*=\s*anytls/.test(line.split(',')[0]);
1505+
};
1506+
const parse = (line) => getSurgeParser().parse(line);
1507+
return { name, test, parse };
1508+
}
15011509
function Surge_SSH() {
15021510
const name = 'Surge SSH Parser';
15031511
const test = (line) => {
@@ -1691,6 +1699,7 @@ export default [
16911699
URI_AnyTLS(),
16921700
Clash_All(),
16931701
Surge_Direct(),
1702+
Surge_Anytls(),
16941703
Surge_SSH(),
16951704
Surge_SS(),
16961705
Surge_VMess(),

backend/src/core/proxy-utils/parsers/peggy/surge.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ const grammars = String.raw`
3737
}
3838
}
3939
40-
start = (shadowsocks/vmess/trojan/https/http/snell/socks5/socks5_tls/tuic/tuic_v5/wireguard/hysteria2/ssh/direct) {
40+
start = (anytls/shadowsocks/vmess/trojan/https/http/snell/socks5/socks5_tls/tuic/tuic_v5/wireguard/hysteria2/ssh/direct) {
4141
return proxy;
4242
}
4343
@@ -118,6 +118,10 @@ socks5_tls = tag equals "socks5-tls" address (username password)? (usernamek pas
118118
proxy.tls = true;
119119
handleShadowTLS();
120120
}
121+
anytls = tag equals "anytls" address (passwordk/reuse/ip_version/underlying_proxy/tos/allow_other_interface/interface/test_url/test_udp/test_timeout/hybrid/no_error_alert/tls_fingerprint/tls_verification/sni/fast_open/tfo/block_quic/others)* {
122+
proxy.type = "anytls";
123+
proxy.tls = true;
124+
}
121125
direct = tag equals "direct" (udp_relay/ip_version/underlying_proxy/tos/allow_other_interface/interface/test_url/test_udp/test_timeout/hybrid/no_error_alert/fast_open/tfo/block_quic/others)* {
122126
proxy.type = "direct";
123127
}

backend/src/core/proxy-utils/parsers/peggy/surge.peg

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
}
3636
}
3737

38-
start = (shadowsocks/vmess/trojan/https/http/snell/socks5/socks5_tls/tuic/tuic_v5/wireguard/hysteria2/ssh/direct) {
38+
start = (anytls/shadowsocks/vmess/trojan/https/http/snell/socks5/socks5_tls/tuic/tuic_v5/wireguard/hysteria2/ssh/direct) {
3939
return proxy;
4040
}
4141

@@ -116,6 +116,10 @@ socks5_tls = tag equals "socks5-tls" address (username password)? (usernamek pas
116116
proxy.tls = true;
117117
handleShadowTLS();
118118
}
119+
anytls = tag equals "anytls" address (passwordk/reuse/ip_version/underlying_proxy/tos/allow_other_interface/interface/test_url/test_udp/test_timeout/hybrid/no_error_alert/tls_fingerprint/tls_verification/sni/fast_open/tfo/block_quic/others)* {
120+
proxy.type = "anytls";
121+
proxy.tls = true;
122+
}
119123
direct = tag equals "direct" (udp_relay/ip_version/underlying_proxy/tos/allow_other_interface/interface/test_url/test_udp/test_timeout/hybrid/no_error_alert/fast_open/tfo/block_quic/others)* {
120124
proxy.type = "direct";
121125
}

backend/src/core/proxy-utils/producers/surge.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ export default function Surge_Producer() {
4646
if (opts['include-unsupported-proxy'] && proxy.type === 'wireguard') {
4747
return wireguard(proxy);
4848
}
49+
if (opts['include-unsupported-proxy'] && proxy.type === 'anytls') {
50+
return anytls(proxy);
51+
}
4952
throw new Error(
5053
`Platform ${targetPlatform} does not support proxy type: ${proxy.type}`,
5154
);
@@ -278,6 +281,71 @@ function trojan(proxy) {
278281
return result.toString();
279282
}
280283

284+
function anytls(proxy) {
285+
const result = new Result(proxy);
286+
result.append(`${proxy.name}=${proxy.type},${proxy.server},${proxy.port}`);
287+
result.appendIfPresent(`,password="${proxy.password}"`, 'password');
288+
289+
const ip_version = ipVersions[proxy['ip-version']] || proxy['ip-version'];
290+
result.appendIfPresent(`,ip-version=${ip_version}`, 'ip-version');
291+
292+
result.appendIfPresent(
293+
`,no-error-alert=${proxy['no-error-alert']}`,
294+
'no-error-alert',
295+
);
296+
297+
// tls fingerprint
298+
result.appendIfPresent(
299+
`,server-cert-fingerprint-sha256=${proxy['tls-fingerprint']}`,
300+
'tls-fingerprint',
301+
);
302+
303+
// tls verification
304+
result.appendIfPresent(`,sni=${proxy.sni}`, 'sni');
305+
result.appendIfPresent(
306+
`,skip-cert-verify=${proxy['skip-cert-verify']}`,
307+
'skip-cert-verify',
308+
);
309+
310+
// tfo
311+
result.appendIfPresent(`,tfo=${proxy.tfo}`, 'tfo');
312+
313+
// udp
314+
result.appendIfPresent(`,udp-relay=${proxy.udp}`, 'udp');
315+
316+
// test-url
317+
result.appendIfPresent(`,test-url=${proxy['test-url']}`, 'test-url');
318+
result.appendIfPresent(
319+
`,test-timeout=${proxy['test-timeout']}`,
320+
'test-timeout',
321+
);
322+
result.appendIfPresent(`,test-udp=${proxy['test-udp']}`, 'test-udp');
323+
result.appendIfPresent(`,hybrid=${proxy['hybrid']}`, 'hybrid');
324+
result.appendIfPresent(`,tos=${proxy['tos']}`, 'tos');
325+
result.appendIfPresent(
326+
`,allow-other-interface=${proxy['allow-other-interface']}`,
327+
'allow-other-interface',
328+
);
329+
result.appendIfPresent(
330+
`,interface=${proxy['interface-name']}`,
331+
'interface-name',
332+
);
333+
334+
// block-quic
335+
result.appendIfPresent(`,block-quic=${proxy['block-quic']}`, 'block-quic');
336+
337+
// underlying-proxy
338+
result.appendIfPresent(
339+
`,underlying-proxy=${proxy['underlying-proxy']}`,
340+
'underlying-proxy',
341+
);
342+
343+
// reuse
344+
result.appendIfPresent(`,reuse=${proxy['reuse']}`, 'reuse');
345+
346+
return result.toString();
347+
}
348+
281349
function vmess(proxy, includeUnsupportedProxy) {
282350
const result = new Result(proxy);
283351
result.append(`${proxy.name}=${proxy.type},${proxy.server},${proxy.port}`);

backend/src/core/proxy-utils/producers/uri.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,14 @@ export default function URI_Producer() {
139139
}
140140
}
141141
if (
142-
['trojan', 'tuic', 'hysteria', 'hysteria2', 'juicity'].includes(
143-
proxy.type,
144-
)
142+
[
143+
'trojan',
144+
'tuic',
145+
'hysteria',
146+
'hysteria2',
147+
'juicity',
148+
'anytls',
149+
].includes(proxy.type)
145150
) {
146151
delete proxy.tls;
147152
}

backend/src/utils/user-agent.js

Lines changed: 39 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -60,42 +60,45 @@ export function getPlatformFromHeaders(headers) {
6060
const { UA, ua, accept } = getUserAgentFromHeaders(headers);
6161
return getPlatformFromUserAgent({ ua, UA, accept });
6262
}
63+
6364
export function shouldIncludeUnsupportedProxy(platform, ua) {
64-
// try {
65-
// const target = getPlatformFromUserAgent({
66-
// UA: ua,
67-
// ua: ua.toLowerCase(),
68-
// });
69-
// if (!['Egern'].includes(target)) {
70-
// return false;
71-
// }
72-
// const coerceVersion = coerce(ua);
73-
// $.log(JSON.stringify(coerceVersion, null, 2));
74-
// const { version } = coerceVersion;
75-
// // if (
76-
// // platform === 'Stash' &&
77-
// // target === 'Stash' &&
78-
// // gte(version, '3.1.0')
79-
// // ) {
80-
// // return true;
81-
// // }
82-
// if (
83-
// platform === 'Egern' &&
84-
// target === 'Egern' &&
85-
// gte(version, '2.7.0')
86-
// ) {
87-
// return true;
88-
// }
89-
// // Loon 的 UA 不规范, version 取出来是 build
90-
// // if (
91-
// // platform === 'Loon' &&
92-
// // target === 'Loon' &&
93-
// // gte(version, '842.0.0')
94-
// // ) {
95-
// // return true;
96-
// // }
97-
// } catch (e) {
98-
// $.error(`获取版本号失败: ${e}`);
99-
// }
65+
try {
66+
const target = getPlatformFromUserAgent({
67+
UA: ua,
68+
ua: ua.toLowerCase(),
69+
});
70+
const coerceVersion = coerce(ua);
71+
const { major } = coerceVersion;
72+
if (
73+
(target === 'SurgeMac' && major >= 9860) ||
74+
(target === 'Surge' && major >= 3613)
75+
) {
76+
return true;
77+
}
78+
// // if (
79+
// // platform === 'Stash' &&
80+
// // target === 'Stash' &&
81+
// // gte(version, '3.1.0')
82+
// // ) {
83+
// // return true;
84+
// // }
85+
// if (
86+
// platform === 'Egern' &&
87+
// target === 'Egern' &&
88+
// gte(version, '2.7.0')
89+
// ) {
90+
// return true;
91+
// }
92+
// // Loon 的 UA 不规范, version 取出来是 build
93+
// // if (
94+
// // platform === 'Loon' &&
95+
// // target === 'Loon' &&
96+
// // gte(version, '842.0.0')
97+
// // ) {
98+
// // return true;
99+
// // }
100+
} catch (e) {
101+
// $.error(`获取版本号失败: ${e}`);
102+
}
100103
return false;
101104
}

0 commit comments

Comments
 (0)