最近折腾 Moto Edge 60 Pro (XT2507-5 ,国行) 时,发现连接任意 WiFi 系统都会强制追加 114 DNS (不管 DHCP 下发了一个还是两个 DNS ,亦或使用静态 IP 手填 DNS 都免不了),这直接破坏了我在 OpenWrt 上的 ADG 和 Mosdns 策略。
经过一番排查和实验,总结出这些应对方法。
路由器有控制权
- 在 OpenWrt 上,对来自手机的 MAC 地址的 114 DNS 请求全部 DNAT 到网关本身
iptables -t nat -A prerouting_lan_rule -m mac --mac-source <手机 MAC> -p udp -d 114.114.114.114 --dport 53 -j DNAT --to-destination 192.168.X.1
iptables -t nat -A prerouting_lan_rule -m mac --mac-source <手机 MAC> -p tcp -d 114.114.114.114 --dport 53 -j DNAT --to-destination 192.168.X.1
(最无感
手机无 root
- 使用私人 DNS
- 使用 VPN 接管 DNS
(不喜欢 VPN 通道被占用
手机已 root
一开始以为是 overlay 配置,结果 cmd overlay 验证并不涉及 DNS 。 抓 dumpsys connectivity ,确认是 ClientModeImpl 里往 LinkProperties 里强加的。 最终在 /apex/com.android.wifi/javalib/service-wifi.jar 找到关键方法:addBackupDnsServerIfNeeded()。
- iptables 丢弃
(治标
iptables -I OUTPUT -d 114.114.114.114 -p udp --dport 53 -j REJECT
iptables -I OUTPUT -d 114.114.114.114 -p tcp --dport 53 -j REJECT
- 反编译 service-wifi.jar 或者 hook ClientModeImpl 让 addBackupDnsServerIfNeeded() 返回空
(治本
罪魁祸首↓
private void addBackupDnsServerIfNeeded() {
Iterator<InetAddress> it = this.mLinkProperties.getDnsServers().iterator();
int i = 0;
while (it.hasNext()) {
if (it.next() instanceof Inet4Address) {
i++;
}
}
if (i == 1) {
try {
this.mLinkProperties.addDnsServer(InetAddress.getByName("114.114.114.114"));
} catch (UnknownHostException unused) {
if (this.mVerboseLoggingEnabled) {
log("Adding 114 DNS Server Fails");
}
}
}
}
吐槽
AOSP 已经有 Fallback 机制了,在无任何可用 DNS 时才会追加 8.8.8.8 。 小米、一加、Moto 搞这种骚操作,看似提升了小白的网络体验,实际上剥夺了用户选择权,都是傻*


