首页 下载中心 在线测速 使用文档 关于与赞助

跨平台代理客户端开发实战指南

从系统代理、TUN/VPN、DNS、路由回环,到 Rust Platform Adapter 与移动端嵌入全流程架构指南。

面向: Mihomo / sing-box 等代理内核
客户端: Flutter / Rust / Electron / 原生 GUI
平台: Windows、Linux、macOS、Android、iOS
目标: 从系统代理、TUN/VPN、DNS、路由回环,到 Rust Platform Adapter 与移动端嵌入,建立一套可以真正落地开发的跨平台代理客户端架构。

0. 先明确:我们到底在开发什么

一个代理客户端并不是“把订阅链接导入,然后启动一个代理内核”这么简单。

真正的客户端至少需要解决三个问题:

  1. Core:流量应该怎么处理?
  2. Platform:操作系统的流量怎么进入 Core?
  3. GUI / Backend:用户怎么控制 Core 与 Platform?

因此可以把整个系统拆成:

TEXT
┌──────────────────────────────────────────────┐
│                    GUI                       │
│       Flutter / Tauri / Native / Electron   │
└──────────────────────┬───────────────────────┘
                       │
                       │ IPC / FFI / API
                       ▼
┌──────────────────────────────────────────────┐
│               Client Backend                 │
│                                              │
│  配置 / 订阅 / 节点 / 状态机 / 生命周期 / 日志 │
└───────────────┬───────────────────┬──────────┘
                │                   │
                ▼                   ▼
       ┌────────────────┐   ┌──────────────────┐
       │   Proxy Core   │   │ Platform Adapter │
       │                │   │                  │
       │ Mihomo         │   │ Windows          │
       │ sing-box       │   │ Linux            │
       │                │   │ macOS            │
       │ DNS            │   │ Android          │
       │ Routing        │   │ iOS              │
       │ Proxy          │   │                  │
       │ TUN/tun2socks  │   │ System / TUN/VPN  │
       └────────┬───────┘   └────────┬─────────┘
                │                    │
                └──────────┬─────────┘
                           ▼
                  Operating System

核心原则:

GUI 不负责代理流量。Client Backend 不负责底层网络。Proxy Core 负责代理逻辑,Platform Adapter 负责操作系统网络接管。

这也是后续所有设计的基础。


1. 代理客户端的两种基本工作模式

绝大多数客户端首先可以抽象为两种模式:

TEXT
System Proxy
TUN / VPN

它们不是两个不同的“代理协议”,而是两种把流量交给 Proxy Core 的方式。


2. System Proxy:让应用主动连接 Core

System Proxy 的逻辑非常简单。

假设 Core 监听:

TEXT
HTTP   127.0.0.1:7890
SOCKS  127.0.0.1:7891

客户端修改操作系统代理:

TEXT
HTTP  → 127.0.0.1:7890
HTTPS → 127.0.0.1:7890
SOCKS → 127.0.0.1:7891

数据流:

TEXT
Application
     │
     │ HTTP / HTTPS / SOCKS
     ▼
OS Proxy Configuration
     │
     ▼
127.0.0.1:7890
     │
     ▼
Proxy Core
     │
     ├── DIRECT
     │
     └── PROXY

这里最重要的概念是:

System Proxy 并没有接管 IP 层流量。它只是告诉支持代理的应用:“如果你需要代理,请连接这个地址。”

因此:

TEXT
浏览器
     ↓
读取系统代理
     ↓
127.0.0.1:7890
     ↓
Core

可能正常。

但是:

TEXT
某些游戏
某些后台服务
某些 CLI
某些 UDP 应用
某些自己实现网络栈的程序

可能完全不读取系统代理。

所以 System Proxy 的特点是:

特性 System Proxy
实现难度 低
权限需求 低
CPU 开销 低
全局接管 否
UDP 取决于应用
游戏 不保证
后台程序 不保证
DNS 不一定经过 Core

3. TUN:直接接管 IP 流量

TUN 的思路完全不同。

System Proxy:

TEXT
应用 → 主动连接代理

TUN:

TEXT
应用 → 操作系统网络栈 → TUN → Core

典型数据流:

TEXT
Application
     │
     ▼
Operating System Network Stack
     │
     ▼
TUN Interface
     │
     │ IPv4 / IPv6 Packet
     ▼
Tun2socks / User-space Network Stack
     │
     │ TCP / UDP
     ▼
Proxy Core
     │
     ├── DNS
     ├── Routing
     ├── DIRECT
     └── PROXY
     │
     ▼
Physical Network
     │
     ▼
Internet

所以:

TEXT
System Proxy
= 应用主动使用代理

TUN
= 系统把 IP 流量送到虚拟网络接口

4. 为什么 TUN 不能直接交给 SOCKS?

这是理解 TUN 的关键。

TUN 读到的是:

TEXT
IPv4 / IPv6 Packet

例如一个 TCP 数据包:

TEXT
┌────────────────────────────────┐
│ IPv4 Header                    │
├────────────────────────────────┤
│ TCP Header                     │
├────────────────────────────────┤
│ Application Payload            │
└────────────────────────────────┘

而 SOCKS5、Shadowsocks、VLESS、Trojan 等代理协议通常需要的是:

TEXT
TCP Stream

或者:

TEXT
UDP Datagram

因此需要一个转换层:

TEXT
L3 IP Packet
      │
      ▼
┌──────────────────┐
│   tun2socks       │
│ / user-space stack│
└────────┬─────────┘
         │
         ▼
TCP / UDP
         │
         ▼
Proxy Protocol

常见实现思路包括:

TEXT
gVisor Netstack
lwIP
系统网络栈
Core 自带用户态协议栈

这里不要把 tun2socks 理解成“另一个代理”。

它解决的是:

如何把 TUN 中的 IP 数据包还原成 Core 能处理的 TCP / UDP 流。

5. TUN 最危险的问题:Routing Loop

这是开发 TUN 客户端必须首先解决的问题。

假设:

TEXT
代理服务器:
1.2.3.4:443

正常情况下:

TEXT
Core
 ↓
1.2.3.4:443
 ↓
Internet

但是你设置了:

TEXT
0.0.0.0/0 → TUN

于是 Core 发出的连接也可能被送进:

TEXT
TUN
 ↓
Core
 ↓
TUN
 ↓
Core
 ↓
...

形成:

TEXT
Routing Loop

结果可能是:

  • CPU 飙升
  • 网络带宽异常
  • Core 不断建立自身连接
  • 整机断网
  • DNS 失效
  • TUN 无法关闭

因此 TUN 客户端有一个非常重要的原则:

Core 自己连接代理服务器的流量,必须绕过当前 TUN。

不同平台实现方式不同。


6. Windows 防回环

Windows 常见思路:

TEXT
TUN 全局接管
       │
       ├── 普通应用 → TUN
       │
       └── Proxy Core → Physical NIC

可以使用:

TEXT
IP_UNICAST_IF
WFP
进程 / PID 过滤
物理网卡 IfIndex 绑定

核心思想不是“让 Core 不联网”,而是:

让 Core 的出站 socket 明确走物理网络接口。

例如:

TEXT
Application
    ↓
Wintun
    ↓
Core
    │
    ├── 普通代理流量
    │
    └── Core → Proxy Server
                  ↓
             Physical NIC

而不是:

TEXT
Core → Wintun → Core

7. Linux 防回环:Policy Routing

Linux 的一个典型方案是:

TEXT
普通流量
    ↓
TUN

Core 流量
    ↓
fwmark
    ↓
独立路由表
    ↓
Physical NIC

概念上:

TEXT
┌──────────────────────────┐
│ Main Routing Table       │
│ default → tun0           │
└──────────────────────────┘

┌──────────────────────────┐
│ Table 100                │
│ default → Physical NIC  │
└──────────────────────────┘

Core 的 socket:

TEXT
SO_MARK = 0x1

然后:

TEXT
ip rule

把:

TEXT
fwmark 0x1

导向:

TEXT
table 100

这样:

TEXT
Core
 ↓
mark 0x1
 ↓
table 100
 ↓
eth0 / wlan0
 ↓
Internet

而普通应用:

TEXT
Application
 ↓
main routing
 ↓
tun0
 ↓
Core

8. Android 防回环:protect()

Android 是这个问题最典型的平台。

Android 提供:

TEXT
VpnService

当 VPN 接管:

TEXT
0.0.0.0/0

以后,Core 自己创建的 socket 也可能被 VPN 捕获。

因此 Core 创建:

TEXT
socket()
connect(proxy_server)

之前,需要:

TEXT
VpnService.protect(socket)

逻辑:

TEXT
Application
     ↓
VPN
     ↓
Core
     │
     │ protect(socket)
     ▼
Physical Wi-Fi / Cellular
     ↓
Proxy Server

没有 protect():

TEXT
Core
 ↓
VPN
 ↓
Core
 ↓
VPN
 ↓
...

因此在 Android 平台,protect() 不是可选优化,而是 VPN Core 集成中的关键机制。


9. DNS 为什么是代理客户端的核心问题

TUN 不仅仅要处理 TCP / UDP。

DNS 同样需要考虑。

如果:

TEXT
Application
 ↓
公网 DNS
 ↓
真实 IP

那么可能出现:

TEXT
DNS Leak
DNS 污染
域名分流失效

例如规则:

TEXT
DOMAIN-SUFFIX,google.com,PROXY

如果应用首先把:

TEXT
google.com

解析成:

TEXT
142.x.x.x

Core 后面只看到:

TEXT
142.x.x.x:443

那么基于域名的路由信息可能已经丢失。


10. Fake-IP

因此许多代理 Core 会采用 Fake-IP。

例如:

TEXT
Application
    │
    │ DNS: google.com
    ▼
Proxy Core DNS
    │
    ▼
198.18.0.23

Core 保存:

TEXT
198.18.0.23
        ↕
google.com

之后:

TEXT
Application
 ↓
198.18.0.23:443
 ↓
TUN
 ↓
Core

Core 查询映射:

TEXT
198.18.0.23
      ↓
google.com

然后:

TEXT
google.com
      ↓
Routing Rules
      ↓
PROXY
      ↓
Proxy Node

这样 Core 即使收到的是 Fake-IP,也能够恢复原始域名。


11. Fake-IP 的数据结构

逻辑上可以理解成:

RUST
struct FakeIpEntry {
    ip: IpAddr,
    domain: String,
    expires_at: Instant,
}

映射:

TEXT
198.18.0.23 → google.com
198.18.0.24 → github.com
198.18.0.25 → example.com

实际 Core 的实现可能更加复杂,但客户端架构需要理解的核心就是:

TEXT
DNS Query
   ↓
Fake-IP allocation
   ↓
Mapping table
   ↓
TUN packet
   ↓
Restore domain
   ↓
Routing

12. Windows:System Proxy

Windows 系统代理通常可以通过:

TEXT
HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings

配置。

典型字段:

TEXT
ProxyEnable
ProxyServer
ProxyOverride

例如:

TEXT
ProxyEnable = 1

ProxyServer =
127.0.0.1:7890

ProxyOverride =
<local>;localhost;127.*;10.*;192.168.*

修改后还需要通知系统刷新设置:

C
InternetSetOptionW(
    NULL,
    INTERNET_OPTION_SETTINGS_CHANGED,
    NULL,
    0
);

InternetSetOptionW(
    NULL,
    INTERNET_OPTION_REFRESH,
    NULL,
    0
);

13. Windows 客户端不能直接“关闭代理”

这是很多客户端容易犯的错误。

假设用户原本:

TEXT
ProxyEnable = 1
ProxyServer = 192.168.1.10:8080
PAC = ...

启动你的客户端:

TEXT
保存原配置
     ↓
设置 127.0.0.1:7890

退出时必须:

TEXT
恢复原配置

而不是:

TEXT
ProxyEnable = 0

否则你的客户端会破坏用户原来的网络环境。

因此 Backend 应该维护:

RUST
struct PreviousProxyState {
    enabled: bool,
    server: Option<String>,
    bypass: Option<String>,
    pac_url: Option<String>,
}

14. Windows:TUN

Windows 没有像 Linux /dev/net/tun 那样直接给用户态使用的标准 TUN 文件接口。

代理客户端通常使用:

TEXT
Wintun

典型结构:

TEXT
Applications
      ↓
Windows TCP/IP Stack
      ↓
Wintun
      ↓
Proxy Core
      ↓
Routing / DNS / Proxy
      ↓
Physical NIC

Platform Adapter 需要负责:

TEXT
创建 Wintun
配置 IP
配置路由
启动 / 停止接口
清理路由
恢复系统状态

15. Windows 权限模型

不要让整个 GUI:

TEXT
Administrator

运行。

推荐:

TEXT
┌──────────────────────┐
│ GUI                  │
│ 普通用户              │
└──────────┬───────────┘
           │
           │ Named Pipe / IPC
           ▼
┌──────────────────────┐
│ Privileged Service   │
│ Windows Service      │
│                      │
│ Wintun               │
│ Route                │
│ Firewall / WFP       │
└──────────────────────┘

这样:

TEXT
GUI

只负责 UI。

而:

TEXT
Service

负责需要管理员权限的操作。


16. Linux:System Proxy

Linux 没有一个统一覆盖所有程序的“系统代理 API”。

常见来源包括:

TEXT
GNOME
KDE
Environment Variables
Application-specific settings

环境变量:

BASH
export HTTP_PROXY=http://127.0.0.1:7890
export HTTPS_PROXY=http://127.0.0.1:7890
export ALL_PROXY=socks5://127.0.0.1:7891
export NO_PROXY=localhost,127.0.0.1

GNOME 可以使用:

BASH
gsettings

KDE 则存在对应桌面配置机制。

因此 Linux System Proxy 的重要结论:

桌面代理设置是约定,不等于系统级流量接管。

17. Linux:TUN

Linux 提供:

TEXT
/dev/net/tun

创建 TUN 后:

TEXT
Application
    ↓
Linux Network Stack
    ↓
tun0
    ↓
Proxy Core

需要处理:

TEXT
TUN
IP address
Routing
Policy Routing
DNS
Firewall
Permissions

典型检查:

BASH
ip addr
ip route
ip rule

18. Linux 权限分离

推荐:

TEXT
GUI
 ↓
Unix Socket / D-Bus
 ↓
Privileged Helper
 ↓
TUN / Route / Firewall

而不是:

TEXT
Flutter GUI
 ↓
sudo
 ↓
各种 shell 命令

对于需要的能力,可以考虑:

TEXT
CAP_NET_ADMIN
CAP_NET_BIND_SERVICE
Polkit
systemd service

例如原始文档中的一种方案:

BASH
sudo setcap cap_net_admin,cap_net_bind_service=+ep /path/to/proxy-core

但实际产品中仍需要根据发行版、安全模型和安装方式决定最终权限方案。


19. macOS:System Proxy

macOS 的系统代理可以通过:

TEXT
SystemConfiguration
networksetup

处理。

例如:

BASH
networksetup -setwebproxy "Wi-Fi" 127.0.0.1 7890
networksetup -setsecurewebproxy "Wi-Fi" 127.0.0.1 7890
networksetup -setsocksfirewallproxy "Wi-Fi" 127.0.0.1 7891

关闭:

BASH
networksetup -setwebproxystate "Wi-Fi" off
networksetup -setsecurewebproxystate "Wi-Fi" off
networksetup -setsocksfirewallproxystate "Wi-Fi" off

产品级实现应优先使用系统 API,而不是简单依赖 shell。


20. macOS:Network Extension

macOS 网络接管可以围绕:

TEXT
Network Extension

设计。

核心组件:

TEXT
NEPacketTunnelProvider

逻辑:

TEXT
Main App
   │
   ▼
VPN Configuration
   │
   ▼
System Extension
   │
   ▼
NEPacketTunnelProvider
   │
   ▼
Proxy Core

主 App 和 Extension 是不同运行环境。

因此需要设计:

TEXT
配置同步
状态同步
启动 / 停止
错误传递
IPC

21. Android:VpnService

Android 与桌面最大的不同是:

Android 的官方系统级流量接管入口就是 VpnService。

基本代码结构:

KOTLIN
class LocalVpnService : VpnService() {

    private var vpnInterface: ParcelFileDescriptor? = null

    fun startVpn() {
        val builder = Builder()
            .setSession("ProxyClient")
            .setMtu(1500)
            .addAddress("172.19.0.1", 30)
            .addRoute("0.0.0.0", 0)
            .addRoute("::", 0)
            .addDnsServer("198.18.0.1")

        vpnInterface = builder.establish()
    }
}

关键 API:

TEXT
Builder.establish()
addAddress()
addRoute()
addDnsServer()
addAllowedApplication()
addDisallowedApplication()
protect()

22. Android VPN 到底是不是“远程 VPN”?

不是。

这里必须区分两个概念。

Android:

TEXT
VpnService

只是建立:

TEXT
本地虚拟网络接口

它并不意味着:

TEXT
Android → 某个 VPN 服务器

真正的链路可能是:

TEXT
Android
 ↓
VpnService
 ↓
Proxy Core
 ↓
Shadowsocks / VLESS / Trojan / ...
 ↓
Remote Proxy Server
 ↓
Internet

因此:

TEXT
VpnService = 系统流量接管机制

代理节点 = Core 的远程出站

二者不是一回事。


23. Android:按 App 分流

Android 可以利用:

KOTLIN
addAllowedApplication()
addDisallowedApplication()

实现:

TEXT
白名单
黑名单
Split Tunnel

例如:

TEXT
Chrome → VPN
Steam → VPN
微信 → DIRECT

最终由:

TEXT
VpnService Builder

决定哪些应用进入 VPN。


24. Android:Core 如何运行

桌面可以:

TEXT
启动 mihomo.exe

Android 不应该简单照搬这种模式。

推荐:

TEXT
Flutter / Native
       │
       ▼
Kotlin VpnService
       │
       │ tunFd
       ▼
Native Core

Core 可以根据实现选择:

TEXT
.so
JNI
C ABI
AAR
Rust library

例如:

TEXT
Kotlin
  │
  ├── establish()
  │
  ├── tunFd
  │
  └── protect()
          │
          ▼
       Rust Core

25. Android:tunFd 的生命周期

这里是移动端开发最容易出问题的地方之一。

流程应该是:

TEXT
用户点击启动
      ↓
请求 VPN 权限
      ↓
VpnService 启动
      ↓
Builder.establish()
      ↓
获得 ParcelFileDescriptor
      ↓
获得 tunFd
      ↓
把 fd 交给 Native Core
      ↓
Core 开始读取 Packet

停止:

TEXT
用户点击停止
      ↓
停止 Core
      ↓
停止所有出站连接
      ↓
关闭 TUN
      ↓
关闭 ParcelFileDescriptor
      ↓
VpnService stop

不能让 Core 在 fd 已经关闭以后继续读写。


26. Android:protect() 的调用链

建议把它抽象成:

TEXT
Rust Core
   │
   │ connect(proxy_server)
   ▼
Native socket
   │
   │ JNI / callback
   ▼
Kotlin VpnService.protect(fd)
   │
   ▼
Android Network
   │
   ▼
Physical Interface

因此 Platform Adapter 可以提供:

RUST
trait SocketProtector {
    fn protect(&self, fd: RawFd) -> Result<(), PlatformError>;
}

Android:

TEXT
protect(fd)

Linux:

TEXT
fwmark

Windows:

TEXT
interface binding / WFP

这样 Core 不需要知道:

TEXT
Android
Windows
Linux

只需要调用抽象接口。


27. iOS:Network Extension

iOS 的系统级网络接管主要围绕:

TEXT
Network Extension
NEPacketTunnelProvider

Main App:

TEXT
Flutter / SwiftUI

Extension:

TEXT
NEPacketTunnelProvider

二者不能简单理解为一个普通进程。

结构:

TEXT
┌────────────────────────┐
│ Main App               │
│ Flutter / SwiftUI      │
└───────────┬────────────┘
            │
            │ VPN configuration
            ▼
┌────────────────────────┐
│ Network Extension      │
│                        │
│ NEPacketTunnelProvider │
│        │               │
│        ▼               │
│    Proxy Core          │
└───────────┬────────────┘
            │
            ▼
      iOS Network Stack

28. iOS:packetFlow

iOS 不让开发者直接照搬桌面:

TEXT
/dev/net/tun

而是提供:

TEXT
packetFlow

读取:

SWIFT
packetFlow.readPackets { packets, protocols in
    // process packets
}

写回:

SWIFT
packetFlow.writePackets(
    packets,
    withProtocols: protocols
)

因此:

TEXT
iOS kernel
    ↓
packetFlow
    ↓
Proxy Core
    ↓
packetFlow
    ↓
iOS kernel

29. iOS:主 App 与 Extension

主 App:

TEXT
订阅
节点
配置
UI
状态

Extension:

TEXT
VPN
Packet
Core
Routing
DNS

共享配置通常需要:

TEXT
App Group

逻辑:

TEXT
Main App
   │
   │ shared container
   ▼
App Group
   ▲
   │
Network Extension

因此不要设计成:

TEXT
Flutter UI 直接控制 packetFlow

而应该:

TEXT
Flutter
 ↓
Native iOS layer
 ↓
VPN Manager
 ↓
Network Extension
 ↓
Core

30. 五个平台真正的差异

平台 System Proxy TUN / VPN 核心入口 防回环
Windows WinINet / 系统配置 Wintun Wintun + 路由 接口绑定 / WFP
Linux GNOME / KDE / 环境变量 /dev/net/tun TUN + ip rule fwmark / policy routing
macOS SystemConfiguration Network Extension / utun 路线 NEPacketTunnelProvider 路由 / Extension 机制
Android 有限系统代理能力 VpnService ParcelFileDescriptor protect()
iOS 能力受限 Network Extension NEPacketTunnelProvider 平台网络扩展机制

真正应该抽象的不是:

TEXT
Windows = TUN
Linux = TUN
Android = TUN

而是:

TEXT
Platform Adapter
        │
        ├── Create Traffic Capture
        ├── Configure Routing
        ├── Configure DNS
        ├── Protect Core Egress
        ├── Configure System Proxy
        └── Restore System State

31. PlatformAdapter

Rust 可以把平台差异收敛到一个接口。

RUST
pub trait PlatformAdapter: Send + Sync {

    fn enable_system_proxy(
        &self,
        settings: &SystemProxySettings,
    ) -> Result<(), AdapterError>;

    fn disable_system_proxy(
        &self,
    ) -> Result<(), AdapterError>;

    fn enable_tun(
        &self,
        settings: &TunSettings,
    ) -> Result<(), AdapterError>;

    fn disable_tun(
        &self,
    ) -> Result<(), AdapterError>;

    fn protect_socket(
        &self,
        fd: RawFd,
    ) -> Result<(), AdapterError>;

    fn status(
        &self,
    ) -> PlatformStatus;

    fn emergency_restore(
        &self,
    ) -> Result<(), AdapterError>;
}

但要注意:

接口统一,不代表底层实现必须统一。

例如:

TEXT
WindowsAdapter
 ├── WinINet
 ├── Wintun
 └── WFP

LinuxAdapter
 ├── gsettings
 ├── /dev/net/tun
 ├── ip rule
 └── nftables

AndroidAdapter
 ├── VpnService
 ├── tunFd
 └── protect()

IOSAdapter
 ├── NETunnelProviderManager
 └── NEPacketTunnelProvider

32. Core 与 Platform 的边界

这是整个项目最重要的架构边界之一。

Proxy Core 负责

TEXT
代理协议
DNS
Fake-IP
Routing
TCP
UDP
TLS
节点
出站
tun2socks
连接管理

Platform Layer 负责

TEXT
TUN 创建
VPN 创建
路由
系统代理
DNS 系统配置
权限
Socket 防回环
网络状态恢复

Client Backend 负责

TEXT
订阅
配置
节点管理
状态机
Core 生命周期
Platform 生命周期
日志
错误处理

GUI 负责

TEXT
界面
交互
节点选择
模式切换
实时状态
流量显示

33. 推荐项目目录

如果使用:

TEXT
Flutter + Rust

可以采用:

TEXT
proxy-client/
├── apps/
│   ├── desktop/
│   ├── android/
│   └── ios/
│
├── crates/
│   ├── core/
│   ├── config/
│   ├── subscription/
│   ├── routing/
│   ├── platform/
│   │   ├── windows/
│   │   ├── linux/
│   │   ├── macos/
│   │   ├── android/
│   │   └── ios/
│   │
│   ├── ipc/
│   └── ffi/
│
├── native/
│   ├── windows/
│   ├── android/
│   └── ios/
│
└── flutter/
    ├── lib/
    └── assets/

如果 Core 使用 Mihomo / sing-box,而不是自己实现代理协议,则可以进一步:

TEXT
proxy-client/
├── frontend/
│
├── backend/
│   ├── config
│   ├── controller
│   ├── process
│   └── state
│
├── core/
│   └── mihomo / sing-box
│
├── platform/
│   ├── windows
│   ├── linux
│   ├── macos
│   ├── android
│   └── ios
│
└── native/

34. Core 生命周期

不要让 GUI 自己到处执行:

TEXT
start core
kill core
restart core
set proxy
set tun

应该由 Backend 管理状态机。

例如:

RUST
enum ClientState {
    Stopped,
    Starting,
    Running,
    Stopping,
    Error,
}

代理模式:

RUST
enum TrafficMode {
    SystemProxy,
    Tun,
}

完整状态:

TEXT
Stopped
   ↓
Starting
   ↓
CoreReady
   ↓
PlatformReady
   ↓
Running

停止:

TEXT
Running
   ↓
Stopping
   ↓
RestorePlatform
   ↓
StopCore
   ↓
Stopped

35. 启动顺序

推荐:

TEXT
1. 读取配置
2. 验证配置
3. 启动 Core
4. 等待 Core Ready
5. 创建 / 配置 Platform
6. 配置 DNS / Route
7. 启用 System Proxy 或 TUN
8. 状态切换 Running

而不是:

TEXT
先改系统路由
再启动 Core

否则 Core 启动失败时:

TEXT
系统已经被接管
但没有处理流量的 Core

用户就会直接断网。


36. 停止顺序

推荐反过来:

TEXT
1. 停止接收新的系统流量
2. 关闭 TUN / System Proxy
3. 恢复 DNS / Route
4. 停止 Core
5. 清理临时资源
6. 状态 = Stopped

如果 Core 先死:

TEXT
Core
 ↓
Crash
 ↓
TUN 仍然存在
 ↓
系统流量继续进入 TUN
 ↓
用户断网

所以平台层必须有:

TEXT
emergency_restore()

37. Fail-Safe

生产环境必须考虑:

TEXT
客户端崩溃
Core 崩溃
系统重启
强制关机
网络切换
用户拔网线
Wi-Fi → Ethernet
Wi-Fi → Cellular

Windows 尤其需要防:

TEXT
ProxyEnable = 1
ProxyServer = 127.0.0.1:7890

但是 Core 已经不存在。

因此:

TEXT
启动
 ↓
检查残留状态
 ↓
验证 Core
 ↓
清理孤儿配置

必要时增加:

TEXT
Watchdog

38. IPv6

如果只配置:

TEXT
0.0.0.0/0

而没有:

TEXT
::/0

系统可能通过 IPv6:

TEXT
Physical NIC
 ↓
Internet

从而绕过 IPv4 TUN。

因此 IPv6 策略必须明确:

TEXT
支持 IPv6

或者:

TEXT
明确阻断 IPv6

而不是:

TEXT
什么都不配置

39. MTU

TUN 不应该默认认为:

TEXT
MTU = 1500

在不同环境中可能需要不同值。

例如:

TEXT
Ethernet
Wi-Fi
Cellular
VPN
Proxy Protocol

都会影响有效 MTU。

如果代理协议产生额外开销:

TEXT
Original Packet
+
Proxy Header
+
Encryption Overhead

可能超过路径 MTU。

因此需要考虑:

TEXT
MTU
MSS
Fragmentation
TCP MSS Clamping

40. 完整 Windows TUN 数据流

TEXT
┌─────────────────────┐
│ Application         │
│ Chrome / Steam etc. │
└─────────┬───────────┘
          │
          ▼
┌─────────────────────┐
│ Windows TCP/IP      │
└─────────┬───────────┘
          │
          ▼
┌─────────────────────┐
│ Wintun              │
└─────────┬───────────┘
          │ L3 Packet
          ▼
┌─────────────────────┐
│ Proxy Core          │
│                     │
│ tun2socks           │
│ DNS                 │
│ Fake-IP             │
│ Routing             │
└─────────┬───────────┘
          │
          │ Proxy Socket
          │
          │ interface binding
          ▼
┌─────────────────────┐
│ Physical NIC        │
└─────────┬───────────┘
          │
          ▼
     Proxy Server
          │
          ▼
       Internet

41. 完整 Android VPN 数据流

TEXT
┌────────────────────┐
│ Android App        │
└─────────┬──────────┘
          │
          ▼
┌────────────────────┐
│ Android Network    │
└─────────┬──────────┘
          │
          ▼
┌────────────────────┐
│ VpnService         │
│ Builder.establish  │
└─────────┬──────────┘
          │
          │ tunFd
          ▼
┌────────────────────┐
│ Rust / Native Core │
│                    │
│ Packet → TCP/UDP   │
│ DNS                │
│ Routing            │
└─────────┬──────────┘
          │
          │ protect(fd)
          ▼
┌────────────────────┐
│ Wi-Fi / Cellular   │
└─────────┬──────────┘
          │
          ▼
     Proxy Server

42. 完整 iOS 数据流

TEXT
┌─────────────────────┐
│ Main App             │
│ Flutter / Swift      │
└──────────┬──────────┘
           │
           ▼
NETunnelProviderManager
           │
           ▼
┌─────────────────────┐
│ NEPacketTunnelProvider│
└──────────┬──────────┘
           │
           ▼
      packetFlow
           │
           ▼
┌─────────────────────┐
│ Embedded Core        │
│ DNS / Routing / Proxy│
└──────────┬──────────┘
           │
           ▼
     iOS Network
           │
           ▼
        Internet

43. Flutter 与 Rust

如果 GUI 使用 Flutter,而 Backend 使用 Rust,建议:

TEXT
Flutter
   │
   │ FFI / plugin
   ▼
Rust Client Backend
   │
   ├── Config
   ├── Subscription
   ├── State
   ├── Core Controller
   └── Platform Adapter

但 Android / iOS 的系统能力仍然需要原生层。

例如 Android:

TEXT
Flutter
 ↓
Dart
 ↓
Platform Channel / FFI
 ↓
Kotlin VpnService
 ↓
Rust Core

iOS:

TEXT
Flutter
 ↓
Swift
 ↓
NETunnelProviderManager
 ↓
Network Extension
 ↓
Rust Core

Windows:

TEXT
Flutter
 ↓
Rust
 ↓
Windows Service
 ↓
Wintun / WFP

因此:

跨平台不意味着所有代码都必须用同一种语言。

真正应该统一的是:

TEXT
业务模型
Core API
配置模型
状态模型
PlatformAdapter 抽象

而不是强迫所有系统 API 都使用 Rust 重新包装。


44. Core API 应该是什么样

Client Backend 不应该依赖 GUI。

例如:

RUST
pub trait ProxyController {

    fn start(
        &self,
        config: CoreConfig,
    ) -> Result<(), CoreError>;

    fn stop(
        &self,
    ) -> Result<(), CoreError>;

    fn reload(
        &self,
        config: CoreConfig,
    ) -> Result<(), CoreError>;

    fn status(
        &self,
    ) -> CoreStatus;

    fn connections(
        &self,
    ) -> Vec<ConnectionInfo>;
}

GUI 只需要:

TEXT
start()
stop()
reload()
status()
connections()

而不需要知道:

TEXT
Wintun
VpnService
NEPacketTunnelProvider
ip rule
fwmark

45. 一个完整的启动流程

以 TUN 模式为例:

TEXT
用户点击“启动”
       │
       ▼
GUI
       │
       ▼
Client Backend
       │
       ├── 读取配置
       ├── 检查配置
       └── 启动 Core
               │
               ▼
          Core Ready
               │
               ▼
        Platform Adapter
               │
       ┌───────┴────────┐
       │                │
       ▼                ▼
     TUN/VPN          DNS/Route
       │                │
       └───────┬────────┘
               ▼
         Platform Ready
               │
               ▼
             Running

46. 一个完整的关闭流程

TEXT
用户点击“停止”
       │
       ▼
Client Backend
       │
       ▼
停止新的流量接管
       │
       ▼
Disable TUN / VPN
       │
       ▼
恢复 Route / DNS
       │
       ▼
恢复 System Proxy
       │
       ▼
Stop Core
       │
       ▼
Cleanup
       │
       ▼
Stopped

47. 开发顺序

不要同时开发五个平台。

推荐:

第一阶段:Windows

先完成:

TEXT
Core Controller
System Proxy
配置备份
配置恢复
Wintun
TUN
Routing
DNS
防回环
Crash Recovery

目标:

TEXT
Windows 上可以稳定运行

第二阶段:Linux

加入:

TEXT
/dev/net/tun
ip rule
ip route
fwmark
systemd-resolved
nftables
CAP_NET_ADMIN

然后验证:

TEXT
Linux TUN

第三阶段:macOS

先实现:

TEXT
System Proxy

再实现:

TEXT
Network Extension

不要一开始就把:

TEXT
utun
root helper
Network Extension

全部混在一起。


第四阶段:Android

核心目标:

TEXT
VpnService
tunFd
Rust / Native Core
protect()
DNS
App Routing

重点测试:

TEXT
Wi-Fi
5G
切网
锁屏
后台
VPN 重启
Core 崩溃

第五阶段:iOS

最后再处理:

TEXT
Network Extension
NEPacketTunnelProvider
App Group
Extension 生命周期
Core 嵌入
内存
签名
Entitlement

iOS 应该最后做,因为它对进程、权限和 Extension 生命周期的限制最明显。


48. 最终架构

最后整个项目应该收敛成:

TEXT
                         ┌───────────────────┐
                         │       GUI         │
                         │ Flutter / Native  │
                         └─────────┬─────────┘
                                   │
                                   ▼
                         ┌───────────────────┐
                         │  Client Backend   │
                         │                   │
                         │ Config            │
                         │ Subscription      │
                         │ State Machine     │
                         │ Core Controller   │
                         └─────────┬─────────┘
                                   │
                    ┌──────────────┴──────────────┐
                    │                             │
                    ▼                             ▼
          ┌──────────────────┐         ┌────────────────────┐
          │    Proxy Core    │         │  Platform Adapter  │
          │                  │         │                    │
          │ DNS              │         │ Windows            │
          │ Routing          │         │ Linux              │
          │ Proxy            │         │ macOS              │
          │ TUN              │         │ Android            │
          │ tun2socks        │         │ iOS                │
          └─────────┬────────┘         └─────────┬──────────┘
                    │                            │
                    └──────────────┬─────────────┘
                                   ▼
                         Operating System
                                   │
                                   ▼
                              Internet

最终职责非常明确:

TEXT
GUI
↓
用户怎么控制

Client Backend
↓
整个客户端怎么运行

Proxy Core
↓
流量怎么代理

Platform Adapter
↓
系统流量怎么进入 Core

Operating System
↓
真正的网络设备与系统能力

49. 开发者应该记住的四句话

第一

System Proxy 是应用主动使用代理,不是真正的全局流量接管。

第二

TUN 接收到的是 L3 IP Packet,而代理 Core 通常处理的是 TCP / UDP,因此需要协议栈转换。

第三

TUN 最危险的问题不是创建网卡,而是防止 Core 自己的出站连接再次进入 TUN。

第四

跨平台客户端真正应该统一的是 Core、Backend、配置和抽象接口,而不是强行统一每个平台的底层网络实现。

50. 最终设计原则

如果把整份指南压缩成一个架构原则,就是:

TEXT
                  GUI
                   │
                   ▼
             Client Backend
                   │
          ┌────────┴────────┐
          ▼                 ▼
      Proxy Core       Platform Adapter
          │                 │
          │                 │
          │          ┌──────┼──────┐
          │          ▼      ▼      ▼
          │       Windows Linux Android ...
          │
          ▼
      Proxy Network

Proxy Core 决定“怎么代理”。

Platform Adapter 决定“怎么接管系统流量”。

Client Backend 决定“怎么把 Core 与 Platform 组织起来”。

GUI 决定“用户怎么操作”。

这四层分开以后,Windows、Linux、macOS、Android、iOS 才真正能够共享一套客户端架构。


附:实现前的验证清单

Core

  • ☐ 配置加载
  • ☐ 配置校验
  • ☐ DNS
  • ☐ Fake-IP
  • ☐ Routing
  • ☐ TCP
  • ☐ UDP
  • ☐ TUN / tun2socks
  • ☐ Proxy Outbound
  • ☐ Core 状态

Platform

  • ☐ System Proxy
  • ☐ TUN / VPN
  • ☐ Route
  • ☐ DNS
  • ☐ Socket 防回环
  • ☐ 权限
  • ☐ 状态恢复
  • ☐ 网络切换
  • ☐ Crash Recovery

Client Backend

  • ☐ Core 生命周期
  • ☐ Platform 生命周期
  • ☐ 状态机
  • ☐ 配置管理
  • ☐ 订阅管理
  • ☐ 日志
  • ☐ 错误处理

GUI

  • ☐ 节点列表
  • ☐ 模式选择
  • ☐ 启动 / 停止
  • ☐ 当前状态
  • ☐ 流量统计
  • ☐ 连接列表
  • ☐ 日志
  • ☐ 设置

Android

  • ☐ VpnService
  • ☐ VPN 授权
  • ☐ tunFd
  • ☐ protect()
  • ☐ App 分流
  • ☐ Wi-Fi / Cellular
  • ☐ 后台生命周期

iOS

  • ☐ Network Extension
  • ☐ NEPacketTunnelProvider
  • ☐ packetFlow
  • ☐ VPN 配置
  • ☐ App Group
  • ☐ Extension 生命周期
  • ☐ Core 嵌入
  • ☐ Entitlement / Signing

本指南以用户提供的《跨平台代理客户端开发指南》为基础重新组织和展开。对于原资料没有充分覆盖的具体平台 API 行为、版本限制或实现细节,正式编码前应再针对目标系统版本和 Core 版本进行验证。