11 月快要过去了,这个月研究了下 android 的 DOT,手写了个 DOT 实现,方便验证 android 的 DoT 行为
先说结论:
1 、DoT 是可以使用自签名证书的,并不是说非的需要一个正式的 HTTPS 证书。
2 、当选择自动模式的时候,代码实现上自动检测当前 DNS 服务器是否支持 TLS,并且 TLS 查询延迟不是比 UDP 差的多时候会自动选择 DOT,否则是 UDP 。所以自动模式下,如果当前的 DNS 服务器不支持 UDP ,只支持 TLS,手机也是能正常工作的。
3 、选择第三方 Dot 服务器,必须填域名,并且服务器的证书需要是正式签名的 HTTPS 证书。
Android 手机上的 Vpn 服务,默认需要 dns 跟地址都存在的才运行使用这个协议栈,所以理论上需要配置一个 ipv4 格式的地址一个 iPv4 格式的 DNS 服务器, 然后配置一个 ipv6 格式的地址加上一个 ipv6 格式的 DNS 服务器,才会双栈同时工作。当然了,也可以通过 VpnService.Builder.allowFamily 来关闭这个默认行为。
android DNS 解析器需要有缺省的路由才会解释对应协议栈的记录。所以手机连着只有 IPv4 的 Wifi ,然后建立 VpnService 是没有配置全局单播路由 2000::/3 那么,手机不会查询 AAAA 记录,也就是无法访问 IPv6 网络(即使你配置了部分的 ipv6 路由)。
所以, 如果 Vpn 的承载网络是 IPv4 单栈( wlan 或者蜂窝网络),需要在 VpnService.Builder 中添加 2000::/3 路由。
64:ff9b::/96 是默认的 NAT64 前缀,
dns64.dns.google (2001:4860:4860::64,2001:4860:4860::6464) 支持返回 NAT64 的记录。不过它是没有 ipv6 记录情况下才会返回 NAT64 地址。所以这里实现,可以修改 pref 的配置,选择优先返回 NAT64 的地址。
这里实现,会有两个个上游 DNS 服务器,223.5.5.5 ,8.8.8.8 ,只返回 pref 高的记录
默认的 pref 顺序:
1 从 223.5.5.5 返回的并且是国内 IPv4 地址,最高优先级。
2 从 8.8.8.8 返回的 NAT64 记录。
3 从 8.8.8.8 返回的 ipv4 记录, 优先级跟 2 同。
4 从 8.8.8.8 返回的 IPv6 记录。
5 从 223.5.5.5 返回的 IPv6 记录。
所以只需要把 64:ff9b::/96 地址段选择正确的路由即可。不过就是需要本地网络开启双栈(不一定一定要全局 ipv6 地址)。
实现:
https://github.com/pagxir/dns-resolver-ng测试地址 (因为 ECH facing server 只配置了 v6 网络,使用时需要 IPv6 网络,否则有问题):
https://test.855899.xyz/dns-query