基于 Surge 的 DNS 优化指南
要获得良好的网络冲浪体验,DNS 设置是至关重要的。本文主要介绍如何使用 Surge 来提高 DNS 隐私和安全性,特别是在复杂的网络环境下,并分享一些经验,其中的原理也可以应用到诸如 Clash、Shadowrocket、Quantumult X 之类的软件。
Host 配置
Host 配置决定了你访问一个域名时 surge 如何解析这个域名的 DNS 记录,想获得高效安全的 DNS 解析体验,首先需要先根据你所处的网络环境配置合适的 Host 规则,先看一个配置示例:
[Host]
local.example.net = 127.0.0.1
local.xxx.net = 1.1.1.1
*xxxx-inc.com = server:system
*example*.com = server:system
*.* = server:https://223.6.6.6/dns-query
各种规则可以总结归类为三个梯队,优先级从上到下:
- 本地开发测试域名:直接将域名绑定到指定 IP
- 企业内部域名:用系统 DNS 解析(server:system),以保障可用性
- 公网域名:排除上述两种之后,剩下的就是一些公网域名了,可以考虑用 DNS Over HTTPS 或脚本自定义解析
需要注意的是,如果遇到配置了 /etc/hosts 不生效,可以检查对应域名是否在 surge 配置里指定了其他服务器解析,有时候会导致冲突。解决方案:
- 可以把 /etc/hosts 里的内容挪到 surge 配置里
- 或者关闭系统代理,只开启增强模式
- 也可以使用 skip-proxy 配置项将对应域名加进去,这样就不走系统代理了
- 如果在命令行里声明了
http_proxy之类的变量,执行 curl 的时候需要指定--noproxy '*'参数避免将请求发送给 Surge
希望后续 surge 能优化这个点,提供更直观的配置。
减少本地 DNS 解析
对于希望走代理的请求,应该尽量避免它们在本地触发 DNS 解析,最好将你常用的需要代理的网站加到 surge 的规则列表中,例如:
[Rule]
DOMAIN-SUFFIX,google.com,📡 Proxy
DOMAIN-SUFFIX,x.com,📡 Proxy
如果你有大量域名需要代理,可以使用 Surge 提供的 rule-set 或者 domain-set 将这些规则和域名维护到单独的文件中,通过 URL 来引用和自动更新,例如:
# 自定义代理域名
RULE-SET,https://ruleset.example.com/proxy.txt,📡 Proxy
# GitHub 项目维护的代理域名
DOMAIN-SET,https://cdn.jsdelivr.net/gh/Loyalsoldier/surge-rules@release/proxy.txt,📡 Proxy
按照上述设置后,访问这些域名将不会在本地触发 DNS 解析,请求会直接发送到代理服务器,由它负责 DNS 解析,这样既可以提升隐私也可以获得更好的 DNS 解析结果。
好的 surge 配置应该尽量避免在前面的规则触发 DNS 解析,将需要触发 DNS 的规则尽量放置的末尾,下面是一个示例:
DOMAIN-SUFFIX,github.com,📡 Proxy
PROCESS-NAME,go-ipfs*,📡 Proxy
USER-AGENT,Figma,📡 Proxy
IP-CIDR,66.197.128.0/17,📡 Proxy,no-resolve
IP-CIDR,23.246.0.0/12,DIRECT
RULE-SET,LAN,DIRECT
GEOIP,CN,DIRECT
- 域名、UA、ProcessName 等不需要触发 DNS 解析的规则放第一梯队
- 包含 no-resolve 参数的规则不会触发 DNS 解析,可以放第二梯队,
- 最后是 IP-CIDR、LAN、GEOIP 这些必须触发 DNS 解析的规则
解决 Surge 增强模式和企业 VPN 冲突
很多大型企业内部都有自己研发的 VPN 客户端(基于 TUN 模式),当你在公司外通过企业 VPN 访问内部域名通常需要特殊设定优化才能避免和 Surge 冲突。
本文接下来使用 10.x.x.x 作为企业内网 DNS IP 示例。
[General]
# 10.x.x.x 换成企业内网的固定 DNS 服务器(如果有的话)用于兜底
dns-server = system, 10.x.x.x
# 企业内部域名确保返回真实的 IP,这样才能被企业 VPN 的 TUN 路由表匹配到。
always-real-ip = %INSERT% *.your-corp.com
[Host]
# 将内网 DNS 管理的 zone 直接指定用内网 DNS 服务器解析
*your-corp.com = server:10.x.x.x
注意:尽量避免使用 surge 的 tun-excluded-routes 配置,如果你把公司内网IP段加入到这个配置,有可能引发和企业 VPN 的冲突或者各种兼容性问题。
例如 10.x.x.x 是你的企业内网 DNS IP,如果你将其加到 surge 的 tun-excluded-routes 配置里:
tun-excluded-routes = 10.x.x.x/32
重启 surge 后,查看路由表就会发现这个 IP 被 surge 又插入了一遍,你再 ping 这个 IP 就发现 ping 不通了(即使开了企业 VPN),因为此时它是走 192.168.10.1 这个家庭网关出口的自然访问不通了。
netstat -rn -f inet | grep 10.x
10.x.x.x 192.168.10.1 UGHS en0
10.x.x.x/32 10.2.x.x UGSc utun5
下面是一些辅助命令,如果配置过程遇到问题可以结合这些命令排查。
确定内网 DNS 服务器,可以使用下面的命令:(先关闭 surge 增强模式。)
scutil --dns
DNS configuration (for scoped queries)
resolver #1
search domain[0] : router.home
nameserver[0] : 10.x.x.x
if_index : 15 (en0)
flags : Scoped, Request A records
reach : 0x00020002 (Reachable,Directly Reachable Address)
resolver #2
nameserver[0] : 198.18.0.2
if_index : 38 (utun4)
flags : Scoped, Request A records
reach : 0x00000002 (Reachable)
找到上面 nameserver[0] 后面的 IP,用 dig 测试能否解析内网域名:
dig your-corp.com @10.x.x.x
找到可以解析出正确 IP 的那个 namesever 就是内网 DNS 服务器。当然一般内网都有固定的 IP 段,可以辅助判断。
开启企业 VPN 之后可以通过以下命令查看哪些 IP 段会走企业 VPN 出口:
netstat -rn -f inet
下面示例中,10.2.x.x 就是企业VPN的网关地址,10.x.x.x/32,9.x.x.x/32 这些 IP 段是企业内网IP。
Routing tables
Internet:
Destination Gateway Flags Netif Expire
default link#38 UCSg utun4
default 192.168.10.1 UGScIg en0
8.x.x.x/28 10.2.x.x UGSc utun5
9.x.x.x/32 10.2.x.x UGSc utun5
10.x.x.x/32 10.2.x.x UGSc utun5
查看所有的 TUN 设备:
ifconfig | grep -B3 -A5 utun
更多参考
本文原载于:baiyun.me