在 android 上,我为了避免 DNS 污染,打算自己解析 DNS ,
使用 iptables -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to-destination 127.0.0.1:XXX ,然后程序监听本地的 XXX 端口用来处理这个 DNS 请求,但是我发现 DNS 请求会先绕到网关,然后在发回手机给我的监听,接收到 UDP DNS 请求后发现远程地址也是本机的内网 IP ,而不是 127.0.0.1 ,这在我自己家里的 WIFI 没问题,但在一些公共 WIFI 或 3G\4G 的情况下,有些网关有 DNS 缓存,会直接返回结果而不会再发送给我解析,我在本地的监听根本没有收到请求,导致一些网站 DNS 解析不正确。
我参考了 SS 后发现它也是这么做的,那它怎么处理这个问题的?
1
squid157 2016-01-13 22:35:12 +08:00 via iPhone
表不对 手机上不用 nat 表
|
2
acess 2016-01-13 22:40:35 +08:00
ss 我不知道是怎么处理的,但我记得与 Android 的 ndc 命令有关系。 Android 有自己的 DNS 缓存。
|
3
yamada OP @squid157 看过了 SS 的源码,一样是 nat 没错的,转 80 和 443 什么的没问题,连接时的远程 ip 也是 127.0.0.1
|
4
miclushine 2016-01-13 23:15:48 +08:00
安卓上 wifi 和移动数据用的不同的 dns ,每个进程都有单独的 dns 缓存。 4.3 以上的 android 如果没有魔改过 dns 部分,彻底手动改 dns 解析基本无解。
|
5
yamada OP @miclushine DNS 缓存我通过开关一次飞行模式还是能够清掉的, 4G 下在有的地方本地监听能收到 DNS 请求,而在有的地方则收不到,但是这个域名却解析成功了,所以怀疑是网关有 DNS 缓存直接返回了解析结果
|
6
yamada OP 总结一下现在的问题就是:为什么添加了 iptables , DNS 请求会先绕到网关然后在发回手机进行解析?而不是直接在本地解析?我都已经-j DNAT --to-destination 127.0.0.1:XXX 了, 80 和 443 之类的则没问题是直接就在本机被处理了
|
7
tatsuteng 2016-01-14 09:07:14 +08:00 via Android
DNAT 不会改变源地址,所以看起源地址是内网 IP
|
8
yamada OP @tatsuteng 我知道,但为什么是内网 ip 而不是 127 ?是不是说明这个 udp dns 包先绕到了网关再回到手机?
|
9
yamada OP 我做了一个这样的测试:断开 wifi ,关闭流量, ping 域名,直接显示 unknow ,并且我的监听程序没有接收到 dns udp 查询包,如果 iptables 生效了的话, dns udp 应该直接被转发到了我本地 127 上吧,但是并没有,看来还是会先发到网关再转回来?怎么直接发到本地 127 ?
|
10
tatsuteng 2016-01-14 11:47:28 +08:00 via Android
源地址是内网 IP 并不代表它会先绕到网关,因为内网 IP 和 127.0.0.1 都是本机的地址,所以 UDP 包会直接在内核中从 wlan0 发到 lo 。至于断开 wifi 和数据连接,手机就不知道谁是 DNS 服务器了吧,当然发不出了
|
11
yamada OP @tatsuteng 那我的监听为什么一直收不到 DNS 请求在 3G\4G 下……是不是因为 UDP 从 IPV6 发出去了?
|
12
tatsuteng 2016-01-14 13:15:33 +08:00 via Android
不清楚,去装个 tcpdump 抓包吧
|