TUN 模式用 Android 的 VpnService 建一张虚拟网卡,把设备流量整包接进 v2rayNG 内置的 Xray 内核。全文按四步展开:先对比它和默认本地代理的差别,再拆开数据路径,然后给出开启与授权顺序,最后用三个可复现的检查确认接管范围,并列出后台存活与 DNS 解析的常见坑。
TUN 模式与默认本地代理的差别
v2rayNG 默认的连接方式只在本机开两个入站:SOCKS 在 127.0.0.1:10808,HTTP 在 127.0.0.1:10809。只有会读代理设置的 App(浏览器、部分下载工具)才会把请求送进这两个端口,其余应用照旧直连。Android 也没有面向全部应用的全局代理开关,Wi-Fi 高级选项里的代理只对遵守该设置的应用生效。
TUN 模式换了一条路径:v2rayNG 通过 Android 的 VpnService 申请一张虚拟网卡,系统把设备发出的 IP 包写进这张网卡,应用侧不需要填任何代理地址。网卡里的包交给内置的 tun2socks 转发组件,还原成 TCP 连接与 UDP 会话之后,再以 SOCKS5 交给 Xray 内核分流。
| 对比项 | 默认本地代理 | TUN 模式 |
|---|---|---|
| 接管对象 | 主动设置代理的 App | 设备全部 IP 流量,可按 App 筛选 |
| App 侧配置 | 需要填 127.0.0.1:10808 | 不需要 |
| DNS 处理 | 由 App 自行解析 | 随流量进内核,按域名解析策略处理 |
| 权限 | 无 | 需要系统 VPN 授权 |
| 功耗 | 低 | 略高,多一次用户态转发 |
| 典型场景 | 浏览器与支持代理的工具 | 不支持代理设置的 App、需要全局接管 |
数据路径:从应用到出站
一次请求在 TUN 模式下要经过五个环节,每一段都能单独排查。
前两段由系统与转发组件完成。VpnService 建立网卡后,默认路由 0.0.0.0/0 指向这张网卡,应用发出的连接被整包写进 TUN;tun2socks 从网卡读出原始 IP 包,还原出 TCP 连接与 UDP 会话,再以 SOCKS5(含 UDP ASSOCIATE)交给 127.0.0.1:10808。
后三段在 Xray 内核里完成。请求进入 socks 入站后先按 routing 规则匹配,再决定走 outbound 代理还是 freedom 直连。域名什么时候解析成 IP,由「设置」里的「域名解析策略」控制:选 IPIfNonMatch 时先用域名匹配规则,匹配不上才发起解析,能省掉一次无谓的 DNS 查询;选 AsIs 则完全按域名匹配;选 IPOnDemand 只在遇到 IP 规则时才解析。
{
"inbounds": [
{ "tag": "socks", "listen": "127.0.0.1", "port": 10808, "protocol": "socks", "settings": { "udp": true } },
{ "tag": "http", "listen": "127.0.0.1", "port": 10809, "protocol": "http" }
],
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{ "type": "field", "outboundTag": "direct", "ip": ["geoip:private"] },
{ "type": "field", "outboundTag": "direct", "domain": ["geosite:cn"] }
]
}
}
上面截取的是入站与路由两段,outbounds 与具体节点由导入的订阅生成。可以看到 TUN 模式没有新增协议:网卡里出来的流量最终仍然走 10808 这个 SOCKS 入站,握手与加密方式完全由节点决定,VMess、VLESS、Trojan、SS 都一样。
开启 TUN 模式的操作顺序
下面的顺序对应 v2rayNG 1.9.x 的中文界面。个别版本的菜单文案有一两字差异,步骤本身不变。
- 先导入订阅并确认节点可用。在节点行右侧菜单执行「测试真连接延迟」,延迟显示 -1 的节点说明握手失败,先换一个能通的,避免把节点问题误判成 TUN 的问题。
- 打开侧边栏 →「设置」,确认连接方式为 VPN(TUN)模式。v2rayNG 用 VpnService 建虚拟网卡,部分版本这里是一个「VPN 模式」开关,部分版本没有独立开关、点连接直接走 VpnService,不影响后续步骤。
- 侧边栏 →「路由设置」→「预定义规则」,选「绕过局域网和大陆」。内网设备与国内站点走 direct,只有需要代理的流量进节点。
- 「设置」→「域名解析策略」选 IPIfNonMatch。这个选项决定域名在规则匹配的哪个阶段被解析,后面验证 DNS 时会用到。
- 需要按 App 控制时,进「设置」→「分应用代理」,打开开关并选择「仅代理所选应用」或「绕过所选应用」,在应用列表里勾选目标 App。
- 返回主界面点连接。首次会弹出系统的「连接请求」对话框,点「允许」;之后状态栏出现 VPN 钥匙图标,通知栏出现 v2rayNG 的运行通知,接管开始。
分应用代理和 TUN 是同一层机制
分应用代理不是第二条通道。它和 TUN 用的是同一个 VpnService,允许列表与排除列表由系统在 VPN 层过滤,被排除的 App 流量根本不进虚拟网卡,自然也不进 Xray。所以「开了 TUN 再开分应用代理」不会形成双重代理,只是把接管范围收窄。
权限与后台存活
授权在系统层,存活却取决于厂商的后台策略。国产 ROM 常在息屏几分钟后回收 VPN 服务,表现是状态栏钥匙图标消失、流量统计停止增长、重新打开应用时连接状态已经回到未连接。
- 电池:系统「设置」→「应用」→「v2rayNG」→「电池」,选「不受限制」或关闭电池优化。
- 自启动:在「自启动管理」里允许 v2rayNG 自启,并在最近任务里给应用加锁,防止一键清理时被清掉。
- 后台弹出界面:v2rayNG 弹「连接请求」时不能被系统拦截,允许该权限可以减少授权失败。
- 始终开启的 VPN:Android 7.0 起在「设置」→「网络和互联网」→「VPN」里有「始终开启的 VPN」,可把 v2rayNG 设为常驻,断线后由系统拉起。
- 阻止无 VPN 连接:同一页面里的这一项会让所有流量在 VPN 断开时被切断,调试阶段先别开,否则排查时会把断网原因搞混。
结论:先设后台,再查规则
同一份配置在不同手机上表现不一致,多数来自后台存活策略而不是内核。把电池不优化、自启动、后台锁定三项设好并观察一天,再回头排查 DNS 与路由规则,顺序反过来会浪费大量时间。
验证接管范围
连接状态只说明 VpnService 建链成功,不说明流量真的进了内核。用三个可复现的检查确认接管范围。
- 出口地址比对:先用浏览器访问一个显示出口 IP 的页面,记下直连时的结果;连上 TUN 后再访问同一页面,IP 应变为节点所在地区的地址,运营商字段也随之改变。
- 分应用代理反证:在「分应用代理」里把某个 App 设为绕过,重开该 App 后它应显示本地 IP;把勾选去掉再重开,它应显示节点 IP。两次结果不同,说明 TUN 的 App 级过滤生效。
- 流量统计:打开「设置」→「启用流量统计」,连接后在统计页看上下行是否随浏览增长;数字不动说明流量没有进内核。
常见问题与排查
断开 v2rayNG 后状态栏钥匙图标还在?
钥匙图标由系统 VPN 框架绘制。先在 v2rayNG 主界面点一次断开,图标会随 VpnService 一起消失;如果仍然存在,去系统「设置」→「网络和互联网」→「VPN」查看是否有其它配置处于连接状态,逐个断开。
开了 TUN,某个 App 还是显示本地 IP?
先看「设置」→「分应用代理」:模式选成「绕过所选应用」时,列表里被勾中的 App 就是不走代理的;模式选成「仅代理所选应用」时,没勾的 App 不走代理。两种模式各检查一遍,再重开该 App 复测。
浏览器插件里还填着 127.0.0.1:10808,要改吗?
建议清掉。留着的话请求会先被插件送进本地入站,绕过 TUN 的 App 级过滤——如果分应用代理把浏览器排除了,插件这一层却仍在代理,排查时会得出互相矛盾的结论。
点连接时系统弹「连接请求」,点了取消还会再弹吗?
会。下次点连接会重新请求授权,不会因为取消一次就永久拒绝。如果弹窗彻底不出现,去系统 VPN 列表里删除 v2rayNG 的条目再连一次,授权流程会重新走一遍。
TUN 模式比本地代理费电吗?
会多一点。多出来的开销是 tun2socks 的用户态转发与一次内存拷贝,长时间挂后台时更明显。只在浏览器里用时把 TUN 关掉,或者用分应用代理把范围收窄到必要 App。
排查顺序建议固定下来:先看后台是否存活,再看路由规则是否把目标流量直连,最后看 DNS 解析位置。三步都过一遍仍然不通,再回到节点本身做一次真连接延迟测试。