# 深入 Windows 应用

这是深度导览：Windows 应用的每个主要界面、它控制什么、默认值是什么，以及出问题时怎么修。它假定你已经安装并连接过。如果还没有，先看[入门指南](/docs/getting-started-windows)。应用背后的网络如何运作，读[概览](/docs/overview)。

Windows 客户端是两个权限不同的程序、一个用于按应用拆分隧道的内核驱动，以及一套与 macOS 应用对齐的 UI。全部开源在 [github.com/urnetwork/windows](https://github.com/urnetwork/windows)。

## 设置一览

默认值不用配置就保护你。下面的每个控制项都在连接抽屉里，只有应用分流规则在设置里。

| 设置 | 默认 | 效果 | 主要代价 |
|---|---|---|---|
| 连接模式（Connection mode） | 自动（Auto） | 决定提供者窗口；自动同时运行质量和速度两个窗口 | 网页（Web）或流媒体（Streaming）收窄到一个窗口 |
| 强匿名化（Strong Anonymization） | 开 | 对提供者隐藏你的来源 IP | 延迟更高 |
| 后量子加密（Post Quantum Encryption） | 开 | 从应用一路加密到提供者 | 跳过无法密封的提供者 |
| 断网保护（Kill switch） | 关 | 隧道断开时停止本地回落 | 提供者失联期间没有流量 |
| 固定 IP（Fixed IP） | 关 | 一个提供者，一个出口地址 | 没有故障切换；自动模式下不生效 |
| 拦截广告与跟踪器（Block ads and trackers） | 关 | 过滤广告和跟踪器流量 | 过滤可能弄坏一些网站 |
| 自定义 DNS（Custom DNS） | 经隧道的加密 DoH | DNS 保持加密并留在隧道内 | 放松它就是那笔交换 |
| 共享连接（Provide mode） | 关 | 把闲置带宽作为出口共享给他人 | 陌生人的流量从你的 IP 出网 |
| 应用分流规则（App split rules） | 空 | 列出的应用绕开隧道 | 它们的流量不受保护 |
| 分流规则（域名/IP）（Split rules） | 空 | 列出的目的地走你的本地连接 | 那些流量不受保护 |

随表附送的注意事项：

- 关掉**强匿名化**就是直连模式：客户端直接与提供者对话、变快，而那个提供者随即看到你的真实地址。默认保护你的身份。要花掉它，就有意识地花。
- 开关设置跨连接模式保持。固定 IP 在你选择网页或流媒体之前不生效。
- 断网保护还决定被安全过滤器丢弃的数据包的去向（见共享连接）：开，直接阻断；关，从你的正常路由离开。
- Windows 上没有删除账户。去管理同一账户的 [Web 应用](https://ur.io/app)里做。

## 两个进程，一条隧道

应用有意拆成两个程序：

- **URnetwork.exe。** 你操作的 WinUI 3 托盘应用。它无特权、在你的用户会话里运行：一个从系统托盘弹出的面板，加一个完整窗口，容纳连接、账户、钱包、排行榜、支持和设置。
- **urnetworkd。** 一个以 LocalSystem（Windows 权限最高的内置账户）运行的 Windows 服务：创建网络适配器和设置路由所需的权力，你点的那个应用永远拿不到。它内嵌 URnetwork SDK，拥有 **wintun** 虚拟适配器，泵送数据包，应用路由、DNS 和 MTU，并让自己的控制流量不走隧道。

两者经两条通道对话，各司其职：

1. **设备 RPC。** 应用的 `DeviceRemote` 通过 SDK 自己的 RPC 驱动服务的 `DeviceLocal`：一条环回上的双向认证 TLS WebSocket。两端都用证书证明身份，连接从不离开你的机器，所以另一个本地程序不能随便连上来指挥服务。你在 UI 里做的一切都走这条通道：连接、选位置、切换共享。
2. **一条命名管道**（`\\.\pipe\urnetwork.control`）。它只承载生命周期和配置：启动和停止隧道、应用拆分隧道规则、登出。它镜像 macOS 应用与其网络扩展的对话方式，让两套代码库保持对齐。

为什么拆分：VPN 隧道需要特权，而 UI 绝不该拥有特权。几乎每个 Windows VPN 都因此是两个程序。你只在安装时、服务注册的那一刻批准一次 UAC 提示。日常使用永远不再要管理员权限。

这也意味着你的保护不取决于窗口是否开着。关掉窗口，它藏进托盘。从托盘菜单退出，隧道还在，因为隧道归服务所有。只有**断开**（Disconnect）、登出或停止服务才会放倒它。

## 窗口

导航栏依次是连接、账户、钱包、排行榜、支持、设置。

**连接**是地球和它下方的抽屉。会话就活在抽屉里：

- **选定位置与对端。** 你正经由什么连接，以及有多少提供者正在承载你的流量。点对端数量可以打开已连接提供者面板：一个地球，下方每个提供者一行，带它的客户端 id、城市/地区/国家、坐标、它在你窗口里待了多久，外加一个就地移除按钮。
- **连接选项（Connect options）。** 连接模式（**自动**、**网页**或**流媒体**：客户端用提供者数量换吞吐量的激进程度），以及上表的四个开关：**固定 IP**、**强匿名化**、**后量子加密**和**断网保护**。
- **客户端统计**与**本地统计**卡片，各自打开一张详情面板：一边是实时合同，另一边是分流规则和被拦流量的活动。
- **自定义 DNS。** 一张状态卡片，下面是完整的解析器编辑器（见下文）。
- **拦截广告与跟踪器。** 一个开关。
- **套餐与用量。** 你的档位、已用/待结/可用条、每日额度、推荐奖励、**获取 UR Pro**（Get UR Pro），以及兑换余额码。

**账户**承载套餐与用量、已兑换的余额码、你的网络名和推荐奖励。**钱包**覆盖你的套餐和升级路径，以及参与 UR protocol（[ur.xyz](https://ur.xyz)）的钱包设置。Bittensor 钱包可以挂上，但只是记录下来留待未来使用，应用也在你预期的位置这么说明。**排行榜**给提供者网络排名。**支持**发送反馈，通向 [feedback.ur.io](https://feedback.ur.io)。**设置**容纳应用分流规则和登出。

进门前有一条提醒：登录屏幕仍然提供**试用访客模式**（Try Guest Mode）。它创建的是一个普通的永久账户，但 Windows 应用会把服务器交回的恢复短语直接扔掉，而这里也没有恢复短语登录。要依赖那个账户之前，先给它挂上邮箱或钱包。

## 托盘

经典 Win32 托盘行为，因为 WinUI 自己没有托盘 API：

- **左键**在托盘图标旁以弹出面板样式打开窗口。
- **右键**给出一个菜单：连接/断开、显示、退出。
- **四种图标状态**镜像 macOS 菜单栏的矩阵（连接与否、共享与否），各有浅色和深色图案，随你的任务栏主题切换。

## 选择提供者，以及这意味着什么

位置选择器就是 SDK 自己的分组：先是已连接的网络对端，然后是最佳可用，然后是带实时提供者数量的**国家**。在搜索框输入，结果重新分区为最佳匹配加上**地区**、**城市**和**设备**。定位是城市级的；城市靠搜索到达，不靠滚动。

每条中继会话背后站着两道保护，哪一道都不需要碰设置。让你的流量出网的提供者永远不知道你是谁，因为运营方站在中间。运营方读不了它转发的数据包，因为后量子加密默认把会话端到端密封到提供者。合在一起，没有任何单独一方同时握有你的身份和你的活动。完整路径，包括把你的加密会话送到运营方的扩展器一段，在[概览](/docs/overview)里。

| 模式 | 运营方看到 | 提供者看到 | 默认与可用性 |
|---|---|---|---|
| **中继密封** | 账户和来源连接、提供者关联、密文及时序和数据量 | 它出网的目的地、一个设备/合同 id，**不含**你的真实 IP | 出厂默认：后量子加密在抽屉里开启 |
| **中继标准** | 账户和来源连接、提供者关联、内层目的地和数据包字节 | 它出网的目的地、一个设备/合同 id，**不含**你的真实 IP | 自行选择开启：关掉后量子加密 |
| **直连** | 更少的中继参与 | **你的真实 IP**及它出网的目的地 | 自行选择开启：关掉强匿名化 |

[威胁模型](/docs/threat-model)把这几行逐一对照具名的对手推演，并明说每一行在哪里失守。

在**自动**模式下两个提供者窗口并排运行，所以流量通常同时从 3–8 个提供者出网，每个站点固定走一个。任何单个提供者只看得到你会话的一小片。网页和流媒体各运行一个更窄的窗口。**固定 IP** 把它收拢成一个提供者、一个出口地址。

## 按应用拆分隧道与驱动

"让这个应用绕开 VPN"——好让游戏保住最低延迟，或者对 VPN 不友好的银行应用留在你的正常连接上——在 Windows 上没法在用户态做好。重定向决策必须发生在创建套接字的地方，在网络栈内部。所以应用带上了 **SplitTunnel.sys**，一个 Windows Filtering Platform（WFP）标注驱动：

- **净室实现。** 对照 Microsoft 的文档和公开规范从头实现，不派生自任何其他厂商的驱动。
- **MPL-2.0 许可**，与应用在同一个开放仓库里开发。
- **按进程，绝不按目的地。** 驱动只注册一个标注，位于 Windows 的绑定重定向层。任何进程打开套接字时，驱动把该进程的可执行文件路径与你的排除清单比对，命中就把套接字的本地地址改写到物理接口，于是这条流从你的正常连接离开。它完全不读远端地址。服务按进程 id 豁免自己的流量。
- **子进程继承。** 启动器的辅助进程跟随你排除的那个应用。
- **放行失败，绝不黑洞。** 如果没有设置物理接口，重定向转为不生效，而不是丢弃流量。

清单在**设置 → 应用分流规则**（app split rules）里管理。三个局限。进程已经打开的套接字保持原路径，直到它们重连。被排除应用的 DNS 查询仍走 Windows 的共享解析服务，所以即使应用本身不走隧道，它的查询也可能走。而且驱动是构建期选项：不带它打包的 MSI 装出来的隧道照常工作，只是没有按应用规则。

另外，连接抽屉里的**分流规则面板**做的是经隧道自身的域名和 IP 级规则，与 Apple 和 Linux 应用相同的界面。两者可以叠加：驱动按应用决定，规则按目的地决定。

## 让服务避开自己的隧道

隧道进程有一个自举问题：它自己发往平台的流量绝不能走它创建的隧道，否则第一个数据包就永远打转。服务在套接字层解决它。SDK 暴露一个出口绑定钩子，服务把自己的控制和中继套接字钉在物理接口上，由一个出口监视器跟踪，在每次网络变化（Wi-Fi 换以太网、适配器出现和消失）时重新计算正确的接口。

## 路由与 DNS

隧道起来时，服务不删除你的默认路由。它出更高的价：整个 IPv4 空间**除去**私有局域网段（10.0.0.0/8、172.16.0.0/12、192.168.0.0/16）被装成一组更精确的路由，走隧道适配器。它们赢过你现有的默认路由而不动它，拆除就是把它们移走，你的打印机和 NAS 在本地照常工作。隧道适配器从 SDK 获得地址和 1440 的 MTU，网络的解析器设置在那个适配器上。

三个你可以拿来要求应用的局限：

- **DNS 按适配器设置，Windows 也按适配器解析。** 应用自己的 DNS 设置（自定义 DNS 面板，默认是经隧道解析的加密 DNS-over-HTTPS）才是这里有意义的保护。如果你跑着不寻常的解析器配置，查一查你的查询实际去了哪。
- **隧道承载 IPv4。** IPv6 今天不经它路由，所以在启用 IPv6 的网络上，支持 v6 的站点仍可能看到你的真实地址。如果你需要一切都从提供者出网，就在该连接上禁用 IPv6。
- **失败即断网是一个开关，不是一个假设。** 断网保护关着，隧道停了就意味着 Windows 回落到你的正常连接。打开它，流量改为停住。它是 SDK 的 `SetRouteLocal` 原语取反，每个 URnetwork 应用绑定的都是同一个，出厂默认关闭。

## 自定义 DNS

与 Apple 和 Linux 应用相同的跨平台解析器面板。默认是最严格的选项：加密的 DNS over HTTPS，经隧道解析。你可以有意识地做交换：DoH 或不加密、远程或本地解析、可编辑的服务器清单、一个在隧道启动期间并发本地解析器让查询不卡住的本地 DNS 回退开关，以及一键恢复安全默认。

## 共享连接

共享默认关闭，位置在连接抽屉里：**自动**（Auto）、**始终**（Always）、**网络**（Network，只对你自己账户的设备）或**永不**（Never）。提供者参与 UR protocol；[ur.xyz](https://ur.xyz) 记录了奖励的运作方式。

你共享时保护你的，是连接引擎的开源 `ip_security` 层。它在你自己的出口上检查流量，在 DMCA 类流量（有状态的 BitTorrent 和文件共享特征、不透明协议丢弃）和 CFAA 类流量（攻击与入侵模式）离开你的连接之前把它们丢弃。命中就是丢包，不记录目的地、域名或内容。你替别人承载的流量上如果命中明文 BitTorrent 特征，还会给运营方发送一个滥用标记，只含对端设备 id 和一个布尔值，别无其他，而运营方今天没有处理它的代码。同一个过滤器无论你共不共享都跑在你自己的发送路径上，而你自己的流量从不被上报。密封绕不开这个过滤器，因为它运行在流量出网的地方。[概览](/docs/overview)完整讲解这一层。

## 后量子加密到底做什么

你的客户端在一条以 **X25519MLKEM768**（经典加 ML-KEM 混合）协商的会话上，把流量端到端密封到提供者。这条密封的段就是让中间跳失明的东西：运营方承载着自己读不了的字节。它默认开启，并且失败即关闭：只要它开着，客户端就不会以明文发送或接收应用数据，因此无法与之建立密封会话的提供者会被跳过，而不是不加密封地使用。当前所有提供者构建都启用应答一侧，所以实际上密封是自动的。代价在可用性，不在机密性：你可能失去一个提供者，但绝不会失去你的加密，也不存在悄无声息的降级。把这个开关关掉，流量才可以重新走标准的 TLS 到平台路径。身份签名仍是 Ed25519，加密算法是 AES-256-GCM。"后量子"指的就是这次密钥交换，不指更多。

局限：Windows 应用没有身份检查面板。没有可以带外比对的密钥指纹，也没有告诉你这条会话是否密封成功的逐连接结论。已连接提供者面板是最接近的界面。

## 签名与更新

- **Windows 10 21H2 或更新版本以及 Windows 11**，x64 和 ARM64，从发布页获取按机安装的 MSI。ARM64 是原生构建，不是模拟。
- **应用、服务和安装器**都有 Authenticode 签名。
- **驱动**要求更多：EV 证书加上 Microsoft 的证明签名（attestation signing）。Windows 只加载有证明签名的驱动，所以这是加载门槛，不是仪式。
- **驱动打包在 MSI 里。** 运行时不下载任何东西；安装器里有什么，跑的就是什么。钉住的第三方依赖（wintun）在打包前按哈希和上游签名者核验。
- **更新是服务的事，不是商店的事。** Microsoft Store 不为 EXE/MSI 上架推送更新，而 MSIX 包（商店确实自动更新的那种）无法干净地携带内核驱动。所以更新路径走 `urnetworkd`：抓取、验证签名、替换二进制。每次更新不弹 UAC，安全修复也不用等商店审核。Windows 同样守卫这个模式：服务二进制只有在新旧两者由同一发布者签名时才能被替换。

## 疑难解答

### 应用说连不上服务

隧道住在 `urnetworkd` 里。在**服务**里（或 `sc query urnetworkd`）确认它在运行；它注册为自动启动，失败后自动重启两次。如果它停了又起不来，重装 MSI，重新注册服务。

### 已连接，但某个应用没有网络

查看**设置 → 应用分流规则**。排除清单上的应用按设计绕开隧道，如果你排除的东西随后在你的正常连接上够不到某个服务，那正是规则在起作用。更改在该应用下一次建立连接时生效，因为已打开的套接字保持原路径，所以重启那个应用。

### 按应用拆分隧道不可用

驱动是安装器里的可选功能。重新运行 MSI，确认选中了拆分隧道功能。内核驱动还要求证明签名的构建；自行编译的驱动在未处于测试签名模式的机器上不会被加载。

### 网站仍然看到我的真实地址

几乎总是 IPv6。隧道今天承载 IPv4；在网络适配器上禁用 IPv6 再测。第二可能：按适配器的 DNS 路径，自定义 DNS 面板的默认值（经隧道的 DoH）正是为堵上它设计的。

### 切换网络后流量停滞

在 Wi-Fi 和以太网之间移动会改变服务必须把自己套接字钉在哪个接口上。它会监视并重新计算，但如果某个会话卡死了，断开再重连，干净重建。

### 退出时什么都没发生

这正是设计：退出托盘应用，隧道继续在服务里运行。用**断开**。

## 其他文档

[概览](/docs/overview)端到端讲解这个网络：提供者、合同、各方能看到什么和不能看到什么，以及加密。[FAQ](/docs/faq) 回答常见问题。其他平台：[Android](/docs/getting-started-android)、[iOS](/docs/getting-started-ios)、[macOS](/docs/getting-started-macos)、[Linux](/docs/getting-started-linux)，以及[浏览器](/docs/getting-started-browser)。
