爱意满满的作品展示区。
heiher

分享一个 tun2socks 实现

  •  
  •   heiher ·
    heiher · Jan 31, 2023 · 9573 views
    This topic created in 1373 days ago, the information mentioned may be changed or developed.

    自用分享,一个 C 语言实现、基于协程和 LwIP 用户态协议栈的 tun2socks 实现,当前支持 Linux 和 Android 系统。

    项目地址: https://github.com/heiher/hev-socks5-tunnel

    功能

    1. IPv4/IPv6 双栈。
    2. 支持重定向 TCP 连接。
    3. 支持重定向 UDP 报文。(UDP over TCP ,需配合hev-socks5-server)

    性能

    详细信息

    速率

    CPU 使用率

    Supplement 1  ·  Feb 4, 2023
    2.4.0 版本增加了 MacOS 系统的支持。
    Supplement 2  ·  Feb 7, 2023

    v2.4.2 版本传输性能翻倍

    内存使用

    Supplement 3  ·  Feb 9, 2023

    在AArch64(RK3399)上的最大传输速率和对应CPU使用率

    • CPU: tun2socks是绑定在两个大核上的(4-5)
    • 网卡: 1Gbps

    最大速率

    speed

    CPU使用率

    cpu

    Supplement 4  ·  Mar 4, 2023
    开始支持 iOS Network Extension
    Supplement 5  ·  Jul 31, 2025
    开始支持 Windows 系统
    40 replies  •  2025-08-28 12:19:54 +08:00
    missdeer
    missdeer
    Feb 1, 2023
    1
    更想要 windows 版,因为 Linux 、mac 上用 iptables ,pf 就能工作得很好
    heiher
    heiher
    OP
    Feb 1, 2023
    2
    @missdeer 确实,Linux 上我也是使用 tproxy 方案,性能更好,我也主要是用在 Android 系统上的。可惜底层的协程框架目前还不支持 Windows [Doggy]
    nmap
    nmap
    Feb 1, 2023
    3
    请问原理是什么
    heiher
    heiher
    OP
    Feb 1, 2023❤️2
    4
    @nmap 简述原理:创建 tun 虚拟网卡,配置策略路由使网络应用程序的 TCP 和 UDP 流量经过虚拟网卡,前向链路上 tun2socks 程序从虚拟网卡接收经过操作系统网络协议栈分片的 TCP/IP(UDP/IP)报文,程序再通过用户态网络协议栈 LwIP 将 TCP 分片重组成流,转发至连接着 socks5 服务端的 socket 上。反向链路,程序从 socks5 服务端接收到流数据后,通过 LwIP 的 TCP 写 API 送到用户态网络协议栈进行分片,再将分片后的报文送入虚拟网卡,随后被操作系统重组,最终送到网络应用程序。
    aa51513
    aa51513
    Feb 3, 2023 via Android
    5
    需要预先手动创建 tun 网卡吗,如果是自动创建 tun ,自动修改路由就好了
    heiher
    heiher
    OP
    Feb 3, 2023
    6
    @aa51513 #5 自动创建 tun 网卡设备,但不会自动创建路由规则,主要是考虑到使用需求不同,比如最简单的用法是直接创建一个默认路由,而有些用户可能用策略路由只针对 TCP 、UDP 协议或指定用户下的进程的网络流量。
    TongNianShanHe
    TongNianShanHe
    Feb 5, 2023
    7
    楼主您好,有 android 端的参考例子吗,我这边根据您的代码调用了 TProxyStartService ,然而好像没生效(第二个参数应该填的是 v*nservice 创建后的 fd 吧)
    TongNianShanHe
    TongNianShanHe
    Feb 5, 2023
    9
    感谢,找过没找到,应该是被我忽略了。
    但问题似乎还是没有解决,试过 demo 里的写法,没法连通,我的 local 端没有数据(此前用的 xjasonlyu 的 tun2socks 实现),logcat 报“getIfIndex: cannot find interface tun0”,把 demo 的 release 跑了一遍,也不行。
    我先放一下吧,近期没有多余时间去排错了,但是看图感觉性能会比之前好一些,先 star 一下,后续有时间再弄。
    heiher
    heiher
    OP
    Feb 5, 2023
    10
    @TongNianShanHe #9 重点检查配置文件对不对,可以先用生成的配置文件在 Linux 上验证一遍。另外一个需要注意的地方是 JNI 的 PKGNAME ,我不知道你改了没有,可以在 Makefile 中用宏定义覆盖为你的项目包名。
    TongNianShanHe
    TongNianShanHe
    Feb 5, 2023
    11
    @heiher PKGNAME 和 hev-jni.c 的 64 行( class 名)都改过,配置文件我注意到你给的例子里填写 IPv4 地址是没有单引号的,但是安卓 demo 的代码里是加了单引号,两种都试过了,看 logcat 感觉加了单引号是对的,因为改动后 local 端有了 socks5 的握手,但只发出了第一部分,后续都无法接收到。
    heiher
    heiher
    OP
    Feb 5, 2023
    12
    @TongNianShanHe #11 看你描述的现象,我怀疑是没有处理好访问 socks5 server 要加入例外(不通过 VPN)的情况。Android VpnService 给出了 protect(Socket)的[方法]( https://developer.android.com/reference/android/net/VpnService#protect(java.net.Socket)),但 socks5-tunnel 在 jni 里创建 socket ,所以我的 demo 里是把当前应用加入到 disallow 列表里,当处于全局模式时。在 per app 模式是是不允许选择当前应用的。

    https://github.com/heiher/hev-htproxy/blob/master/app/src/main/java/hev/htproxy/TProxyService.java#L99-L105
    TongNianShanHe
    TongNianShanHe
    Feb 5, 2023
    13
    @heiher 这个情况其实考虑过,但我用的是白名单(白名单是硬编码),local 是一个独立进程(通过 sh 运行,写的很糙,因为是自己用)
    我再去看看源码吧,不排除 local 端某些情况下的不兼容的可能性,谢谢你的解答。
    heiher
    heiher
    OP
    Feb 5, 2023 via Android
    14
    @TongNianShanHe #13 好,不客气哈~ 也可以试试在 htproxy 上改改 socks5 server address 来验证。
    TongNianShanHe
    TongNianShanHe
    Feb 6, 2023
    15
    @heiher 我调试了一下,发现是 tun2socks 确实是连通的状态,但是有俩问题:
    1. 握手“黏包”(其实这也不算问题,毕竟 tcp 流,已经自行处理过了)
    2. socks5 里面,通过 ip 地址进行访问是正常的(也就是 command 为 0x01 ),通过域名访问就“死”了,检查了一下发现 DNS 请求头(也就是 udp )的 command 是 0x05 ,我以为是协议做过魔改,所以我把 command=0x05 映射到了 udp 转发上,但也是无法工作。(刚重新看了一遍帖子才发现,是必须要用 UDP over TCP 方式做吗?)
    TongNianShanHe
    TongNianShanHe
    Feb 6, 2023
    16
    @heiher 试着做了个 UDP over TCP 的 demo ,证实了这个想法,确实需要用 UDP over TCP 方式,没有问题了,打扰你了
    heiher
    heiher
    OP
    Feb 6, 2023
    17
    @TongNianShanHe #15 是的,hev-socks5-tunnel 的 udp relay 是采用扩展的 socks5 cmd 实现的 udp over tcp ,不是协议标准的 udp 方式,原因是为了让所有流量都走 tcp ,这样方便过 cdn 。
    heiher
    heiher
    OP
    Feb 6, 2023
    18
    @TongNianShanHe #16 好的,hev-socks5-tunnel 的 udp 功能需要配合 hev-socks5-server 或兼容的服务端使用。
    TongNianShanHe
    TongNianShanHe
    Feb 6, 2023
    19
    @heiher 花了点时间把我那边的适配做好了(我没想到 UDP over TCP 包也做了魔改)

    如果想使用这个库的话这边有几个提示:这个 tun2socks 实现基于 socks5 ,支持两个模式( 0x01 是 CONNECT ,0x05 是 UDP over TCP ),并且 UDP over TCP 包的前两位和 10 ,11 位是当前包的长度,中间的和 socks5 udp relay 转发头是差不多的(也就是说 IPV4 relay 头的长度会从 10 变为 14 ,IPv6 同理加 4 ),其他的都是差不多的,直接转发就行。

    等哪天真闲下来就试着啃啃这个项目吧,感谢分享。
    heiher
    heiher
    OP
    Feb 15, 2023
    20
    @TongNianShanHe Android VPN over socks5 proxy 参考实现: https://github.com/heiher/sockstun
    heiher
    heiher
    OP
    Feb 16, 2023
    21
    @TongNianShanHe 增加了的 udp relay over udp 的方式
    TongNianShanHe
    TongNianShanHe
    Feb 17, 2023❤️1
    22
    @heiher ( v2 的消息提醒好像有点问题,刚刚才看到)谢谢您,虽然我已经实现了 udp relay over tcp
    testFor
    testFor
    Mar 11, 2023
    23
    从 badvpn 的切换过来,不清楚为什么感觉引入了一个 1s 的延迟,及时很小的网页也是,是为了吞吐量做了缓存么
    heiher
    heiher
    OP
    Mar 11, 2023 via Android
    24
    @testFor 能否提供一个可量化的测试方法?
    testFor
    testFor
    Mar 12, 2023
    25
    没有,刚切换过来,主观感觉延迟 1s,特别是打开 V2EX 这种小网页,表现为前 0.5s 什么也不发生,后 1.0s 集中加载
    testFor
    testFor
    Mar 12, 2023
    26
    @heiher 是否可能因为开了 tcp 延迟
    testFor
    testFor
    Mar 12, 2023
    27
    @heiher 可能也是这个延迟导致楼上说的沾包出现
    heiher
    heiher
    OP
    Mar 12, 2023 via Android
    28
    @testFor 有关 TCP delay 都是系统默认配置,“粘包”效果是因为 socks5 客户端有意实现为预测发送,是有减少延迟作用的。不知道切换前怎样,切换后应该是 dns 经过 socks5 服务器端,不知道是不是因为 dns 的延迟。浏览器的开发者选项中网络传输页面应该可以显示每个资源的加载时间,不妨对比看看,需要注意的是尽可能网络环境的抖动影响,比如本地跑 socks5 服务器,访问本地或国内 http 资源。
    testFor
    testFor
    Mar 12, 2023
    29
    @heiher 所以实现上还是主动延迟了发送时间?
    heiher
    heiher
    OP
    Mar 12, 2023
    30
    @testFor #29 没有主动延迟的意思。

    刚测了访问国内四个网站的传输时间情况,socks5 服务端在局域网另一主机,测试主机配置 tun0 为默认路由(ipv4 & ipv6),数据来自 firefox 开发者选项的 timing:

    testFor
    testFor
    Mar 12, 2023
    31
    @heiher 可以关闭预测么.我的平台是安卓 ,型号为小米 12s.安卓 12. 测试方法可能只有切换 tun2socks 与你的新的 so 进行测试了.
    heiher
    heiher
    OP
    Mar 12, 2023
    32
    @testFor #31 暂不支持,socks5 握手预测的实质是将多轮交互的客户端侧数据一次发送(大概率合并在一个报文中):

    假设客户端与服务端通信的前、反向链路延迟都是 100ms 的话,两种方式的传输模式和延迟情况大致如下:

    经典:
    客户端:Hello ,我支持的鉴权方法有:123 (100ms)
    服务端:Hello ,我选鉴权方法 1 (100ms)
    客户端:请帮我建立与 xxx 的连接 (100ms)
    服务端:好的,连接已经建立好 (100ms)
    合计:400ms

    预测:
    客户端:Hello ,我支持的鉴权方法有:123 ;请帮我建立与 xxx 的连接 (100ms)
    服务端:Hello ,我选鉴权方法 1 ;好的,连接已经建立好 (100ms)
    合计:200ms
    testFor
    testFor
    Mar 12, 2023
    33
    如何是本地连接 1ms 完成交互.会不会你的延迟合并的超时时间都大于连接开销
    heiher
    heiher
    OP
    Mar 12, 2023
    34
    @testFor #31 说明一下没有主动延迟等待收集数据再合并的逻辑,这样理解与事实不符。事实是客户端将 socks5 握手中需多轮交互的多个数据片段一次准备好,并在 TCP 流中一次 send ,仅此而已。
    Cormic
    Cormic
    Apr 11, 2023
    35
    看配置文件似乎是 socks2tun ,名字又是 tun2socks ,是我理解错了吗?
    heiher
    heiher
    OP
    Apr 11, 2023
    36
    @Cormic client -> virtual tunnel -> socks5 server
    TongNianShanHe
    TongNianShanHe
    Apr 19, 2023
    37
    你好作者,我又来了,这次来反馈一个问题,2.5.1 版本,android 端封装后,使用 TProxyStartService 启动没有任何问题,功能也能正常使用,但是通过 TProxyStopService 关闭时,应用会闪退,Logcat 报错如下图,使用您的 android demo 上的代码尝试,问题依旧,但老版本(具体应该是 2.4 左右,时间有点久我也忘记了)没有出现这个问题,如果您方便的话,还是烦请您看一下😂

    ![e6cb550c920dcd75a5923a95d24b4841.png]( https://s2.loli.net/2023/04/19/v3i5RQZFfTwujC8.png)
    heiher
    heiher
    OP
    Apr 19, 2023 via Android
    38
    @TongNianShanHe 好的,我找时间看看,感谢反馈~
    heiher
    heiher
    OP
    Jul 31, 2025 via Android
    39
    开始支持 Windows 系统
    vpnviaemail
    vpnviaemail
    Aug 28, 2025
    40
    vpn2Socks 的开源 SWIFT 项目

    解决了内存压力和对 Youtube 等社交媒体的优化,效率非常高
    https://github.com/CoNET-project/vpn2socks

    该项目的实际应用场景,SilentPassVPN 支持所有电脑,安卓和 iOS
    下载链接
    https://silentpass.io/download/
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   3566 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 44ms · UTC 05:17 · PVG 13:17 · LAX 21:17 · JFK 00:17
    ♥ Do have faith in what you're doing.