macOS 无法在图形界面中直接配置 DNS 转发规则,但可通过 dnsmasq 代理或 /etc/resolver 实现:前者支持域名条件转发,需设系统 DNS 为 127.0.0.1 并配置规则;后者为原生静态映射,仅对指定域名生效,优先级低于 dnsmasq。

macOS 本身不支持图形界面或系统设置中直接配置“DNS 转发规则”(比如把 corp.internal 的查询固定发给 10.0.0.5,其余走公共 DNS),但可通过本地 DNS 代理实现等效功能。核心思路是:让系统所有 DNS 查询先发到本机(127.0.0.1),再由代理按域名条件转发——这比修改全局 DNS 或依赖网络层更精准、更可控。
用 dnsmasq 实现域名级转发
dnsmasq 是最轻量、稳定且 macOS 兼容性最好的方案,适合多数场景:
- 安装后启动服务:
brew install dnsmasq && sudo brew services start dnsmasq - 编辑配置文件
/opt/homebrew/etc/dnsmasq.conf,添加转发规则,例如:server=/corp.internal/10.0.0.5server=/dev.example.com/192.168.1.100
每行一个域名后缀,匹配时精确到子域(api.corp.internal也会走10.0.0.5) - 确保 dnsmasq 绑定本地端口:
bind-interfaces和address=/#/127.0.0.1(可选,用于拦截全部请求) - 系统 DNS 设为
127.0.0.1(在“系统设置 > 网络 > 详细信息 > DNS”中设置并置顶) - 改完必须刷新缓存:
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
用 /etc/resolver 实现静态域名映射
这是 macOS 原生支持的机制,无需代理服务,但仅限指定 DNS 服务器,不支持条件转发逻辑:
- 为每个目标域名建独立文件:
sudo tee /etc/resolver/corp.internal <<< "nameserver 10.0.0.5" - 文件名必须与域名完全一致(支持通配符如
sudo touch /etc/resolver/.internal,但 macOS 13+ 对点开头的文件支持不稳定,建议用完整域名) - 权限必须为
root:wheel且不可被 group/o 写:sudo chmod 644 /etc/resolver/corp.internal - 该方式只影响对应域名解析,其他域名仍走系统 DNS 列表,无需重启服务或刷新代理
验证转发是否生效
别只看 dig example.com —— 它默认查系统 DNS,需显式指定解析器:
- 查 resolver 规则是否加载:
scutil --dns | grep -A 5 resolver - 测试域名是否命中自定义 DNS:
dig @127.0.0.1 api.corp.internal +short(dnsmasq 场景) - 或直接绕过系统缓存:
dig api.corp.internal @10.0.0.5确认上游可达 - 查看 dnsmasq 日志实时确认转发行为:
tail -f /usr/local/var/log/dnsmasq.log
注意优先级和冲突点
多个机制共存时,实际生效顺序取决于查询路径:
- /etc/resolver/ 下的文件优先级高于系统 DNS 列表,但低于 dnsmasq 这类主动监听 53 端口的代理
- 若同时启用 dnsmasq 并设系统 DNS 为
127.0.0.1,则/etc/resolver不再起作用(所有请求已被 dnsmasq 拦截) - mDNSResponder 不会读取 resolver 文件中的转发指令,它只做最终投递;真正的“转发决策”发生在 dnsmasq 或应用层(如浏览器 DoH)
- 加密 DNS(DoH/DoT)会绕过本地转发,除非你把 dnsmasq 配成唯一上游并关闭 DoH/DoT


















