@@ -32,6 +32,7 @@ import io.nekohasekai.sagernet.fmt.wireguard.WireGuardBean
3232import io.nekohasekai.sagernet.fmt.wireguard.buildSingBoxOutboundWireguardBean
3333import io.nekohasekai.sagernet.ktx.isIpAddress
3434import io.nekohasekai.sagernet.ktx.mkPort
35+ import io.nekohasekai.sagernet.ktx.runOnMainDispatcher
3536import io.nekohasekai.sagernet.utils.PackageCache
3637import moe.matsuri.nb4a.*
3738import moe.matsuri.nb4a.SingBoxOptions.*
@@ -205,8 +206,30 @@ fun buildConfig(
205206
206207 // 旧 fork 的 "hosts" DNS 地址 = 系统解析器;官方内核无此 scheme,对应 "local"
207208 // (官方 legacy 升级会把裸 "hosts" 误判为 UDP 服务器域名,静默失败)。
209+ // 仅用于 dns-direct / 订阅 resolver 等"本就应本机直解"的场景,远程 DNS 禁止走此函数。
208210 fun normalizeDnsAddress (address : String ): String = if (address == " hosts" ) " local" else address
209211
212+ // 远程 DNS 必须由节点代访问(配合下方 detour=当前节点),绝不能归一化为本机直解的 local:
213+ // 官方内核下 local/hosts/fakeip 都是本机解析占位符(Android 上 local 走平台接口经物理网卡
214+ // 直连系统 DNS),用作远程即 DNS 泄露,与 fork 时代 hosts 语义不对齐。
215+ // 统一回退为公共 DoH 并 Toast 提示用户修改设置。
216+ fun normalizeRemoteDnsAddress (address : String ): String {
217+ return when (address) {
218+ " hosts" , " local" , " localhost" , " fakeip" -> {
219+ runOnMainDispatcher {
220+ Toast .makeText(
221+ SagerNet .application,
222+ " Warning: \" $address \" is not supported as remote DNS and has been replaced with https://8.8.8.8/dns-query. Please update your remote DNS setting." ,
223+ Toast .LENGTH_LONG
224+ ).show()
225+ }
226+ " https://8.8.8.8/dns-query"
227+ }
228+
229+ else -> address
230+ }
231+ }
232+
210233 return MyOptions ().apply {
211234 if (! forTest) {
212235 experimental = ExperimentalOptions ().apply {
@@ -935,8 +958,10 @@ fun buildConfig(
935958 remoteDns.firstOrNull().let {
936959 // Always use direct DNS for urlTest
937960 if (! forTest) dns.servers.add(DNSServerOptions ().apply {
938- address = normalizeDnsAddress (it ? : throw Exception (" No remote DNS, check your settings!" ))
961+ address = normalizeRemoteDnsAddress (it ? : throw Exception (" No remote DNS, check your settings!" ))
939962 tag = " dns-remote"
963+ // 远程 DNS 交给当前节点代访问(对齐 Throne 桌面端 detour=proxy),本机直出即泄露。
964+ detour = mainProxyTag
940965 address_resolver = " dns-direct"
941966 strategy = autoDnsDomainStrategy(SingBoxOptionsUtil .domainStrategy(tag))
942967 })
0 commit comments