Surge for Mac – 设置部分域名使用系统 DNS

4 min


在局域网中架设了一些服务,需要实现同一个域名,在局域网中的设备的访问时解析到局域网的服务器地址,外网则解析到经过内网穿透的公网服务器地址。

因此在局域网中架设了一个 AdGuard Home 服务器,在实现广告隐私过滤的基础上设置了对应的重写规则,并将路由器 DHCP 下发的 DNS 地址改为 AdGuard Home 的地址。

由于其他局域网设备都是使用的 Openwrt 的透明代理,因此之前一切都十分正常,直到一台 MacBook 的加入。

MacBook 使用的是 Surge,并且进入了增强模式,因此 Surge 会使用 Fake-IP 模式,并接管系统的所有 DNS 解析,导致 AdGuard Home DNS 无法生效。

关于代理环境下 DNS 解析的详情,可以阅读 浅谈在代理环境中的 DNS 解析行为 | Sukka’s Blog

尝试解决

翻阅 Surge 的文文件,发现它提供了一个 Assigning DNS Server 的功能,通过 hostname = server:dns-server 来指定指定域名的 DNS 服务器。

[Host]
exaple.com = server:8.8.8.8
*.exaple.com = server:system

参照上例,为需要的域名指定 server:system,但是发现进入增强模式后,依然交给了 Surge 配置中的 DoH 服务器来解析,并没有回落到系统解析。

通过 cat /etc/resolv.conf 查看系统的 DNS 服务器,发现系统的 DNS 服务器在进入增强模式后被设置为了 198.18.0.2,因此代理请求依然被 Surge 接管。

在社区中搜索到 mac 进入 doh 后,在增强模式下:host 模块 指定 syslib 的域名还是走的 doh – Surge Tech Community,开发组回复 「设计如此,增强模式下 syslib 无效,会导致回环查询」。既然是特性,那就只能寻找新的解决方案了。

使用 Script

Surge 提供了很强的脚本功能,可以处理 DNS 请求,因此就可以用脚本来对 DNS 做处理。参考 dns.js,使用以下脚本进行了处理:

var hostname = $domain;
// 这些网络下使用路由器下发的 DNS
var ssids = [
 'SSID1',
 'SSID2'
];
// 如果路由器提供的 DNS 包括这些 DNS, 就使用路由器下发的 DNS
var dnss = [
 '192.168.1.11',
];
ssids = '^(' + ssids.join('|') + ')

将文件保存到配置目录中,例如文件名为 system-dns.js,配置文件对应修改:

[Host]
example.com = script:system-dns
*.example.com = script:system-dns
[Script]
system-dns = type=dns,script-path=system-dns.js

即可实现 在指定网络下 或者 存在指定的 DNS 服务器 时,对 指定域名 使用路由器下发的 DNS

简单版

如果没有网络环境的要求,还可以直接将脚本写为:

$done({ servers: $network.dns })

在配置文件中设置 script:system-dns 为指定域名使用代理,这样指定的域名就会永远使用上游网络下发的 DNS 了。

所参考的 原脚本 实现了更复杂的功能,逻辑是 在指定网络下 或者 存在指定 DNS 服务器时,或者域名匹配到规则时,均使用上游 DNS,有需求可以参考。


Like it? Share with your friends!

0
Anonymous

Choose A Format
Story
Formatted Text with Embeds and Visuals
List
The Classic Internet Listicles
Countdown
The Classic Internet Countdowns
Open List
Submit your own item and vote up for the best submission
Ranked List
Upvote or downvote to decide the best list item
Video
Youtube and Vimeo Embeds