# 深入 iOS 应用

这是深度导览：iPhone 和 iPad 上 URnetwork 的每个屏幕、各项设置及其出厂默认值，以及通常只装在支持工程师脑子里的疑难解答知识。从安装到连接的短路径见 [iOS 入门](/docs/getting-started-ios)；这一切背后的网络设计见[概览](/docs/overview)。

## 应用的构造

一个 Xcode 项目同时产出 iOS 和 macOS 应用。在你的设备上它以两个进程运行：

- **应用**（bundle `network.ur`）是你看到的界面。
- **隧道扩展**（`network.ur.extension`）是一个由 iOS 亲自启动和监护的网络扩展（`NEPacketTunnelProvider`）。你的流量走的是这个进程，不是应用：它在流量离开设备之前把你手机发送的内容包进加密里（也就是"隧道"）。有四样东西按配置留在隧道之外，任何守规矩的 iOS VPN 都是如此：你的本地网络（打印机、AirPlay、家用设备）、Apple 推送通知、Wi-Fi 通话之类的运营商服务，以及发往你自己附近 Apple 设备的流量。

两个进程通过本地设备 RPC 对话，所以应用重新启动后会接管仍在运行的隧道，而不是拆掉重来。这个拆分就是你把应用划走后 VPN 仍在工作的原因，也是 iOS 第一次要你批准 VPN 配置的原因：扩展是一个由系统管理的组件。那次批准是 Apple 对任何 VPN 应用的标准同意步骤。它不授予对你手机的其他任何控制，并且一直可见、可撤销，位置在设置 → 通用 → VPN 与设备管理。

应用需要 iOS 16.6 或更新版本，一切都在 [github.com/urnetwork](https://github.com/urnetwork) 开源。尚无独立审计覆盖协议或运营方的服务器代码，而隐私承诺正落在那里。2025 年的两项第三方评估覆盖其他层面：对 Web 应用和 API 的渗透测试，以及 Leviathan Security Group 对 Android 应用的 MASA AL2 评估，结果通过。两者都不覆盖 iOS 应用。[威胁模型](/docs/threat-model)记录了这两项评估及其局限。

## 四个标签页

应用是四个标签页：**连接**（Connect）、**账户**（Account）、**排行榜**（Leaderboard）和**支持**（Support）。

### 连接

主屏幕，从上到下：

- **地球。** 你会话的实时画面。连接后，它显示你的流量正在出网的位置：互联网在哪里看到你。你的客户端同时持有多个提供者，通常三到八个，分在并排的两个窗口里（HTTPS 偏好的质量窗口和服务其余流量的速度窗口），并把每个站点固定到其中一个。画面是有意复数的，而任何单个网站看到的仍是一个稳定地址。[概览](/docs/overview)完整讲解提供者窗口。
- **连接按钮。** 一键连接或断开。
- **抽屉。** 按钮下方一张可折叠的面板，容纳你选定的位置、**连接选项**（Connect options）、实时流量图表，以及**拦截广告与跟踪器**（Block ads and trackers）开关。往上拖看到完整内容；已经在连接标签页时再点一次连接标签，抽屉就折回去。共享连接不在这里。它在账户 → 设置里。

点位置卡片打开**可用提供者**（Available providers）面板。它打开时显示你自己的设备、"最佳可用提供者"（Best available provider），以及带在线提供者实时数量的国家。在"搜索提供者"（Search providers）里输入地名，结果里会长出一个**城市**（Cities）区：城市级定位靠搜索到达，不靠滚动。一个位置只在有成员设备在那里在线时才会被列出，平台根据它观察到的连接推导城市，而不是相信提供者自己的申报；看起来像数据中心或 VPN 的地址会被降级而不是被信任。"最佳可用"挑选你附近得分最高的提供者；指定位置让你出现在那里（附近的出口通常最快，因为距离要付延迟的代价）。提供者是共享闲置带宽的其他成员。你的流量到达他们那里时已经是加密的，因为网页在进隧道之前就已经是 HTTPS，所以提供者像 ISP 一样看得到它承载的流量去哪里，但看不到内容，也看不到你的真实地址。

抽屉再往下是四个**连接选项**：

| 设置 | 默认 | 效果 | 主要代价 |
|---|---|---|---|
| 连接模式（Connection Mode） | 自动（Auto） | 自动同时运行两个提供者窗口，把每个数据包路由到合适的那个 | 网页（Web）或流媒体（Streaming）则押注单一窗口 |
| 固定 IP（Fixed IP） | 关 | 把窗口收窄到一个提供者，每个站点都看到同一个稳定地址 | 放弃复数出口 |
| 强匿名化（Strong Anonymization） | 开 | 禁止客户端到提供者的直连路径，提供者永远见不到你的真实 IP | 比直连路径慢 |
| 后量子加密（Post Quantum Encryption） | 开 | 把会话端到端密封到提供者，运营方承载的是密文 | 跳过无法密封的提供者 |

- 固定 IP 在自动之外的模式下可选。
- 关掉强匿名化就是选择直连模式：匿名化跳点退出，你的客户端直接与提供者对话，吞吐量上升，而那个提供者现在看到你的真实地址。默认保护你的身份；只有当你确实想要时，才拿它换速度。
- **拦截广告与跟踪器**，在同一个抽屉里，默认关闭，打开后过滤隧道承载的一切。
- 在两个默认开启的开关之间，提供者永远不知道你是谁，运营方永远读不到你发送的内容。两条不动任何设置就都成立，所以没有任何单独一方同时握有你的身份和你的活动。

这两个开关加上出厂默认就是全景：

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

第一行读作你的默认所在。只要后量子加密开着，客户端就是失败即闭合的：与它无法建立密封会话的提供者会被跳过，而不是明文使用，所以不匹配的代价是失去那个提供者，不是失去你的机密性。把这个开关关掉，才会把你放到第二行。还没有应用显示逐连接的"密封还是没密封"结论，所以告诉你身在何处的是设置，不是会话。局限：没有任何机制验证分配给你的提供者彼此独立、且独立于运营方，运营方自己也可以运行提供者。[威胁模型](/docs/threat-model)把这几行逐一对照具名的对手推演，包括恶意的运营方，并明说每一行在哪里失守。

### 自定义 DNS

连接标签页的详情之下是一整套 DNS 控制面板。DNS 是互联网的电话簿，是把 ur.io 这样的名字变成网络地址的查询，而应答这些查询的一方（解析器）看得到你访问的每个站点的名字。默认是最安全的安排：加密的 DNS over HTTPS，经隧道解析。其余都是你可以主动做的交换：

- **DNS over HTTPS（远程）。** 在隧道远端解析的 DoH。默认项，也最私密：解析器看到的是提供者的地址，不是你的。
- **DNS over HTTPS（本地）。** 直接从你的设备解析的 DoH。
- **不加密 DNS（远程/本地）。** 经典的 UDP DNS，走隧道或直接从设备出发，供需要它的网络和解析器使用。
- **本地 DNS 回退（Local DNS fallback）。** 在隧道启动期间并发使用一个本地解析器，握手时名字查询不至于卡住。关掉后，DNS 只经隧道解析。

解析器清单可以自己编辑（远程和本地 DoH URL、远程和本地 DNS 服务器、IPv4 和 IPv6）。另有两项便利：

- **按国家推荐。** 已知最强的设置在某些国家行不通。当你连接到一个有已知推荐的地方，屏幕会说明，并提供一键"使用推荐设置"（Use recommended settings），以及一键恢复到最安全默认。
- **建议的服务器。** 一份精选的远程 DNS 服务器清单，为你所连国家建议的那些以该国颜色标出。打开某一个就把它加进你的远程解析器清单。

### 分流规则

分流规则让你在域名和 IP 层面把特定流量路由到隧道之外，或把它固定住：

- 连接期间，屏幕显示实时路由活动。点一个域名让它走本地（绕开隧道，于是那个站点看到你的真实地址），或把它按在单个提供者上，让那个站点更长时间地看到一个稳定地址，而不是你平常的复数出口。对任何地址变化都要盘问的银行和登录页很有用。
- 规则作用于域名周围整个协同关联的网络簇，所以相关主机和 CDN 流量被一并捕获，而不是一个子域一个子域地漏。
- 规则持久保存，随时可以在同一屏幕移除。

局限：**iOS 上没有按应用拆分隧道**（Android 和 Windows 有）。iOS 不给 VPN 应用受支持的按应用包含/排除流量的方式，所以在 iPhone 和 iPad 上，分流规则作用于域名和 IP，不作用于应用。

### 共享连接

共享你的闲置带宽是账户 → 设置 → 连接里的四档**共享连接**（Provide mode）选择器，在你改动之前停在**永不**（Never）：

| 模式 | 它承载什么 |
|---|---|
| **永不（Never）** | 什么都不承载。默认。 |
| **自动（Auto）** | 你自己连接时承载公共流量；不连接时只服务你自己的设备 |
| **始终（Always）** | 公共流量，无论你连没连接 |
| **网络（Network）** | 只服务你自己网络的设备，无偿。应用实现的最窄共享 |

几条基本规则。除非你在同一区打开**允许经蜂窝网络共享**（Allow providing on cellular network），共享只用 Wi-Fi，所以它绝不会突然动用你的流量套餐。它运行在隧道进程里，所以手机闲置时也照常工作。你承载的流量是别人的加密会话：你读不了它，它也碰不到你的设备。滥用执法在你的设备上、在流量出网的出口处运行：BitTorrent 和已知攻击模式在那里被丢弃。丢弃不记录任何东西，没有目的地、没有域名、没有内容，不过明文 BitTorrent 命中还会给运营方发一个标记，携带设备 id 和一个布尔值，仅此而已。你承载的公共流量在签名合同下计量，提供者参与 UR protocol。[ur.xyz](https://ur.xyz) 记录了奖励的运作方式。

### 账户

你的身份和套餐住在这里：

- **套餐。** 免费或 Pro、剩余的余额、升级路径，以及你的连接为网络承载过多少的累计数。
- **兑换余额码（Redeem Balance Code）。** 一次性的流量补给，无需订阅。
- **个人资料（Profile）、设置（Settings）、钱包（Wallet）。** 设置是最深的一个：恢复短语、登录方式、设备名、连接（共享连接、蜂窝许可、断网保护、**屏蔽的位置**（Blocked locations）：你永远不想从那里出网的国家）、通知、账户删除，以及一个"使用 UR 协议"（Uses the UR Protocol）链接指向 [ur.xyz](https://ur.xyz)，讲提供者如何获得奖励。
- **检查我的 IP（Check my IP）。** 打开 [ur.io/ip](https://ur.io/ip)，从应用之外确认你的流量真的在别处出网的办法。
- **后量子身份（Post Quantum Identity）。** 即下面那块面板，也是通往你所连提供者身份的路。

### 后量子身份面板

账户底部的面板把你设备的身份显示为一个identicon（由密钥推导的图形，比十六进制更容易用肉眼比对），下方是它的密钥哈希和客户端 id，各自点击即可复制，另有分享面板，以及一叠你当前连接的对端，点开是完整列表。它自己说明了用途：如果某个对端的密钥看起来与本地存储的那份不同，居中的运营方就不可信了。这让"运营方的失明"变得可检验。

它点名的加密就是连接抽屉里的**后量子加密**开关，默认开启，所以你的客户端从第一次连接起就把流量直接密封到提供者。会话是双向认证的 TLS 1.3，密钥来自 **X25519MLKEM768**（经典曲线与 NIST 的 ML-KEM 的混合体），所以运营方中继的是自己无法读取的字节。应答一侧是机会性的：当前所有提供者构建都启用它，所以同一个提供者可以同时服务密封与未密封的用户。你这一侧不是。只要开关开着，客户端就是失败即闭合的，与它无法建立密封会话的提供者会被跳过，而不是明文使用。还没有应用显示逐连接的"密封还是没密封"结论。身份仍是 Ed25519。

### 排行榜

按传输数据量排名的顶级提供者。如果你共享连接，可以出现在这里，公开或匿名，由你选择。

### 支持

标题是"联系我们"（Get in touch）：一个反馈框、星级评分、一个可选的**随反馈附上日志**（Attach logs to feedback）开关，以及一个 Discord 邀请用于实时求助。套餐不在这里；升级在账户标签页。

## Siri 与快捷指令

应用注册了两个 App Intent：**连接 URnetwork VPN**（Connect URnetwork VPN）和**断开 URnetwork VPN**（Disconnect URnetwork VPN）。它们出现在快捷指令应用里，可以用语音触发（"嘿 Siri，连接 URnetwork"），还能串进自动化，比如离开家里 Wi-Fi 时自动连接。

## 不用邮箱开始，以及守住它的短语

登录屏幕上的**创建即时账户**（Create Instant Account）一键给你一个真实、永久的网络。不要邮箱、不要手机号、不要密码，屏幕自己也这么说。保护它的是一份**恢复短语**（seedphrase）：平台生成的一列单词，只在创建后紧接着的那个屏幕上展示一次，之后只保留哈希形式。当场保存它。从一台尚未登录的设备回来，它是唯一的路。趁还有一台登录着的设备，设置 → 恢复短语（Settings → Seedphrase）可以铸一份新短语并作废旧的。保存之后，账户经得起重装或换新 iPhone，套餐和历史完好无损，而设备本地的身份永远做不到。这一切都不是二等待遇：设置 → 登录方式（Settings → Sign-In Methods）可以给同一个网络挂上邮箱、手机号、Apple 或 Google 登录、或一个钱包，保留你的流量余额和历史。匿名在账户里，不在支付里：应用内购买的订阅与你的 Apple 账户绑定，余额码则不与任何人绑定。

## 疑难解答

### VPN 配置的批准

第一次连接会请求添加一个 VPN 配置。如果你拒绝了，隧道就永远起不来。在下一次连接尝试时批准它，或检查设置 → 通用 → VPN 与设备管理，URnetwork 的配置应该列在那里。

### 多个 VPN 配置描述文件，以及应用如何管理它们

经过反复重装和升级，iOS 可能积累不止一份 URnetwork 的 VPN 配置描述文件。应用预料到了这一点：连接时它枚举每一份配置，重置并重试启动失败的，然后转到下一份。如果已经有隧道在运行，它通过设备 RPC 接管那一条而不是重启它。坏掉的配置会被重置或移除，移除有上限所以清理不会失控，而且每次配置操作都有时限，卡死的系统守护进程拖不垮应用。这一切都是自动的。写在这里只是为了当你看到设置里的配置列表时能明白它的来由。

### "Failed to load VPN profiles"（错误 12）

如果连接失败并提示 **"Failed to load VPN profiles"**（无法加载 VPN 配置描述文件，错误代码 12），说明系统的 VPN 偏好存储拒绝枚举配置，这个状态应用无法从内部修复。手动修复：

1. 打开设置 → 通用 → VPN 与设备管理。
2. 移除 URnetwork 的 VPN 配置。
3. 回到应用并连接。系统会请求你批准一份全新配置，隧道干干净净地启动。

### 断网保护在这里如何工作

应用在账户 → 设置 → 连接里带一个**断网保护**（Kill switch）开关，与每个 URnetwork 应用相同的 SDK 控制项，默认关闭。打开后，客户端拒绝回落到你的本地路由，流量停住而不是泄漏到隧道之外。iOS 不给它的是系统级执行。应用没有设置 `includeAllNetworks`，所以如果隧道进程意外死掉，iOS 会恢复正常联网，而不是阻止流量。监护、重试和配置恢复让隧道保持健康，但应用没有要求操作系统硬性闭合失败。如果你的威胁模型要求有保证的"失败即断网"，要为此另做打算。

### 读取隧道的日志

隧道扩展写入统一系统日志，不写文件。要观察它：

1. 把设备连到 Mac，打开 **Console.app**。
2. 选中设备，在操作菜单里启用**包含信息级消息**（Include Info Messages）和**包含调试级消息**（Include Debug Messages）。有意思的行都在这两级。
3. 按 `network.ur.extension` 子系统过滤，或搜索"URnetwork"。

### 睡眠与后台行为

隧道的配置是 `disconnectOnSleep` 关闭：VPN 跨设备睡眠保持在线，而不是每次锁屏都重新握手。配合双进程设计，它也经得起应用被划走。断开是你用按钮、Siri 或移除配置来做的事。

## 接下来去哪里

- 短路径看 [iOS 入门](/docs/getting-started-ios)。
- 同一引擎的 Mac 形态看 [macOS 导览](/docs/tour-macos)。
- 网络本身看 [FAQ](/docs/faq) 和[概览](/docs/overview)。
