Add Mac client mode and simplify local proxy UI

This commit is contained in:
2026-05-19 13:12:39 +03:00
parent 2ef1e09986
commit d02dbe10de
22 changed files with 924 additions and 70 deletions

View File

@@ -202,7 +202,7 @@ function ruDirectRule() {
};
}
function routeRules(customRules, vpnTag) {
function routeRules(customRules, vpnTag, { includeTransparent = true } = {}) {
const deviceProfiles = readDeviceProfiles();
const rules = [
{
@@ -217,8 +217,10 @@ function routeRules(customRules, vpnTag) {
const ruRule = ruDirectRule();
if (ruRule) rules.push(ruRule);
// Device defaults are only transparent-gateway fallbacks after global rules.
rules.push(...deviceDefaultRouteRules(deviceProfiles.devices, vpnTag));
if (includeTransparent) {
// Device defaults are only transparent-gateway fallbacks after global rules.
rules.push(...deviceDefaultRouteRules(deviceProfiles.devices, vpnTag));
}
const proxyFallback = inboundDefaultRule(
MIXED_INBOUND,
@@ -227,12 +229,14 @@ function routeRules(customRules, vpnTag) {
);
if (proxyFallback) rules.push(proxyFallback);
const transparentFallback = inboundDefaultRule(
TPROXY_INBOUND,
deviceProfiles.defaultTransparentMode,
vpnTag,
);
if (transparentFallback) rules.push(transparentFallback);
if (includeTransparent) {
const transparentFallback = inboundDefaultRule(
TPROXY_INBOUND,
deviceProfiles.defaultTransparentMode,
vpnTag,
);
if (transparentFallback) rules.push(transparentFallback);
}
return rules;
}
@@ -254,6 +258,30 @@ export function buildGatewayConfig(
}
const customRuleSets = readCustomRuleSets();
const clientMode = settings.appMode === "client";
const proxyOnlyRules = [{ inbound: [MIXED_INBOUND], outbound: vpnOutbound.tag }];
const inbounds = [
...(clientMode
? []
: [
{
type: "tproxy",
tag: "tproxy-in",
listen: "::",
listen_port: settings.tproxyPort,
sniff: true,
sniff_override_destination: true,
},
]),
{
type: "mixed",
tag: "mixed-in",
listen: settings.bindIp,
listen_port: settings.proxyPort,
sniff: true,
set_system_proxy: false,
},
];
return {
log: {
@@ -269,34 +297,21 @@ export function buildGatewayConfig(
dns: {
independent_cache: true,
},
inbounds: [
{
type: "tproxy",
tag: "tproxy-in",
listen: "::",
listen_port: settings.tproxyPort,
sniff: true,
sniff_override_destination: true,
},
{
type: "mixed",
tag: "mixed-in",
listen: settings.bindIp,
listen_port: settings.proxyPort,
sniff: true,
set_system_proxy: false,
},
],
inbounds,
outbounds: [
vpnOutbound,
{ type: "direct", tag: "direct" },
{ type: "block", tag: "block" },
],
route: {
rule_set: bypassAll ? [] : ruleSets(customRuleSets, vpnOutbound.tag),
rule_set: bypassAll || clientMode ? [] : ruleSets(customRuleSets, vpnOutbound.tag),
rules: bypassAll
? [{ ip_is_private: true, outbound: "direct" }]
: routeRules(subscriptionConfig.customRules, vpnOutbound.tag),
: clientMode
? proxyOnlyRules
: routeRules(subscriptionConfig.customRules, vpnOutbound.tag, {
includeTransparent: !clientMode,
}),
final: "direct",
auto_detect_interface: true,
},