Pangolin 客户端 · 断网保护设计依据与现状 · 2026-06-22
KillSwitch 的本质是 fail-closed:
目标是堵住 VPN 掉线瞬间的 IP / DNS 泄漏。没有 KillSwitch 时,隧道一掉,流量静默回落到运营商默认路由,用户真实 IP 与 DNS 查询直接暴露——对科学上网场景是致命泄漏。
| Level | 机制 | 能堵什么 | 堵不住什么 |
|---|---|---|---|
| L0 无 | 掉线即走明文 | — | 全泄漏 |
| L1 内核路由绑定(软) | 路由绑死隧道接口(如 sing-box strict_route) | 进程活着、隧道未建/重连时不泄漏 | 进程一死、接口被拆 → 路由恢复 → 泄漏 |
| L2 OS 防火墙强制(硬) | OS 级包过滤规则(NE 框架 / WFP / nftables)阻断非隧道流量 | 进程死了也照堵(规则在 OS 内核,不在 app) | 开机到规则生效前的窗口 |
| L3 常开 + 开机持久 | L2 + OS 从开机起自动拉起 VPN 并强制阻断 | 开机窗口也堵,全程 fail-closed | (基本无死角) |
理想态 = L3。
strict_route 都还停在 L1。
| 平台 | 机制 | 天花板 | 说明 |
|---|---|---|---|
| macOS | NetworkExtension System Extension | L3 | includeAllNetworks=true 全量入隧道 + NEOnDemandRule 常开 + enforceRoutes。NE 守护进程(neagent)在系统级强制,扛 app 崩溃。Apple 平台原生支持最完整。 |
| iOS | NetworkExtension | L3 | 同 NE 原语,甚至更干净;on-demand「按需常开」。⚠️ 目前无 iOS 客户端。 |
| Android | VpnService | L3,但有条件 | app 内只能到 L1(strict_route);真正的 L2/L3 = 系统设置「始终开启 VPN + 无 VPN 时阻止连接」,OS 级强制、扛崩溃、开机生效。但 app 不能编程开启,只能深链引导用户手动开(或 Device Owner/MDM 下发)。 |
| Windows | 子进程 sing-box + wintun | L2(需开发) | 现仅 strict_route(L1)。要到 L2 须让 app 装 WFP(Windows Filtering Platform)过滤器阻断非隧道流量;做成系统服务持久化才能扛崩溃。 |
| Linux(非主目标) | 子进程 + tun | L2(需开发) | L1 现成;L2 靠 nftables/iptables killswitch 链。 |
一句话:Apple 两端原生能直达 L3;Android 能到 L3 但要用户手动配合;Windows/Linux 要自己写 OS 防火墙规则才能上 L2。
| 平台 | 当前 Level | 真实状态 | 代码位置 |
|---|---|---|---|
| Windows | L1 | ✅ 改 strict_route + 子进程重载 + 退避重连。进程被硬杀仍泄漏。 | desktop_vpn_bridge.dart:305(applyKillSwitchToConfig)、:178 |
| Linux | L1 | 同 Windows(共用 DesktopVpnBridge)。 | 同上 |
| macOS | L0 | ❌ stub:setKillSwitch 直接 result(nil),includeAllNetworks()→false。天花板 L3,实际啥都没做。 | VpnChannel.swift:69、PacketTunnelProvider.swift:224 |
| Android | L0 | ❌ stub:setKillSwitch 只打日志(TODO 11G)。 | MainActivity.kt(setKillSwitch 分支) |
| iOS | — | 无客户端。 | — |
注:macOS 自 kUseNativeVpnMacOS=true(vpn_bridge_provider.dart:19)起走原生 System Extension,不再走 DesktopVpnBridge。所以 macOS 的 strict_route(Windows 路线)对它不生效,必须走 NE 原生路线。
strict_route,与 Windows 一致),再引导用户开系统 Always-on 拿到 L3,UI 上诚实标注「彻底防泄漏需在系统设置开启」。这是「app 能力上限 + OS 兜底」的合理组合,不夸大。includeAllNetworks + on-demand)—— 天花板 L3、改动集中在 Swift,性价比最高。KillSwitch 相关待办见项目 todo/(/todo list),主要三条:
includeAllNetworks + on-demand)strict_route)+ 引导系统 Always-on(属 Android 客户端 11G)| 主题 | 文件 |
|---|---|
桥接契约(setKillSwitch 方法签名) | client/lib/bridge/vpn_bridge.dart |
| 平台分派(哪个平台走哪个 bridge) | client/lib/bridge/vpn_bridge_provider.dart |
| Windows/Linux 实现(strict_route) | client/lib/bridge/desktop_vpn_bridge.dart |
| macOS 原生通道(stub) | client/macos/Runner/VpnChannel.swift |
| macOS 隧道 Provider | client/macos/PacketTunnel/PacketTunnelProvider.swift |
| Android 通道(stub) | client/android/app/src/main/kotlin/com/pangolin/pangolin_vpn/MainActivity.kt |
| Android VPN 服务 | client/android/app/src/main/kotlin/com/pangolin/pangolin_vpn/PangolinVpnService.kt |