diff --git a/backend/package.json b/backend/package.json index 63a4fd0a2..f609054d1 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "sub-store", - "version": "2.14.27", + "version": "2.14.28", "description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.", "main": "src/main.js", "scripts": { diff --git a/backend/src/core/proxy-utils/parsers/index.js b/backend/src/core/proxy-utils/parsers/index.js index 780479306..5d8627dde 100644 --- a/backend/src/core/proxy-utils/parsers/index.js +++ b/backend/src/core/proxy-utils/parsers/index.js @@ -345,6 +345,7 @@ function Clash_All() { 'tuic', 'vless', 'hysteria', + 'wireguard', ].includes(proxy.type) ) { throw new Error( diff --git a/backend/src/core/proxy-utils/producers/clash.js b/backend/src/core/proxy-utils/producers/clash.js index 9cac0e55d..fc6d34a73 100644 --- a/backend/src/core/proxy-utils/producers/clash.js +++ b/backend/src/core/proxy-utils/producers/clash.js @@ -14,6 +14,7 @@ export default function Clash_Producer() { 'http', 'snell', 'trojan', + 'wireguard', ].includes(proxy.type) ) { return false; @@ -53,6 +54,10 @@ export default function Clash_Producer() { ) { proxy.cipher = 'auto'; } + } else if (proxy.type === 'wireguard') { + proxy.keepalive = + proxy.keepalive ?? proxy['persistent-keepalive']; + proxy['persistent-keepalive'] = proxy.keepalive; } if ( diff --git a/backend/src/core/proxy-utils/producers/loon.js b/backend/src/core/proxy-utils/producers/loon.js index 86489f5e6..0e77db4a3 100644 --- a/backend/src/core/proxy-utils/producers/loon.js +++ b/backend/src/core/proxy-utils/producers/loon.js @@ -1,6 +1,7 @@ /* eslint-disable no-case-declarations */ const targetPlatform = 'Loon'; import { isPresent, Result } from './utils'; +import { isIPv4, isIPv6 } from '@/utils'; export default function Loon_Producer() { const produce = (proxy) => { @@ -17,6 +18,8 @@ export default function Loon_Producer() { return vless(proxy); case 'http': return http(proxy); + case 'wireguard': + return wireguard(proxy); } throw new Error( `Platform ${targetPlatform} does not support proxy type: ${proxy.type}`, @@ -271,3 +274,63 @@ function http(proxy) { result.appendIfPresent(`,udp-relay=${proxy.udp}`, 'udp'); return result.toString(); } + +function wireguard(proxy) { + if (Array.isArray(proxy.peers) && proxy.peers.length > 0) { + proxy.server = proxy.peers[0].server; + proxy.port = proxy.peers[0].port; + proxy.ip = proxy.peers[0].ip; + proxy.ipv6 = proxy.peers[0].ipv6; + proxy['public-key'] = proxy.peers[0]['public-key']; + proxy['pre-shared-key'] = proxy.peers[0]['pre-shared-key']; + proxy['allowed-ips'] = proxy.peers[0]['allowed_ips']; + proxy.reserved = proxy.peers[0].reserved; + } + const result = new Result(proxy); + result.append(`${proxy.name}=wireguard`); + + result.appendIfPresent(`,interface-ip=${proxy.ip}`, 'ip'); + result.appendIfPresent(`,interface-ipv6=${proxy.ipv6}`, 'ipv6'); + + result.appendIfPresent( + `,private-key="${proxy['private-key']}"`, + 'private-key', + ); + result.appendIfPresent(`,mtu=${proxy.mtu}`, 'mtu'); + + if (proxy.dns) { + if (Array.isArray(proxy.dns)) { + proxy.dnsv6 = proxy.dns.find((i) => isIPv6(i)); + proxy.dns = proxy.dns.find((i) => isIPv4(i)); + } + } + result.appendIfPresent(`,dns=${proxy.dns}`, 'dns'); + result.appendIfPresent(`,dnsv6=${proxy.dnsv6}`, 'dnsv6'); + result.appendIfPresent( + `,keepalive=${proxy['persistent-keepalive']}`, + 'persistent-keepalive', + ); + result.appendIfPresent(`,keepalive=${proxy.keepalive}`, 'keepalive'); + const allowedIps = Array.isArray(proxy['allowed-ips']) + ? proxy['allowed-ips'].join(',') + : proxy['allowed-ips']; + let reserved = Array.isArray(proxy.reserved) + ? proxy.reserved.join(',') + : proxy.reserved; + if (reserved) { + reserved = `,reserved=[${reserved}]`; + } + let presharedKey = proxy['pre-shared-key']; + if (presharedKey) { + presharedKey = `,preshared-key="${presharedKey}"`; + } + result.append( + `,peers=[{public-key="${proxy['public-key']}",allowed-ips="${ + allowedIps || '0.0.0.0/0,::/0' + }",endpoint=${proxy.server}:${proxy.port}${reserved ?? ''}${ + presharedKey ?? '' + }}]`, + ); + + return result.toString(); +} diff --git a/backend/src/core/proxy-utils/producers/shadowrocket.js b/backend/src/core/proxy-utils/producers/shadowrocket.js index 5ae7bdfba..b7e4bfd79 100644 --- a/backend/src/core/proxy-utils/producers/shadowrocket.js +++ b/backend/src/core/proxy-utils/producers/shadowrocket.js @@ -74,6 +74,10 @@ export default function Stash_Producer() { ) { proxy['fast-open'] = proxy.tfo; } + } else if (proxy.type === 'wireguard') { + proxy.keepalive = + proxy.keepalive ?? proxy['persistent-keepalive']; + proxy['persistent-keepalive'] = proxy.keepalive; } if ( diff --git a/backend/src/core/proxy-utils/producers/stash.js b/backend/src/core/proxy-utils/producers/stash.js index bce823166..a742325af 100644 --- a/backend/src/core/proxy-utils/producers/stash.js +++ b/backend/src/core/proxy-utils/producers/stash.js @@ -18,6 +18,7 @@ export default function Stash_Producer() { 'trojan', 'tuic', 'vless', + 'wireguard', ].includes(proxy.type) || (proxy.type === 'snell' && String(proxy.version) === '4') || @@ -86,6 +87,10 @@ export default function Stash_Producer() { ) { proxy['fast-open'] = proxy.tfo; } + } else if (proxy.type === 'wireguard') { + proxy.keepalive = + proxy.keepalive ?? proxy['persistent-keepalive']; + proxy['persistent-keepalive'] = proxy.keepalive; } if (