让 v2ray 透明代理的 DNS 更聪明一些


透明代理(TPROXY) | 新 V2Ray 白话文指南 中,作者通过 v2ray 内置的 DNS 功能实现 DNS 查询分流的功能,但 v2ray 内置的 DNS 功能并不完善,实际体验下来速度并不快,于是参考其他网友的文章,试了一下用 SmartDNS 来接管全局网络的 DNS。

SmartDNS 是一个运行在本地的 DNS 服务器软件,它支持缓存、分流、测速等功能,可以极大地提高 DNS 使用体验。SmartDNS 提供了 OpenWRT 的预编译包,参考官方文档就可以很容易的在 OpenWRT 上完成安装配置。

启动 SmartDNS

在 v2ray 的 TProxy 的网络环境下,v2ray 会接管来自局域网的 DNS 查询请求,为了让 SmartDNS 能够正常工作,需要修改之前设置的 iptables 规则,让来自 53 端口的 UDP 请求不再被转发到 v2ray:

- iptables -t mangle -A V2RAY -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN # 直连局域网,53 端口除外(因为要使用 V2Ray 的 DNS)
+ iptables -t mangle -A V2RAY -d 192.168.0.0/16 -p udp -j RETURN # 直连局域网

再添加一些上游 DNS 服务器地址:

# 国内域名服务器,设置分组名为 cn
server-tls 233.5.5.5  -group cn
# 国外域名服务器,使用默认分组 default
server-tls 1.1.1.1
server-tls 8.8.8.8

接着,设置 SmartDNS 监听 53 端口,并关闭 dnsmasq 服务:

启用 SmartDNS

如果一切顺利,你应该可以通过命令查询到 smartdns 这个域名:

$ dog smartdns
# A smartdns. 10m00s   192.168.68.4

实现 DNS 查询分流

为了能够在不造成 DNS 污染的情况下尽可能地使用国内 CDN,需要借助 dnsmasq-china-list 项目提供的域名列表实现查询分流。

先 clone 这个项目到本地,然后执行下面的命令来生成 SmartDNS 规则:

$ make smartdns-domain-rules SERVER=cn
$ ls *.domain.smartdns.conf
# accelerated-domains.china.domain.smartdns.conf  apple.china.domain.smartdns.conf  google.china.domain.smartdns.conf

再把这些生成出来的文件复制到 OpenWRT 中,并修改 SmartDNS 的自定义设置:

conf-file /etc/smartdns/conf.d/accelerated-domains.china.domain.smartdns.conf
conf-file /etc/smartdns/conf.d/apple.china.domain.smartdns.conf
conf-file /etc/smartdns/conf.d/bogus-nxdomain.china.smartdns.conf
conf-file /etc/smartdns/conf.d/google.china.domain.smartdns.conf

设置 v2ray 路由规则

在完成 DNS 查询分流后,还需要更新一下 v2ray 的路由规则,让 v2ray 能够正确的把流量发送到正确的 outbound,以下是一个国内直连白名单策略的设置:

{
  "outbounds": [
    {
      // 配置省略,请参考白话文
      "tag": "proxy"
    },
    {
      // 配置省略,请参考白话文
      "tag": "direct"
    }
  ],
  "routing": {
    // 优先按域名匹配规则,无匹配时再将域名解析为 ip 进行匹配
    "domainStrategy": "IPIfNonMatch",
    "rules": [
      {
        // 国外 DNS 需要代理
        "ip": [
          "8.8.8.8",
          "1.1.1.1"
        ],
        "outboundTag": "proxy",
        "type": "field"
      },
      {
        // 国内 DNS 必须直连
        "ip": [
          "223.5.5.5"
        ],
        "outboundTag": "direct",
        "type": "field"
      },
      {
        // 需要直连的域名白名单:国内域名、国内 CDN 等
        "domain": [
          "geosite:private",
          "geosite:apple-cn",
          "geosite:google-cn",
          "geosite:category-games@cn",
          "geosite:cn",
          "ntp.org",
          "domain:mi.com",
          "domain:ls.apple.com",
          // steam 优先选择国内 CDN,如果无效可以删掉
          "domain:cm.steampowered.com",
          "YOUR_VPS_ADDRESS"
        ],
        "outboundTag": "direct",
        "type": "field"
      },
      {
        // 需要直连的 IP 地址白名单:局域网地址、国内地址
        "ip": [
          "geoip:private",
          "geoip:cn",
          "YOUR_VPS_IP"
        ],
        "outboundTag": "direct",
        "type": "field"
      }
    ]
  }
}

这份配置文件中用到的 geosite.dat 来自 Loyalsoldier/v2ray-rules-dat,其中的国内域名列表也是基于上面的 dnsmasq-china-list 项目生成的。这样就可以保证 SmartDNS 解析出来的国内域名也一定会被 v2ray 发送到 direct outbound。


发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

You can use markdown syntax in comment