v2rayN icon indicating copy to clipboard operation
v2rayN copied to clipboard

[Feature request]: 对DNS配置的增强

Open minusmulticoloredper opened this issue 11 months ago • 26 comments

相关问题

对 "https://github.com/2dust/v2rayN/issues/6416" 的DNS配置的补充

描述你希望的解决方案

在正文中

描述你所考虑的替代方案

在正文中

我确认已查询历史issues

  • [X] 是

minusmulticoloredper avatar Jan 06 '25 03:01 minusmulticoloredper

当前DNS配置已有效防止DNS泄露,但仍存在几点不足: 1.配置中包含多余的proxy.example.com条目,保留此项并无实际意义,可删除。 2.缺少广告拦截机制。 3.Xray具有DNS回退查询机制,当geosite:geolocation-!cn中的某些境外域名在国外DNS无法解析时,将自动使用国内DNS进行二次查询,这可能导致解析结果不符合预期。 针对上述问题,我提出了两套改进方案。两套方案均针对回退查询进行了配置,避免出现3中描述的情况。此外,解析过程全面采用DOH(DNS over HTTPS)以提升安全性,并提前配置了DOH服务器的IP地址,进一步加速解析。

方案一:使用Hosts功能,将广告域名解析至无效IP地址

{
  "hosts": {
    "cloudflare-dns.com": [
      "104.16.249.249",
      "104.16.248.249",
      "2606:4700::6810:f9f9",
      "2606:4700::6810:f8f9"
    ],
    "dns.google": [
      "8.8.8.8",
      "8.8.4.4",
      "2001:4860:4860::8888",
      "2001:4860:4860::8844"
    ],
    "dns.alidns.com": [
      "223.5.5.5",
      "223.6.6.6",
      "2400:3200:baba::1",
      "2400:3200::1"
    ],
    "geosite:category-ads-all": "127.255.255.255"
  },
  "servers": [
    {
      "address": "https://cloudflare-dns.com/dns-query",
      "skipFallback": false,
      "domains": [
        "geosite:geolocation-!cn"
      ],
      "expectIPs": [
        "geoip:!cn"
      ]
    },
    {
      "address": "https://dns.google/dns-query",
      "skipFallback": false
    },
    {
      "address": "https://dns.alidns.com/dns-query",
      "skipFallback": true,
      "domains": [
        "geosite:cn"
      ],
      "expectIPs": [
        "geoip:cn"
      ]
    }
  ]
}

方案二:使用AdGuard公共DNS进行广告拦截 此外,该方案允许不在geosite内的域名通过AdGuard DNS进行解析。AdGuard DNS仅拦截广告,不拦截正常网页。

{
  "hosts": {
    "cloudflare-dns.com": [
      "104.16.249.249",
      "104.16.248.249",
      "2606:4700::6810:f9f9",
      "2606:4700::6810:f8f9"
    ],
    "dns.adguard-dns.com": [
      "94.140.14.14",
      "94.140.15.15",
      "2a10:50c0::ad1:ff",
      "2a10:50c0::ad2:ff"
    ],
    "dns.alidns.com": [
      "223.5.5.5",
      "223.6.6.6",
      "2400:3200:baba::1",
      "2400:3200::1"
    ]
  },
  "servers": [
    {
      "address": "https://cloudflare-dns.com/dns-query",
      "skipFallback": false,
      "domains": [
        "geosite:geolocation-!cn"
      ],
      "expectIPs": [
        "geoip:!cn"
      ]
    },
    {
      "address": "https://dns.adguard-dns.com/dns-query",
      "skipFallback": false,
      "domains": [
        "geosite:category-ads-all"
      ]
    },
    {
      "address": "https://dns.alidns.com/dns-query",
      "skipFallback": true,
      "domains": [
        "geosite:cn"
      ],
      "expectIPs": [
        "geoip:cn"
      ]
    }
  ]
}

minusmulticoloredper avatar Jan 06 '25 03:01 minusmulticoloredper

同时,sing-box中的DNS配置也有小小的缺陷,当路由规则设置为全局时,查询国内域名的IP时为直连状态。 建议匹配出站代理,将DNS查询请求路由。 以下DNS配置将在sing-box 1.11.0版本以及之后的版本中失效,之后需要对路由规则进行改动才能正确路由DNS请求。

{
  "servers": [
    {
      "tag": "remote",
      "address": "8.8.8.8",
      "strategy": "prefer_ipv4",
      "detour": "proxy"
    },
    {
      "tag": "cn_direct",
      "address": "223.5.5.5",
      "strategy": "prefer_ipv4",
      "detour": "direct"
    },
    {
      "tag": "cn_proxy",
      "address": "223.5.5.5",
      "strategy": "prefer_ipv4",
      "detour": "proxy"
    },
    {
      "tag": "block",
      "address": "rcode://success"
    }
  ],
  "rules": [
    {
      "rule_set": [
        "geosite-cn"
      ],
      "outbound": "direct",
      "server": "cn_direct"
    },
    {
      "rule_set": [
        "geosite-cn"
      ],
      "outbound": "proxy",
      "server": "cn_proxy"
    },
    {
      "rule_set": [
        "geosite-category-ads-all"
      ],
      "server": "block"
    }
  ],
  "final": "remote"
}

minusmulticoloredper avatar Jan 06 '25 03:01 minusmulticoloredper

[Info] app/dns: failed to lookup ip for domain 459yy.ipv4.surfsharkdns.com at server UDP:1.1.1.1:53 > features/dns: empty response [Info] app/dns: failed to lookup ip for domain l6s5fi.ipv4.surfsharkdns.com at server UDP:1.1.1.1:53 > features/dns: empty response [Info] app/dns: UDP:223.5.5.5:53 got answer: l6s5fi.ipv4.surfsharkdns.com. TypeA -> [207.154.224.110 207.154.252.37] 230.1412ms [Info] app/dns: UDP:223.5.5.5:53 got answer: l6s5fi.ipv4.surfsharkdns.com. TypeAAAA -> [] 239.1421ms [Info] app/dns: failed to lookup ip for domain l6s5fi.ipv4.surfsharkdns.com at server UDP:223.5.5.5:53 > app/dns: expectIPs not match [Info] app/dns: UDP:223.5.5.5:53 got answer: 459yy.ipv4.surfsharkdns.com. TypeA -> [207.154.224.110 207.154.252.37] 243.2448ms

DNS泄露检测的原理是通过让客户端尝试连接临时生成的随机域名,监听哪些DNS来请求了这个特殊的域名。 今天发现,那些DNS泄露检测网站,生成一个解析为空的域名,让客户端来连接, 结果客户端上当了,第一次用1.1.1.1解析不了,就自动切换到了223.5.5.5解析,导致又泄露DNS啦!!! 然后,我查看了xtls文档,这个参数设置为true就能避免已经匹配上的国外域名再次尝试连接国内223.5.5.5了 "disableFallbackIfMatch": true

CharlesWou avatar Jan 06 '25 06:01 CharlesWou

[Info] app/dns: failed to lookup ip for domain 459yy.ipv4.surfsharkdns.com at server UDP:1.1.1.1:53 > features/dns: empty response [Info] app/dns: failed to lookup ip for domain l6s5fi.ipv4.surfsharkdns.com at server UDP:1.1.1.1:53 > features/dns: empty response [Info] app/dns: UDP:223.5.5.5:53 got answer: l6s5fi.ipv4.surfsharkdns.com. TypeA -> [207.154.224.110 207.154.252.37] 230.1412ms [Info] app/dns: UDP:223.5.5.5:53 got answer: l6s5fi.ipv4.surfsharkdns.com. TypeAAAA -> [] 239.1421ms [Info] app/dns: failed to lookup ip for domain l6s5fi.ipv4.surfsharkdns.com at server UDP:223.5.5.5:53 > app/dns: expectIPs not match [Info] app/dns: UDP:223.5.5.5:53 got answer: 459yy.ipv4.surfsharkdns.com. TypeA -> [207.154.224.110 207.154.252.37] 243.2448ms

DNS泄露检测的原理是通过让客户端尝试连接临时生成的随机域名,监听哪些DNS来请求了这个特殊的域名。 今天发现,那些DNS泄露检测网站,生成一个解析为空的域名,让客户端来连接, 结果客户端上当了,第一次用1.1.1.1解析不了,就自动切换到了223.5.5.5解析,导致又泄露DNS啦!!! 然后,我查看了xtls文档,这个参数设置为true就能避免已经匹配上的国外域名再次尝试连接国内223.5.5.5了 "disableFallbackIfMatch": true

此参数设置为true,则会彻底关闭DNS回退查询机制,我认为这不是好的做法。 应该给国内的DNS设置为跳过DNS回退查询机制,国外的DNS则不跳过。 一旦其中一个国外DNS服务器无法解析出IP,则接着使用下一个国外DNS进行解析。

minusmulticoloredper avatar Jan 06 '25 06:01 minusmulticoloredper

方案一中category-ads-all导入到本地空地址,这个已经在路由规则中有配置block了 image

CharlesWou avatar Jan 06 '25 06:01 CharlesWou

刚才忘记看了, "skipFallback": true就会跳过国内查询,这挺符合预期的,有效避免了国内DNS泄露。 但想请问下,如果一个域名,是国内的IP,但是不在geosite:cn中(国内小众网站),他是不是就用不了阿里DNS了?

CharlesWou avatar Jan 06 '25 07:01 CharlesWou

刚才忘记看了, "skipFallback": true就会跳过国内查询,这挺符合预期的,有效避免了国内DNS泄露。 但想请问下,如果一个域名,是国内的IP,但是不在geosite:cn中(国内小众网站),他是不是就用不了阿里DNS了?

好像是的,会先走CloudFlare DNS,查询失败就会接着走Google DNS。

minusmulticoloredper avatar Jan 06 '25 07:01 minusmulticoloredper

如果要让Google DNS先查询,得把它放在第一位。

minusmulticoloredper avatar Jan 06 '25 07:01 minusmulticoloredper

你们讨论的结果可用于自用,app中默认规则需要基础功能和适合大众;

2dust avatar Jan 06 '25 07:01 2dust

还有就是,DNS地址其实只要是国外的,客户端就会默认proxy路由到VPS上。(不然当前客户端8.8.8.8的DNS解析早被污染了,打不开google了。) 个人感觉DOH像是保护国内到国际这端。但其实DNS已经proxy到了VPS,再通过VPS进行DOH查询,是不是有点浪费?

CharlesWou avatar Jan 06 '25 07:01 CharlesWou

去掉一个DNS服务器,并禁用DNS回退查询机制。 匹配国内域名自动使用阿里云DNS,查询失败返回空解析不继续。 匹配国外域名自动使用CloudFlare DNS,查询失败返回空解析不继续。 如果两者都不匹配,自动使用CloudFlare DNS,查询失败返回空解析不继续。 广告域名则会被解析为无效IP。

{
    "hosts": {
        "cloudflare-dns.com": [
            "104.16.249.249",
            "104.16.248.249",
            "2606:4700::6810:f9f9",
            "2606:4700::6810:f8f9"
        ],
        "dns.alidns.com": [
            "223.5.5.5",
            "223.6.6.6",
            "2400:3200:baba::1",
            "2400:3200::1"
        ],
        "geosite:category-ads-all": "127.255.255.255"
    },
    "servers": [
        {
            "address": "https://cloudflare-dns.com/dns-query"
        },
        {
            "address": "https://dns.alidns.com/dns-query",
            "domains": [
                "geosite:cn"
            ],
            "expectIPs": [
                "geoip:cn"
            ]
        }
    ],
    "disableFallback": true
}

minusmulticoloredper avatar Jan 06 '25 07:01 minusmulticoloredper

https://www.v2fly.org/dns_flowchart_20210418.svg

minusmulticoloredper avatar Jan 06 '25 07:01 minusmulticoloredper

去掉一个DNS服务器,并禁用DNS回退查询机制。 匹配国内域名自动使用阿里云DNS,查询失败返回空解析不继续。 匹配国外域名自动使用CloudFlare DNS,查询失败返回空解析不继续。 如果两者都不匹配,自动使用CloudFlare DNS,查询失败返回空解析不继续。 广告域名则会被解析为无效IP。

{
    "hosts": {
        "cloudflare-dns.com": [
            "104.16.249.249",
            "104.16.248.249",
            "2606:4700::6810:f9f9",
            "2606:4700::6810:f8f9"
        ],
        "dns.alidns.com": [
            "223.5.5.5",
            "223.6.6.6",
            "2400:3200:baba::1",
            "2400:3200::1"
        ],
        "geosite:category-ads-all": "127.255.255.255"
    },
    "servers": [
        {
            "address": "https://cloudflare-dns.com/dns-query"
        },
        {
            "address": "https://dns.alidns.com/dns-query",
            "domains": [
                "geosite:cn"
            ],
            "expectIPs": [
                "geoip:cn"
            ]
        }
    ],
    "disableFallback": true
}

@2dust 最终版,规避了DNS回退查询机制造成的DNS泄露。

minusmulticoloredper avatar Jan 06 '25 07:01 minusmulticoloredper

我也是试了很久,安全和速度终究没法两全。 如果把skipFallback设置为true,dns泄露的问题是解决了,但是国内小众域名先1.1.1.1解析,解析ip不匹配后,走8.8.8.8,不会走223.5.5.5了。 如果把skipFallback设置为false(相当于当前最新pre-release版的配置),1.1.1.1如无法解析出外网域名,会走223.5.5.5,会发生dns泄露。

{
  "hosts": {
    "dns.google": "8.8.8.8",
    "geosite:category-ads-all": "127.255.255.255"
  },
  "servers": [
    {
      "address": "1.1.1.1",
      "expectIPs": [
        "geoip:!cn"
      ]
    },
    {
      "address": "223.5.5.5",
>     "skipFallback": true,
      "domains": [
        "geosite:cn"
      ],
      "expectIPs": [
        "geoip:cn"
      ]
    },
    "8.8.8.8"
  ]
}

CharlesWou avatar Jan 06 '25 10:01 CharlesWou

关键问题是core没有把“查询失败”和“ip不匹配”分开做条件判断,如果能对“查询失败”做策略,对“ip不匹配”另外做策略,那就好办了:查询失败disableFallback,ip不匹配enableFallback 1736159632799

CharlesWou avatar Jan 06 '25 10:01 CharlesWou

@minusmulticoloredper 最终我发现,要最安全就直接切换成AsIs域名解析策略(不过内置dns服务器模块,直接发送域名到vps,让他来解析),要牺牲部分安全为了加快/兼容国内小网站,那就用最新pre-release就行。我不折腾了,直接切AsIs域名解析策略了。

CharlesWou avatar Jan 06 '25 11:01 CharlesWou

@minusmulticoloredper 最终我发现,要最安全就直接切换成AsIs域名解析策略(不过内置dns服务器模块,直接发送域名到vps,让他来解析),要牺牲部分安全为了加快/兼容国内小网站,那就用最新pre-release就行。我不折腾了,直接切AsIs域名解析策略了。

你又回到了app默认的配置了;其实dns全部发给远程解析是最好的,就是可能慢点

2dust avatar Jan 06 '25 12:01 2dust

去掉一个DNS服务器,并禁用DNS回退查询机制。 匹配国内域名自动使用阿里云DNS,查询失败返回空解析不继续。 匹配国外域名自动使用CloudFlare DNS,查询失败返回空解析不继续。 如果两者都不匹配,自动使用CloudFlare DNS,查询失败返回空解析不继续。 广告域名则会被解析为无效IP。

{
    "hosts": {
        "cloudflare-dns.com": [
            "104.16.249.249",
            "104.16.248.249",
            "2606:4700::6810:f9f9",
            "2606:4700::6810:f8f9"
        ],
        "dns.alidns.com": [
            "223.5.5.5",
            "223.6.6.6",
            "2400:3200:baba::1",
            "2400:3200::1"
        ],
        "geosite:category-ads-all": "127.255.255.255"
    },
    "servers": [
        {
            "address": "https://cloudflare-dns.com/dns-query"
        },
        {
            "address": "https://dns.alidns.com/dns-query",
            "domains": [
                "geosite:cn"
            ],
            "expectIPs": [
                "geoip:cn"
            ]
        }
    ],
    "disableFallback": true
}

@2dust 最终版,规避了DNS回退查询机制造成的DNS泄露。

TA的这个也算是挺完美的了,只是小众国内域名的dns解析走proxy,流量不会被代理,但是我觉得vps这边再发出DOH请求有些复杂了

{
  "hosts": {
    "dns.google": "8.8.8.8",
    "geosite:category-ads-all": "127.255.255.255"
  },
  "servers": [
    "8.8.4.4",
    {
      "address": "localhost",
      "skipFallback": true,
      "domains": [
        "geosite:cn"
      ],
      "expectIPs": [
        "geoip:cn"
      ]
    },
    "1.0.0.1"
  ]
}

CharlesWou avatar Jan 06 '25 12:01 CharlesWou

请问在开启tun模式后可以使用xray的内部dns而不是singbox的dns设置吗,可以的话该怎么设置?

debugzxcv avatar Jan 07 '25 00:01 debugzxcv

去掉一个DNS服务器,并禁用DNS回退查询机制。 匹配国内域名自动使用阿里云DNS,查询失败返回空解析不继续。 匹配国外域名自动使用CloudFlare DNS,查询失败返回空解析不继续。 如果两者都不匹配,自动使用CloudFlare DNS,查询失败返回空解析不继续。 广告域名则会被解析为无效IP。

{
    "hosts": {
        "cloudflare-dns.com": [
            "104.16.249.249",
            "104.16.248.249",
            "2606:4700::6810:f9f9",
            "2606:4700::6810:f8f9"
        ],
        "dns.alidns.com": [
            "223.5.5.5",
            "223.6.6.6",
            "2400:3200:baba::1",
            "2400:3200::1"
        ],
        "geosite:category-ads-all": "127.255.255.255"
    },
    "servers": [
        {
            "address": "https://cloudflare-dns.com/dns-query"
        },
        {
            "address": "https://dns.alidns.com/dns-query",
            "domains": [
                "geosite:cn"
            ],
            "expectIPs": [
                "geoip:cn"
            ]
        }
    ],
    "disableFallback": true
}

@2dust 最终版,规避了DNS回退查询机制造成的DNS泄露。

TA的这个也算是挺完美的了,只是小众国内域名的dns解析走proxy,流量不会被代理,但是我觉得vps这边再发出DOH请求有些复杂了

{
  "hosts": {
    "dns.google": "8.8.8.8",
    "geosite:category-ads-all": "127.255.255.255"
  },
  "servers": [
    "8.8.4.4",
    {
      "address": "localhost",
      "skipFallback": true,
      "domains": [
        "geosite:cn"
      ],
      "expectIPs": [
        "geoip:cn"
      ]
    },
    "1.0.0.1"
  ]
}

不用DOH的话,可以把这行去掉。

"dns.google": "8.8.8.8"

minusmulticoloredper avatar Jan 07 '25 01:01 minusmulticoloredper

要是全部交给远程解析的话,可以用FakeDNS,但是这样就没法把域名转成IP用于匹配IP路由规则,只能匹配纯IP访问。

minusmulticoloredper avatar Jan 07 '25 01:01 minusmulticoloredper

还是把谷歌DNS加上吧,增加点容错。

{
  "hosts": {
    "geosite:category-ads-all": "127.255.255.255"
  }, 
  "servers": [
    {
      "address": "1.1.1.1", 
      "skipFallback": false, 
      "domains": [
        "geosite:geolocation-!cn"
      ], 
      "expectIPs": [
        "geoip:!cn"
      ]
    }, 
    {
      "address": "8.8.8.8", 
      "skipFallback": false
    }, 
    {
      "address": "223.5.5.5", 
      "skipFallback": true, 
      "domains": [
        "geosite:cn"
      ], 
      "expectIPs": [
        "geoip:cn"
      ]
    }
  ]
}

minusmulticoloredper avatar Jan 07 '25 02:01 minusmulticoloredper

请问在开启tun模式后可以使用xray的内部dns而不是singbox的dns设置吗,可以的话该怎么设置?

这个得要开启xray内部的dns入站,然后让singbox把dns请求传给xray。

minusmulticoloredper avatar Jan 07 '25 02:01 minusmulticoloredper

这个得要开启xray内部的dns入站,然后让singbox把dns请求传给xray。

有具体的配置文件吗?

debugzxcv avatar Jan 07 '25 02:01 debugzxcv

这个得要开启xray内部的dns入站,然后让singbox把dns请求传给xray。

有具体的配置文件吗?

刚才看了一下xray配置文档,只有dns出站,没有dns入站,可能得再加个dns转发器了。

minusmulticoloredper avatar Jan 07 '25 02:01 minusmulticoloredper

请教一下各位高手,以下V2Ray DNS配置,是否可以? { "hosts": { "dns.pub": "119.29.29.29", "dns.alidns.com": "223.5.5.5", "dns.google": "8.8.8.8", "geosite:category-ads-all": "127.0.0.1" }, "servers": [ { "address": "https://dns.google/dns-query", "port": 53, "domains": [ "geosite:gfw", "geosite:greatfire", "geosite:tld-!cn", "geosite:geolocation-!cn" ], "expectIPs": [ "geoip:!cn" ] }, { "address": "https+local://dns.alidns.com/dns-query", "port": 53, "domains": [ "geosite:private", "geosite:cn", "geosite:tld-cn", "geosite:category-games@cn" ], "expectIPs": [ "geoip:private", "geoip:cn" ], "skipFallback": true }, { "address": "localhost", "skipFallback": true } ] }

eirik-lu avatar Jan 07 '25 06:01 eirik-lu