症状#

小鸡上随手跑了个 apt update,结果很诡异:只有一个源报错,其他源全正常。

Err:1 http://mirrors.tencentyun.com/ubuntu jammy InRelease
Could not resolve 'mirrors.tencentyun.com'

换成 archive.ubuntu.com、mirrors.aliyun.com 之类的公网源,或者去 ping 别的东西,一切正常。也就是说网络是通的,只有这一个内网镜像域名解析不了。

根因#

本机跑着 mihomo,开了 TUN 模式。TUN 一开,它会接管本机所有的 :53 请求——你写在 /etc/resolv.conf 里的 DNS 根本不会被用到,实际查询统一交给 mihomo 配置里的上游 DNS,而我的上游全是公网 DNS(DoH、1.1.1.1)。

问题就出在这里:mirrors.tencentyun.com 是腾讯云内网专属的镜像域名,它只能由 VPC 内部 DNS 解析:

183.60.83.19 / 183.60.82.98

拿 1.1.1.1 去问一个只在内网存在的域名,结果可想而知——公网 DNS 根本不认识它,直接解析失败。

踩的第一个坑:fake-ip-filter 不管用#

第一反应是「既然走了 fake-ip,把这个域名排除掉不就行了」,于是往 fake-ip-filter 里加:

dns:
fake-ip-filter:
- 'mirrors.tencentyun.com'

不管用。

原因很简单:fake-ip-filter 只决定「这个域名要不要返回假 IP」,它管的是返回什么地址,压根不决定用哪个上游 DNS 去查。域名该发给 1.1.1.1 还是发给别的上游,跟这个开关没半点关系。

正解:nameserver-policy 显式指定上游#

真正要改的是「谁来解析这个域名」。补上 nameserver-policy,把它指回 VPC DNS:

dns:
nameserver-policy:
'+.mirrors.tencentyun.com': ['183.60.83.19', '183.60.82.98']
# 其它内网域名同理,按需追加

热重载之后验证一下:

Terminal window
$ dig +short mirrors.tencentyun.com
169.254.0.3

169.254.0.3 是 mihomo 发给应用的 fake-ip(真实解析已经在 VPC DNS 那边完成,连接时由 TUN 层还原成真实地址),不影响使用。

再跑一次 apt update,秒恢复。

教训#

  • TUN 模式下 DHCP 下发的内网 DNS 形同虚设。 系统所有 :53 都被 mihomo 接管了,你把 VPC DNS 写在 resolv.conf 里也白搭。
  • 内网域名必须显式配解析策略。 不管是腾讯云的 mirrors.tencentyun.com,还是企业内网、私有服务的域名,只要它只有内网 DNS 认识,就得用 nameserver-policy 把上游指回内网 DNS,否则一律按公网查,必然失败。
  • 分清 fake-ip-filter 和 nameserver-policy 的分工:
    • fake-ip-filter —— 决定「返回真 IP 还是假 IP」;
    • nameserver-policy —— 决定「用哪个上游 DNS 去解析」。
    • DNS 解析不通的问题,要改的通常是后者。

一个小配置项的错位,折腾了大半天。记下来,给后来的自己踩坑用。