DNS及其应用

in #cn6 years ago (edited)

上周我们发布了一个重要的功能: DNS 出站协议。

这个协议的描述很简单,它把接收到的 DNS 流量,原封不动地发到它们本来的目的地,同时也相应地转发回程流量。如果只是这样,这个功能就不能称之为“重要”了(笑

DNS 出站协议有一个特殊行为,它默认把所有的 IP 查询(即 A 和 AAAA)交给 V2Ray 内部的 DNS 服务器来处理 。也就是说,通过合理地配置 DNS 服务器,可以做到很多有趣的功能。

广告屏蔽

V2Ray 的 DNS 服务器自带了 hosts 功能。当然我们的 hosts 比传统的操作系统自带的 hosts 文件强大很多,你只需要一行就可以屏蔽很多广告域名了。示例如下:

"dns": {
    "hosts": {
      "geosite:category-ads": "127.0.0.1"
    }
}

这一项的意思是对于所有 'category-ads' 中的域名,把 IP 解析到 '127.0.0.1',即一个肯定访问不了的 IP。'category-ads' 是 'geosite'中的一个特殊项,它包含了一些常见的广告域名,具体的内容点这里。如果你觉得还不够的话,欢迎按照格式提交 PR。

域名别名

由于众所周知的原因,'v2ray.com' 的 IP 在某些地区被解析到了 Facebook 的数据中心。实际上,'v2ray.com' 用的是 CloudFlare 的服务。CloudFlare 是一个 CDN,它的单个 IP,通常可以承载多个域名的流量。于是,我们即使不查询 'v2ray.com',而使用另一个域名(比如 'www.vicemc.net'),同样也可以得到一个可用的 IP。配置样例如下:

"dns": {
    "hosts": {
      "domain:v2ray.com": "www.vicemc.net"
    }
}

其中 'dns' 和 'hosts' 和上面一段的配置是一模一样的,实际的配置中,只需要写一遍就可以了。区别是这里把所有 'v2ray.com' 的域名(包括子域名)指向了 'www.vicemc.net'。在实际使用中,V2Ray 会通过 DNS 传出代理,拦截 'v2ray.com' 的查询,改写成 'www.vicemc.net' 再发送出去,完全避免了 DNS 污染。

这个功能在配置时有点复杂,你需要先知道一个域名的同 IP 其它域名,需要发挥一些想象力。

DNS 分流

在使用代理的时候,DNS 查询经常得到不合理的 IP,比如淘宝被解析到了一个国外的 IP,导致访问缓慢。这是因为代理软件修改了来源 IP 地址,DNS 服务器不知道你的实际位置,而是返回了一个离代理服务器较近的 IP 地址。解决这一问题的方法有很多,比如 EDNS Client Subnet。

这里 V2Ray 提供了一个理解起来更方便的方法:DNS 分流。即对于国内的域名,向国内的 DNS 服务器发送查询;其它的域名,向国外的服务器查询。示例如下:

"dns": {
  "servers": [
      "1.1.1.1",
      {
        "address": "114.114.114.114",
        "port": 53,
        "domains": ["geosite:cn"]
      },
      "localhost"
  ]
}

这段配置的意思是,所有常用的国内域名('geosite:cn')都使用 '114.114.114.114' 作为 DNS 服务器;而其它的域名使用 '1.1.1.1'。'geosite:cn' 尽可能地包含了国内外 IP 地址不同的域名,这些域名需要查询就近的 DNS 服务器。而对于那些只有单个 IP 的小站点,查哪里是一样的。

总结

即使你不使用代理功能,现在 V2Ray 也可以作为一个智能 DNS 来用了。更多有趣的功能还等着你来发掘。

顺便提一句,DNS 传出代理的套餐配置如下:

入站代理(透明代理):

{
  "port": 53,
  "tag": "dns-in",
  "protocol": "dokodemo-door",
  "settings": {
    "address": "1.1.1.1",
    "port": 53,
    "network": "tcp,udp" // 是的,同时支持 TCP 和 UDP 流量,加了 TLS 之后还可以支持 DoT
  }
}

出站代理:

{
  "protocol": "dns",
  "tag": "dns-out"
}

路由:

{
  "type": "field",
  "inboundTag": ["dns-in"],
  "outboundTag": "dns-out"
}

又顺带提一句,虽然这种情况不常发生,但是万一万一你不小心把内置 DNS 服务器发出的流量,指向了 DNS 出站协议。这时候按理说 DNS 出站代理会再一次把查询扔回给 DNS 服务器,造成死循环。这种情况我们已经考虑到了,DNS 出站协议能够识别出来自内置 DNS 服务器的流量,不会把它们扔回去,而且直接发出去。

又又顺带提一句,新年快乐!

Sort:  

✅ Enjoy the vote! For more amazing content, please follow @themadcurator for a chance to receive more free votes!

感谢大佬,我是从你这篇文章才得知 Steemit 的呢。

入站代理的setting 部分是不是可以直接删掉了?
全部流量不都是直接到出站代理然后走内置dns服务器了?

同感!我研究了很久也還沒搞明白,為什麼dokodemo-door那裏轉發了一次到1.1.1.1,路由那裏又轉發到內置DNS?有沒有兄弟能解惑?

应该是因为除了A和AAAA以外别的记录(如MX,CNAME)的查询是按照进入dns出站协议时的情况原样发出的,即发往docodemo-door的转发位置,不设置的话可能发到别的地方去