MatsuriDayo / nekoray

Qt based cross-platform GUI proxy configuration manager (backend: sing-box)
https://matsuridayo.github.io/
GNU General Public License v3.0
12.41k stars 1.18k forks source link

[Windows] vpn模式下可能有DNS泄漏问题 #32

Closed egg1234 closed 1 year ago

egg1234 commented 2 years ago

在vpn模式下,如果本机网卡的DNS设置为国内的DNS地址或DHCP从宽带路由器得到,那么使用firefox或chrome浏览器,访问https://dnsleaktest.com/ 网站,网页出来后点Extended test按钮进行DNS泄漏测试,结果出来后就会发现既有远程的DNS地址,也有国内运营商的DNS地址,如果本地网卡的的DNS设置为1.0.0.1或9.9.9.9就会出现CF或Quard9的DNS,以及远程的DNS地址

在系统代理模式下无论本机网卡的DNS怎么设置,使用firefox或chrome浏览器,访问https://dnsleaktest.com/ 网站,网页出来后点Extended test按钮进行DNS泄漏测试,结果出来后就会发现只有远程的DNS地址,没有DNS泄漏的问题

arm64v8a commented 2 years ago

是否已开启国内外分流?

请提交配置(右键 - 分享 - 导出v2ray配置)

egg1234 commented 2 years ago

绕过模式是在 首选项->路由vpn设置->点弹出画面的“预设”选择->绕过局域网和大陆

导出的v2ray配置(敏感已处理)

{"dns":{"disableFallbackIfMatch":true,"hosts":{},"servers":[{"address":"https://8.8.8.8/dns-query","domains":[]},{"address":"https+local://223.5.5.5/dns-query","domains":["geosite:cn"],"skipFallback":true}],"tag":"dns"},"inbounds":[{"listen":"127.0.0.1","port":2080,"protocol":"socks","settings":{"auth":"noauth","udp":true},"sniffing":{"destOverride":["http","tls","quic"],"enabled":true,"metadataOnly":false,"routeOnly":true},"tag":"socks-in"},{"listen":"127.0.0.1","port":2081,"protocol":"http","sniffing":{"destOverride":["http","tls","quic"],"enabled":true,"metadataOnly":false,"routeOnly":true},"tag":"http-in"}],"log":{"loglevel":"warning"},"outbounds":[{"domainStrategy":"AsIs","protocol":"vmess","settings":{"vnext":[{"address":"173.173.173.173","port":12345,"users":[{"alterId":0,"id":"b48beaf4-68ed-38e3-a695-c26b6382c73e","security":"aes-128-gcm"}]}]},"streamSettings":{"network":"tcp","security":"none"},"tag":"g-1"},{"protocol":"freedom","tag":"direct"},{"protocol":"freedom","tag":"bypass"},{"protocol":"blackhole","tag":"block"},{"protocol":"dns","proxySettings":{"tag":"g-1","transportLayer":true},"settings":{"address":"8.8.8.8","network":"tcp","port":53,"userLevel":1},"tag":"dns-out"}],"policy":{"levels":{"1":{"connIdle":30}},"system":{"statsOutboundDownlink":true,"statsOutboundUplink":true}},"routing":{"domainMatcher":"mph","domainStrategy":"AsIs","rules":[{"ip":["223.5.5.5"],"outboundTag":"direct","type":"field"},{"ip":["224.0.0.0/3","169.254.0.0/16"],"outboundTag":"block","type":"field"},{"outboundTag":"block","port":"135-139","type":"field"},{"inboundTag":["socks-in","http-in"],"outboundTag":"dns-out","port":"53","type":"field"},{"inboundTag":["dns-in"],"outboundTag":"dns-out","type":"field"},{"domain":["geosite:category-ads-all","domain:appcenter.ms","domain:app-measurement.com","domain:firebase.io","domain:crashlytics.com","domain:google-analytics.com"],"outboundTag":"block","type":"field"},{"ip":["geoip:cn","geoip:private"],"outboundTag":"bypass","type":"field"},{"domain":["geosite:cn"],"outboundTag":"bypass","type":"field"}]},"stats":{}}

arm64v8a commented 2 years ago

这个网站的查询应该都是国外域名。

不清楚为什么浏览器会用到本机网卡的DNS。理论上流量若走TUN网卡,所有DNS流量都会被拦截重写。但是Windows上程序可以随意指定出口网卡。

另外如果网络有v6,请确保TUN也开启v6,否则也可能会出现这种情况(仅限Windows系统)

egg1234 commented 2 years ago

使用的是windows 10 pro 21H2版,宽带路由器没有打开IPv6,内网也没有设置IPv6,其实环境挺简单的 估计你应该也很容易复现这个测试环境

arm64v8a commented 2 years ago

未能复现,打开上述网站测试,全部是远程DNS提供商的IP

egg1234 commented 2 years ago

经过排查,原来是必须在 首选项->路由vpn设置 的画面右上角 勾选“FakeDNS” 就能防止在VPN模式下的DNS泄漏 如果没有勾选这个选项,其实在VPN模式一启动的时候,日志框已经会显示一条错误信息 [Warning] app/dispatcher: default route for [tcp:8.8.8.8:443] [Error] app/dns: failed to retrieve response > Post "https://8.8.8.8/dns-query": context canceled

如果是勾选这个选项,在VPN模式启动的时候,日志框是不会出现这个错误信息的

egg1234 commented 2 years ago

另外vpn模式下还必须设置 首选项->路由vpn设置 的画面左上角的“域名策略”选择“IPIfNonMatch”, 否则访问国内某些网站会测试出代理服务器的IP地址,但是使用国内的DNS服务器,这个更危险

arm64v8a commented 2 years ago

测试中没有设置 FakeDNS IPIfNonMatch 选项。我认为问题不在这里。

开启FakeDNS可以把域名查询交由节点服务端完成,也是防止DNS泄漏的一种方式。

c0def4n commented 2 years ago

我这边也能复现问题。vpn模式连接vmess节点,使用 https://browserleaks.com/ip 以及 https://dnsleaktest.com/ 的DNS泄露测试功能均有显示国内DNS(既有谷歌DNS也有国内DNS)。

c0def4n commented 2 years ago

我这边在VPN模式下,就算启用FakeDNS功能仍然存在泄露。

c0def4n commented 2 years ago

测试环境是windows 10系统,浏览器是Edge最新版

egg1234 commented 2 years ago

所以我现在的临时解决方法就是干脆在vpn模式下,把本地网卡的DNS地址设置为1.0.0.1或9.9.9.9,即使泄漏也无所谓,只要没有国内DNS地址查询出现就可以了

c0def4n commented 2 years ago

可能是wintun的锅,以前netch用tap-windows没问题,换成wintun就有dns泄露问题了

egg1234 commented 2 years ago

其实netch那边早些时间我也开过同样的DNS泄漏issue,netch 1.9.7无论是用wintun设置自定义DNS或用回AioDNS一样是有DNS泄漏的,同样的临时解决方法也是把本地网卡的DNS地址设置为1.0.0.1或9.9.9.9

c0def4n commented 2 years ago

朋友,你这做法属于掩耳盗铃哦,并没有解决DNS泄露。

DNS泄露的根源是直接通过本机发送DNS查询请求,你把本地网卡DNS地址设为cloudflare的1.0.0.1,你的dns查询请求将从本机直接发往1.0.0.1,因为UDP DNS是明文协议,虽然1.0.0.1是境外服务器,但你DNS查询数据包从国内出来的一路上都是明文,都可能被记录。

c0def4n commented 2 years ago

有效杜绝DNS泄露的方法:将本机网卡DNS设置为1270.0.1(不会影响域名解析,数据包会同步走tun)。

c0def4n commented 2 years ago

所以我现在的临时解决方法就是干脆在vpn模式下,把本地网卡的DNS地址设置为1.0.0.1或9.9.9.9,即使泄漏也无所谓,只要没有国内DNS地址查询出现就可以了

可以用我说的方法试试效果

egg1234 commented 2 years ago

将本机网卡DNS设置为1270.0.1对于远端服务器直接ip访问的协议如vmess tcp应该好使,但是有TLS的vmess协议就不行了,因为本机网卡DNS设置为1270.0.1等同于没有最基本的DNS,至少netch一启动这种协议就会报告域名解析错误

另外nekoray这边就有奇怪情况出现,当我设置了本机网卡DNS设置为1270.0.1并重启了机器后,启动vpn模式,日志框就不断报错 [Error] app/dns: failed to retrieve response > Post "https://223.5.5.5/dns-query": context deadline exceeded 然后是不能访问任何网站

后面即使把本机网卡DNS设置为dhcp获得或手动设置一个运营商的dns地址,再启动vpn模式,日志框还是不断报上面的错误信息,同样是不能访问任何网站,更神奇的是把机器再重启,删除整个nekoray目录,重新下载1.4版再解压运行,报错还是一样的,然后把整个1.4版整个nekoray目录删除,重新解压1.2版,情况一样,反复重启机器也没有解决,不知是否有一些错误标识写在了另外的地方,在某些情况下留在那里了没有清除,导致更换了版本都没有用

但是上面这些问题又完全没有影响系统代理的功能,无论上面步骤怎么折腾,系统代理都能用得好好的,所以现在也只能放在那里了

arm64v8a commented 2 years ago

@egg1234 请勿玄学。软件所有配置均在 config 目录下。

首先要确定使用原来的网卡查询DNS的行为是nekoray_core或者是什么程序发出的,查询了什么域名。目前我没有办法复现这种行为,所以只能你们来抓,sysinternals工具或许能做到。

如果是其他进程发出的,且不引入 hook 或者 nfdriver 等技术,似乎是无解的。

egg1234 commented 2 years ago

的确没有玄学,问题排查出来了,由于之前机器一直有内网穿越的逻辑TUN卡, 但没有将本机物理网卡DNS设置为1270.0.1之前,nekoray的vpn模式一直正常工作的,所以没有理会它 但将本机物理网卡DNS设置为1270.0.1后就出现了上面的DNS报错问题,最后退出内网穿越的注册,那个逻辑TUN卡不出现了,就一切正常了 但是没有这个内网穿越的逻辑TUN卡依然不能在本机物理网卡DNS设置运营商的DNS, 否则还是DNS泄漏,至少证明不是这个内网穿越的逻辑TUN卡引致DNS泄漏的, 所以本机物理网卡DNS还是必须设置为1270.0.1,这样就完全没有vpn模式下的DNS泄漏了, 而且现在我还设置nekoray的远程 DNS https://1.0.0.1/dns-query, 设置nekoray的直连 DNS https+local://1.0.0.1/dns-query,工作完美

而且也顺便验证了nekoray的vpn模式与vmware workstation可以共存,即nekoray启动vpn模式,windows 10里面的程序流量都通过vpn走,而同时vmware workstation里面可以启动linux虚拟机并正常使用,虚拟机的流量走自己应该走的通道,windows 10里面的workstation的虚拟网卡没有影响nekoray的DNS查询及没有导致DNS泄漏

@arm64v8a 有一个问题需要请教你一下,像现在这样本机物理网卡DNS设置为1270.0.1, 设置nekoray的直连 DNS https+local://1.0.0.1/dns-query,那么按照nekoray的工作原理, 是否连第一次的TLS域名查询都没有使用明码,而直接使用了1.0.0.1的DoH加密查询呢?

@c0def4n 谢谢你这个将本机物理网卡DNS设置为1270.0.1的方法,对于nekoray的vpn模式来说是完美方法

arm64v8a commented 2 years ago

有人复现了。使用 Windows API 查询 DNS 时,svchost.exe 会在所有网卡发送 DNS 查询。

egg1234 commented 2 years ago

我不成熟的想法是有没有可能在启动vpn模式时由nekoray程序本身先记录本机物理网卡的DNS设置状况,如DHCP获得或是已经手动设置的IP,然后更改本机物理网卡的DNS为127.0.0.1,当退出vpn模式时把本机物理网卡的DNS设置状况恢复到之前状态,整个流程可以作为一个选项,因为有些用户可能有自己的DNS策略而不需要这样处理

当然我没有研究过这个流程的难度,所以不知是否可行

arm64v8a commented 2 years ago

目前程序不负责这部分,所以不方便。我也不清楚有没有比设置 127.0.0.1 更好的方法

可以试试单独使用sing-box(预计行为是一致的),然后在那边开 issue

arm64v8a commented 1 year ago

上游已添加防dns泄漏措施。

egg1234 commented 1 year ago

已经验证nekoray 2.0[windows]版应该是消除了VPN模式下的DNS泄漏问题,也就是不改变物理网卡的DNS设置,只是使用DHCP从路由器获得,不需要像之前版本那样把物理网卡的DNS设置成127.0.0.1

另外在v2ray内核情况下最好选择FakeDNS

hb-0 commented 10 months ago

和楼主有同样的问题,所以作者认为不是软件导致的?那有什么解决方案吗?实测修改网卡DNS还是不能解决……

egg1234 commented 10 months ago

@hb-0 这个issue所说的nekoray版本太老了,没有讨论的意义,下面是最近的nekoray版本关于TUN模式防止DNS泄露的配置建议,当然新版本nekoray已经没有所谓VPN模式的说法

nekoray 3.17 windows 10 22h2在TUN模式下防止DNS泄露的设置,在ipv4环境下实际使用结果,如果使用ipv6(即启用Tun IPv6勾选),那么需要你自己实际测试组合的勾选项,stack gvisor mtu 9000缺省

sing-box内核情况下 Strick Route必须勾选 FakDNS必须勾选 内部TUN无所谓

xray内核情况下 Strick Route必须勾选 FakDNS不能勾选

如果使用其他nekoray版本(强烈建议至少3.17以上版本),或其他操作系统版本,需要你自己实际测试组合的勾选项