macOS 通过 /etc/resolver/ 实现域名级 DNS 分流:为特定域名(如 github.com)创建对应文件,内写 nameserver,系统按最长后缀匹配生效;不支持通配符和 TLD,需 root 权限、正确权限与缓存刷新;scutil --dns 不显示该配置属正常。

用 /etc/resolver/ 文件实现域名级 DNS 分流
这是 macOS 原生支持、无需额外服务、最轻量也最常用的方式:对 example.com 这类域名,强制走你指定的 DNS(比如内网 DNS 或特定 CDN 解析节点),其他域名照常走系统默认 DNS。
它本质是让系统在 DNS 查询时「查表匹配」:只要查询的域名后缀能被 /etc/resolver/ 下某个文件名精确或通配匹配,就改用该文件里写的 nameserver。
-
必须用
sudo创建目录和文件:sudo mkdir -p /etc/resolver,否则系统直接忽略 - 文件名就是域名(不带协议、不带子域前缀):
sudo tee /etc/resolver.github.com→ 仅影响github.com及其子域(api.github.com、docs.github.com都命中) - 文件内容只有一行:
nameserver 192.168.1.100(不能写端口,不能写多个nameserver,不支持注释) - 权限必须是
root:wheel且不可被组/其他写入:sudo ls -l /etc/resolver/github.com应显示-rw-r--r--,否则 mDNSResponder 拒绝加载 - 修改后无需重启,但需刷新 DNS 缓存:
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
为什么 scutil --dns 看不到你的 resolver 配置?
这不是配置失败,而是 macOS 的 resolver 加载机制决定的:它不会把 /etc/resolver/ 下的规则“注册”进 scutil --dns 输出的 resolver 列表里,而是由 mDNSResponder 在运行时动态匹配。所以你执行 scutil --dns 看不到 github.com 对应的 resolver 条目,完全正常。
验证是否生效,别看输出,要看行为:
- 用
dig @8.8.8.8 github.com +short查公网解析结果 - 再用
dig github.com +short(不指定 @)——如果返回的是你写在/etc/resolver/github.com里的那个 DNS 返回的结果,说明已生效 - 注意:
nslookup默认不走系统 resolver 链路,优先用dig测试
通配符和子域控制的实际限制
macOS 的 /etc/resolver/ 不支持 * 或正则,但支持「最长后缀匹配」。也就是说,/etc/resolver/com 是无效的(太宽泛,系统会拒绝加载),而 /etc/resolver.example.com 和 /etc/resolver.api.example.com 是两个独立文件,后者优先级更高。
- 想覆盖所有
.dev域?不行——/etc/resolver/dev会被系统忽略(TLD 文件不被接受) - 想覆盖
a.b.example.com和c.example.com?建两个文件:/etc/resolver/b.example.com和/etc/resolver/example.com,前者更精确,优先匹配 - 文件名区分大小写:
/etc/resolver/GitHub.com≠/etc/resolver/github.com,推荐全小写 - 删除某域名规则?直接
sudo rm /etc/resolver/github.com,然后刷新缓存即可
当需要更复杂逻辑时,dnsmasq 是唯一可靠选择
如果你要:按关键词转发(如含 staging- 的域名走测试 DNS)、做 IP 白名单过滤、启用 DNSSEC 验证、或同时处理几十个不同策略的域名——/etc/resolver/ 就力不从心了。这时候必须上本地 DNS 代理。
dnsmasq 是最轻量、最可控的选择,但要注意几个硬性前提:
- 必须把系统 DNS 改成
127.0.0.1(通过网络设置或networksetup),否则 dnsmasq 根本收不到请求 - 启动前确认端口 53 未被占用:
sudo lsof -i :53,常见冲突来自 Docker Desktop 或 Parallels - 转发规则语法严格:
server=/example.com/1.1.1.1中的斜杠不能少,末尾不能有空格,否则配置静默失效 - 日志默认关闭,调试时加
log-queries和log-facility=/var/log/dnsmasq.log,再sudo touch /var/log/dnsmasq.log && sudo chmod 644 /var/log/dnsmasq.log
真正容易被忽略的点是:一旦启用 dnsmasq,所有 DNS 查询都经过它,包括系统更新、App Store、甚至某些后台服务的证书校验。任何配置错误都会导致大面积解析失败,且错误现象分散(有时只是某个 App 打不开,而不是全网断)。建议先用 dig @127.0.0.1 example.com 单独验证转发链路,再切全局 DNS。

















