https://www.txthinking.com/talks/
Updated at: 2023-05-13
cloud@txthinking.com
Brook 通过虚拟 DNS 来拿到域名,进而去做一些基于域名的任务,比如用 hosts 指定 IP 等。
虚拟 DNS 的 TTL 是 60 秒,Brook 断开再重新连接会重置虚拟 DNS 数据,但是一些不遵守标准的 App 可能自己缓存超过 60 秒很久才重新查询 DNS,这样 Brook 重新连接重置虚拟 DNS 后 App 仍然尝试连接之前的虚拟 IP 就会失败,点名批评 Instagram,可以用脚本让指定域名不走虚拟 DNS。
可以看得出来,本地全程都不知道真正要连接的 IP 地址。
以上只是用最简单的流程来方便理解虚拟 DNS 是如何工作的,实际流程还有规则脚本等很多其他环节。
上面我们知道了虚拟 DNS 是通过拦截系统 UDP 53 端口来工作的,所以我们要避免应用或系统走其他方式查询域名。
Settings -> Network & internet -> Private DNS -> Off
Settings -> Network & Internet -> Your Network -> DNS settings -> Edit -> Preferred DNS -> Unencrypted only -> 8.8.8.8
继续往下看
继续往下看
Settings -> Privacy and security -> Use secure DNS -> Off
Settings -> Privacy and security -> Security -> Use secure DNS -> Off
也就是说,明明你的系统 DNS 配置的普通 DNS,但是最后查询却走的是安全 DNS。
这是因为,系统或浏览器会向系统 DNS 发起一个查询,来询问是否支持 DOH,如果支持后续就会升级使用 DOH 来查询。比如 8.8.8.8
brook dnsclient --dns 8.8.8.8:53 -d _dns.resolver.arpa -t SVCB
;; opcode: QUERY, status: NOERROR, id: 52504
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 4
;; QUESTION SECTION:
;_dns.resolver.arpa. IN SVCB
;; ANSWER SECTION:
_dns.resolver.arpa. 86400 IN SVCB 1 dns.google. alpn="dot"
_dns.resolver.arpa. 86400 IN SVCB 2 dns.google. alpn="h2,h3" dohpath="/dns-query{?dns}"
;; ADDITIONAL SECTION:
dns.google. 86400 IN A 8.8.8.8
dns.google. 86400 IN A 8.8.4.4
dns.google. 86400 IN AAAA 2001:4860:4860::8888
dns.google. 86400 IN AAAA 2001:4860:4860::8844
可以看见,8.8.8.8 支持 DOT 和 DOH。
不过放心,如果开启了虚拟 DNS, Brook 客户端会帮你阻止了这个 SVCB 查询
也就是说,明明你的系统 DNS 配置的普通 DNS,即使没有升级查询,但是最后查询却走的是安全 DNS。
这里因为系统和浏览器内置了一些主流安全 DNS 的信息,比如如果发现是 8.8.8.8,知道这个 DNS 也支持 DOH,就不会再问,而是直接使用 DOH。这时我们可以用脚本阻断这些连接
text := import("text")
f := func() {
if in_dnsquery {
if in_dnsquery.domain == "dns.google" {
return { "block": true }
}
return
}
if in_address {
m := in_address
if m.ipaddress && (m.ipaddress == "8.8.8.8:853" || m.ipaddress == "8.8.8.8:443" || m.ipaddress == "8.8.4.4:853" || m.ipaddress == "8.8.4.4:443" || m.ipaddress == "[2001:4860:4860::8888]:853" || m.ipaddress == "[2001:4860:4860::8888]:443" || m.ipaddress == "[2001:4860:4860::8844]:853" || m.ipaddress == "[2001:4860:4860::8844]:443") {
return { "block": true }
}
if m.domainaddress && text.has_prefix(m.domainaddress, "dns.google:") {
return { "block": true }
}
return
}
}
out := f()
这里有例子
当然你也可以配置一个不支持 DOH 的系统 DNS,比如用 brook 自建一个 DNS
brook dnsserver --listen :53
你可能会说,上文全程都没有真正向这个系统 DNS 发起真实网络连接,填一个不存在的 DNS 也行。
针对 A/AAAA 的确如此,但是如果是 MX 或其他类型就会向这个系统 DNS 发起真实网络连接,所以还是要填写一个真实存在的 DNS。