From 800b16a7c48d34e6d964c75f3ae914f8217dfc82 Mon Sep 17 00:00:00 2001 From: SukkaW Date: Mon, 15 Dec 2025 16:30:30 +0800 Subject: [PATCH] Fix: opt-in Surge DNS's special handling for `.local` --- ...c-direct-lan-ruleset-dns-mapping-module.ts | 12 ++++++++++-- Source/non_ip/direct.ts | 19 +++++++++++++++++-- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/Build/build-domestic-direct-lan-ruleset-dns-mapping-module.ts b/Build/build-domestic-direct-lan-ruleset-dns-mapping-module.ts index 9def7cf6..9ec77851 100644 --- a/Build/build-domestic-direct-lan-ruleset-dns-mapping-module.ts +++ b/Build/build-domestic-direct-lan-ruleset-dns-mapping-module.ts @@ -233,7 +233,9 @@ export const buildDomesticRuleset = task(require.main === module, __filename)(as const ruleset_name = cur[0].toLowerCase(); const mihomo_ruleset_id = `mihomo_nameserver_policy_${ruleset_name}`; - acc.dns['nameserver-policy'][`rule-set:${mihomo_ruleset_id}`] = dns; + if (dns) { + acc.dns['nameserver-policy'][`rule-set:${mihomo_ruleset_id}`] = dns; + } acc['rule-providers'][mihomo_ruleset_id] = { type: 'http', @@ -257,7 +259,9 @@ export const buildDomesticRuleset = task(require.main === module, __filename)(as break; } - acc.dns['nameserver-policy'][domain] = dns; + if (dns) { + acc.dns['nameserver-policy'][domain] = dns; + } }); } @@ -297,6 +301,10 @@ export const buildDomesticRuleset = task(require.main === module, __filename)(as 'https://doh.pub/dns-query', '[//]udp://10.10.1.1:53', ...(([DOMESTICS, DIRECTS, LAN, HOSTS] as const).flatMap(Object.values) as DNSMapping[]).flatMap(({ domains, dns: _dns }) => domains.flatMap((domain) => { + if (!_dns) { + return []; + } + let dns; if (_dns in AdGuardHomeDNSMapping) { dns = AdGuardHomeDNSMapping[_dns as keyof typeof AdGuardHomeDNSMapping].join(' '); diff --git a/Source/non_ip/direct.ts b/Source/non_ip/direct.ts index 19555196..44cfceea 100644 --- a/Source/non_ip/direct.ts +++ b/Source/non_ip/direct.ts @@ -6,7 +6,7 @@ export interface DNSMapping { realip: boolean, /** should convert to ruleset */ ruleset: boolean, - dns: string, + dns: string | null, /** * domain[0] * @@ -47,6 +47,18 @@ export const DIRECTS = { } as const satisfies Record; export const LAN = { + // By default, all hostnames with the suffix '.local' will be resolved by the system. + // Some app like OrbStack uses mDNS and this TLD (orb.local) via mDNS. + // Surge already handles .local with mDNS properly, we should not map to server:system + LOCAL_SPECIAL: { + dns: null, + hosts: {}, + realip: false, + ruleset: false, + domains: [ + '+local' + ] + }, LAN_WITHOUT_REAL_IP: { dns: 'system', hosts: { @@ -139,7 +151,10 @@ export const LAN = { ruleset: true, domains: [ '+lan', - '+local', + // By default, all hostnames with the suffix '.local' will be resolved by the system. + // Some app like OrbStack uses mDNS and this TLD (orb.local) via mDNS. + // Surge already handles .local with mDNS properly, we should not map to server:system + // '+local', '+internal', // 'amplifi.lan', // '$localhost',