专门应对 UDP 封锁和 UDP QoS 的通用解决方案。用 raw socket 把 udp 协议包装成 tcp,模拟 3 次握手,模拟序号,模拟 tcp option,可以让防火墙认为是 tcp 流量;还可以把流量包装成 icmp。支持几乎任何 udp 应用。包括 kcptun 和 finalspeed。支持 openvz。支持 NAT 穿透。稳定。
repo: https://github.com/wangyu-/udp2raw-tunnel ,支持桌面 linux、openwrt、树莓派。
另一个功能是心跳保活、自动重连,自动重连后可以恢复上次的连接,重连后上层连接继续有效,底层掉线上层不掉线。可以有效解各种掉线问题的问题(比如你用 kcptun,就算你拔掉网线重插,或者重新拨号获得新 ip,上层的 kcp 也不会断线)。(功能借鉴自 kcptun-raw )
udp2raw+kcptun step by step 教程:
https://github.com/wangyu-/udp2raw-tunnel/blob/master/doc/kcptun_step_by_step.md
udp2raw+finalspeed step by step 教程:
https://github.com/wangyu-/udp2raw-tunnel/blob/master/doc/finalspeed_step_by_step.md
在windows和mac上运行udp2raw,门槛已经极大降低:
https://github.com/wangyu-/udp2raw-tunnel/wiki/在windows-mac上运行udp2raw客户端,带图形界面
1
wangyucn OP windows 下配合虚拟机可以稳定使用。
|
2
ovear 2017-08-11 18:25:55 +08:00
先收藏下,不过如果走 TCP 不是就失去了 UDP 的意义了么 0 0
|
3
kuretru 2017-08-11 18:28:51 +08:00
$$下加一层 kcptun 现在再加一层 udp2raw 隧道,怕是我的搬瓦工吃不消
|
5
wangyucn OP 这不是真正的走 TCP,是给 UDP 加上 tcp/icmp 包头,以骗过 udp 防火墙。本质上仍然是 UDP,跟传统的 tcp over udp 是不同的(比如 tcp 模式的 openvpn)。
引用一下我在 github 上的回复: ``` @wangyu- 有一个疑惑,如果 udp over tcp 的话不就失去 kcptun 的意义了? 本来就是因为 tcp 协议效率低才会用 Kcptun 吧? @wangyu- wangyu- commented 7 hours ago • edited @sqwwqw5 这是个非常好的问题。 普通的 udp over tcp 方案配合 kcptun 确实几乎没有意义(比如用 openvpn 把 udp 转成 tcp 再用 kcptun 加速的想法)。 udp2raw 的方式是,用 raw socket 给 udp 加上 tcp 包头,模拟 tcp 握手和 seq ack_seq,以打通 tcp NAT pipe 和骗过 udp 防火墙。但是这种模拟的 tcp 本质上还是 udp,继承 udp 的实时乱序到达特性,没有拥塞控制和重传(所以可以让上层的 kcptun 自己完全控制拥塞和重传),忽略对方的接收窗口。本质上不属于 udp over tcp,所以没有类似问题。 ==updated== 重新编辑了一下,补充了些细节。 普通的 udp over tcp 方案配合 kcptun ”失去意义“的原因:tcp 只支持按序到达,破坏了上层承载的 udp 的实时性(tcp 只要丢一个包,后续的包就都要等这个包的重传完成才能投递给上层,上层承载的 udp 也继承了这个特性,会为上层 kcp 引入额外延时,也可能会误导 kcp 造成额外重传); tcp 有激进的拥塞控制,上层承载的 udp 不能自由控制发送速率; tcp 丢包后还必须重传,kcp 有自己的重传策略,两个重传策略在一起有双倍重传的问题,造成性能下降。 注: 这里说的是 kcptun_client---->udp over tcp----->kcptun_server 的问题。 不是 udp over tcp---->kcptun_client---->kcptun_server-----> udp over tcp,虽然这个方案也有问题。 ``` |
6
wangyucn OP 尴尬了,原来回复是不支持 markdown 语法的,格式好乱。 可以去 kcptun 的这个 issue 下看,有我的回复:
https://github.com/xtaci/kcptun/issues/228 |
7
akwIX 2017-08-11 18:31:45 +08:00 2
让出口炸的更猛烈一些
|
8
wangyucn OP @akwIX
取决于使用者怎么用。我这个不多倍发包方案,只是绕过 udp qos 限制。udp qos 确实造成了很多不便。 我觉得节省出口的更好方式是看 youtube 用 720p 不用 1080p = = 。 |
9
wangyucn OP 不是多倍发包方案
|
10
wangyucn OP 假设,仅仅是假设:你的本地运营商不做 udp Qos,而别人的运营商做 Qos,你不希望别人能绕过 Qos,以防止挤占你的出口带宽。
这也是种自私吧 = =。 |
12
Love4Taylor 2017-08-11 18:45:36 +08:00
外挂就比较累 看哪个项目愿意集成吧 233333
|
13
wangyucn OP @Love4Taylor
其实有人做过集成的版本,只是 kcptun 作者决定不 merge 这个功能。比如这个,https://github.com/Chion82/kcptun-raw 外挂的方案比较通用。这个可以支持 kcptun finalspeed openvpn 还有 ss 的 udp 转发。 |
14
suikator 2017-08-11 18:54:50 +08:00 via Android
配合 ss 的 udp 转发 是无加密的吗
|
15
s82kd92l 2017-08-11 18:55:10 +08:00
这个非常有意义,曾经有一样的想法但觉得实现起来很麻烦。想知道楼主怎么实现的?
如果要伪装成 tcp,必然需要实现一个用户态 tcp 状态机,难道要借用内核 tcp 代码? 还有,感觉项目名称不准确。这个项目核心在于 fake-tcp/icmp 头部包装隧道,而 payload 可以是 udp,也可以是 tun/tap,对吧?鉴于 icmp-tunnel 这东西早就有人实现, 建议改为 faketcp-tunnel |
16
wangyucn OP |
17
s82kd92l 2017-08-11 18:58:44 +08:00
感觉 icmp 隧道比 faketcp 效果还是差很多的,尤其是 nat 设备会让 icmp 很快超时,而 faketcp 连接可以保留很长一段时间。建议楼主砍掉 icmp,专注 faketcp。
|
18
HaoyangWei 2017-08-11 19:00:14 +08:00
很有想法,手动点赞 :D
|
20
wangyucn OP @s82kd92l
实现起来确实麻烦。 首先用 iptables 屏蔽掉内核对指定端口的 tcp 处理。 然后用 raw_socket 在 3 层发 ip 包,用另一个 raw_socket 在 2 层(链路层)收 Ip 包(因为用 iptables 屏蔽掉,就无法在 3 层收到包了)。 确实实现了简单的用户态 tcp 状态机。这个没有重传策略、拥塞控制、按序到达,所以简单很多。 名字我就不改了 = =。 这个项目可以把 udp 用 raw 发出,支持模拟成 tcp/icmp/udp 本身。所以就叫 udp2raw 了 = = 。 github 上确实有个 Imcptunnel 很多,但是那个是不能穿透 nat 的,而且有一个大问题就是没有认证 /加密机制,你架设了服务,任何人都可以用。 |
21
wangyucn OP github 上确实有个 Imcptunnel 很火。
|
22
wangyucn OP @s82kd92l 你说的对。icmp 隧道效果确实不好,我的 20m 带宽用 icmp 模式只能达到 6m,用 faketcp 可以打满 20m。
icmp 对一般情况没用,但是在特殊情况下,比如只有 icmp 能通的情况下,可以救急使用。icmp 几乎没给代码增加维护代价,我暂时没有砍掉的想法。我的精力确实主要 forcus 在 faketcp 上的,不用担心。 |
23
wangyucn OP |
24
s82kd92l 2017-08-11 19:14:47 +08:00
@wangyucn
没必要在 2 层与 3 层同时作业, 建议单独开一个 tun/tap 设备,添加一个内网地址 192.168.254.254 之类的,再利用 ip_forward 和 iptables masquerade,可以在第 3 层完成所有动作。 |
25
wangyucn OP 你说得很对。tun/tap 配合 ip_forward 也可以实现。https://github.com/chobits/tapip ,github 上这个项目就是这个原理。
这算实现路线的区别吧,tun tap 的方式我没深入研究,我从一开始就感觉 raw 的方式比较容易,就 forcus 在这个方案了。 2 层 3 层同时作业,看起来确实有点脏。 不过我已经做好了同时在 2 层收发的功能。用一个隐藏选项--lower-level 可以开启。在项目的一个 issue 里有提到。 |
26
s82kd92l 2017-08-11 19:35:05 +08:00
可是我觉得在第二层收包会带来性能问题啊,因为这个肯定需要遍历所有收到的 IP 包,不管目的地是否是 faketcp,而如果只是普通 IP 包的话,iptables 会再次遍历剩下的 IP 包。iptables 是内核实现,遍历速度应该比用户态快很多吧。
尤其是部署在路由器上的时候,双重遍历应该会带来很大压力吧。 新内核上好像有个 ebpf 接口,配合 pcap 应该能在内核态进行 filter,如果你坚持在第二层处理的话可以利用这个加速一下。 |
27
wangyucn OP @s82kd92l
补充以下,关于 icmp 模式的。我这边的 icmp 没有 nat pipe 很快失效的问题。 开着一个 ping 可以 ping 几天不掉线。 貌似性能不好是因为运营商做了 icmp 流量或者包速限制。具体是流量还是包速我没有实验。 |
28
wangyucn OP |
29
wangyucn OP bpf filter : https://www.kernel.org/doc/Documentation/networking/filter.txt
不用担心内核版本不够新,这个据我查到的资料在 linux 2.1 版就有实现了。 |
30
wangyucn OP @s82kd92l 这个是不用配合 pcap 的。直接用 setsockopt attach 在 socket 上就可以了。见我给 kcptun-raw 提的 issue,很简单,就几行代码:
https://github.com/Chion82/kcptun-raw/issues/15 |
32
s82kd92l 2017-08-11 20:13:30 +08:00
|
33
pisser 2017-08-11 20:23:01 +08:00
支持 shadowvpn 吗?
|
34
wangyucn OP @s82kd92l @t123yh
有一点简单状态机。syn,synack,ack 这些改装的都装了。前几个数据包(udp2raw client 和 server 互相认证的认证包),还模拟了重传。 再后面(真正承载数据的包)的模拟就比较简单了,就是 seq 增长,ack_seq 跟着收到的 seq 增长一下。 ======================== 我以后可能会模拟一个从外部看起来完全和 tcp 一样、无法封杀的协议。模拟重传和拥塞控制但是支持实时乱序到达。 拥塞控制模拟带来的问题可以通过多条 tcp 克服。重传带来的 overhead 大部分时间都不大,普通 tcp 不能承载 Udp 的原因主要是不支持乱序到达,一个包丢了后续的包都必须等这个包的重传完成才能投递(一个包丢了会阻塞住所有包的投递)。 这个想法的可行性是没问题的。有一篇论文就是提了这个,https://arxiv.org/pdf/1103.0463.pdf 。但是他没有公开他的实现。而且他是用改内核的“笨”方法实现的,部署难度堪忧 = =. |
35
wangyucn OP @pisser 我没有用过,shaowvpn udp 模式应该没有问题。 他的 tcp 模式是用跟 udp2raw 类似的方式实现的,你可以直接用 tcp 模式。 如果连不上再试试套上 udp2raw
|
36
swulling 2017-08-11 20:41:31 +08:00 via iPhone 1
有点意思,我们办公网对 UDP 做了封禁,可以试试这个
|
37
s82kd92l 2017-08-11 20:50:25 +08:00
@wangyucn
"我以后可能会模拟一个从外部看起来完全和 tcp 一样、无法封杀的协议。模拟重传和拥塞控制但是支持实时乱序到达。 " 这个不用自己实现,直接在 faketcp 上加个 sctp 就行,什么 multihoming, multistreaming, out-of-order delivery 都有,sctp 内核态与用户态实现都有现成的。webrtc 就搞了个 sctp over udp, 咱只需改成 sctp over faketcp 就好 |
38
wangyucn OP @s82kd92l 你可能没理解我的意思。我的意思是这个 faketcp 对标准 tcp 的模拟不够完全,所以如果运营商做深度包检测的话,理论上有可能把 faketcp 流量区分出来,再有针对性的 qos。 所以我打算模拟个 real-tcp 来代替 fake-tcp,消除被封杀的可能。
|
39
s82kd92l 2017-08-11 21:08:25 +08:00
@wangyucn
这个深度检测我觉得是多虑了。运营商的 qos 和流量区分完全是依赖与硬件设备提供商,他们没有自主开发深度检测的能力(大流量下用 cpu 做 spi 不现实,都是硬件 asic 做)。等到整个产业链都开始针对 faketcp 时,可能 ipv4/udp-qos 这些都不存在了。 |
41
wangyucn OP @s82kd92l 我觉得运营商有时候都不是故意 UDPQos 你,只是他们设备对 udp 支持不好,或者 udp NAT 的设备压力太大导致不稳定。 我这边的移动 tcp 多线程(单线程当然不行)连国外基本都满速。 但是 udp 连有一些方向的线路总是时断时续,有的时候 nat pipe 都打不通。 既然 tcp 都满速,udp 故意 Qos 你有什么用呢。
所以我觉得这个项目某种程度上也是在帮运营商,解决 udp nat 支持不好带来的用户抱怨 = = 。 |
42
wangyucn OP 当然,这纯属不负责任猜测。
|
44
FishTorres 2017-08-11 21:29:54 +08:00 1
QUIC 跟着倒霉
|
45
wangyucn OP @s82kd92l 我这边到美国西海岸 udp 基本满速, 到日本经常连都连不上,但是多线程 tcp 到日本和美国西海岸又都满速。有点费解。
|
46
terrytw 2017-08-11 21:32:32 +08:00
有意思,非常支持!
|
47
1423 2017-08-11 23:27:20 +08:00
测了下 kcptun + udp2raw-tunnel 一起用,带宽利用率相当低。。不知道怎么分析原因?
|
48
wangyucn OP @1423,性能问题去项目里提 issue,贴出配置吧。
有可能你使用的是路由器版,用了 aes128cbc 加密,导致 cpu 被打满。路由器建议用 --cipher xor --auth simple |
49
wangyucn OP 我这边移动 20m 宽带,测试出的性能:
./iperf3 -c 10.222.2.1 -P40 -t30 [SUM] 0.00-30.00 sec 68.3 MBytes 19.1 Mbits/sec 3391 sender [SUM] 0.00-30.00 sec 64.6 MBytes 18.1 Mbits/sec receiver ./iperf3 -c 10.222.2.1 -P40 -t30 -R [SUM] 0.00-30.00 sec 71.3 MBytes 19.9 Mbits/sec 10046 sender [SUM] 0.00-30.00 sec 56.6 MBytes 15.8 Mbits/sec receiver 客户端在 linux 虚拟机上,如果是路由器的话,因为 cpu 速度的原因,只有 8Mbits/sec. |
50
wangyucn OP server 在 vultr 日本。
|
51
Damaidaner 2017-08-12 09:28:50 +08:00 via Android
收藏!!
|
52
hjc4869 2017-08-12 10:14:52 +08:00 via Android
Windows 没必要用虚拟机,装 Windows Server 就能用 raw socket 艹 tcp 了。
或者用 pcap 之类的也行 |
53
johnlui 2017-08-12 10:34:00 +08:00
kcptun 和 BBR 有实测数据嘛?
|
54
wangyucn OP |
55
wangyucn OP BBR 感觉跟这个项目不搭边吧。也许你想到了什么特殊用法?比如用 openvpn+udp2raw 再测开启了 bbr 的 tcp 性能?
|
56
linhua 2017-08-12 12:15:14 +08:00 1
@wangyucn
厉害 @kuretru 如果丢包率不高的话(<15%),可以使用 BBR github.com/linhua55/lkl_study 搬瓦工 64M 也是可以使用的,只是 CPU 占用有点高 |
57
wangyucn OP 不敢 不敢
@linhua 是最早实现了用 raw_socket 中转 udp 这个点子的人: https://github.com/linhua55/some_kcptun_tools/tree/master/relayRawSocket Chion82 在他的基础上加上了 tcp 握手功能,集成到了 kcptun 里: https://github.com/Chion82/kcptun-raw 我这个项目,把 kcptun-raw 的功能做成通用的了,再加了点小功能。如果没有 relayRawSocket,可能也就没有 kcptun-raw 了,也没有我这个项目了。 |
58
palxex 2017-08-12 12:54:46 +08:00
建议还是考虑一下 pcap。这样 win/mac 上应该都能原生跑了(虚拟机感觉还是太重),final speed 的 tcp 模式印象中就是这么做到跨平台的,尽管可能是实现略 naive 始终没做到 udp 模式的稳定程度,但原理上跟这个项目应该一样是用 raw socket 发包。
|
59
wangyucn OP finalspeed 用的就是 pcap。 而且他也不愿意同时支持 pcap 和 raw socket,所以他的版本不能在 openvz 上运行。
支持 windows 理论上没问题,问题是开发成本= =。 raw socket 要改成 pcap,epoll 要改成 libevent,暂时不想增加开发负担。 虚拟机很稳定,而且性能很好,如果爱折腾还是装个备用吧。 |
60
wangyucn OP 可以考虑后续发布装了 udp2raw 的 vmware image。用 openwrt x86 版的,容量可以控制在几 MB。
|
61
linhua 2017-08-12 14:24:15 +08:00
@wangyucn
这扯得就有点远了,当初 因为 kcptun 才写了这个小玩意,不过能力有限,只能凑合着用。不过和 finalSpeed 结合着用还是会断流( kcptun 没问题),然后就改用 bbr 了。 用 docker,网络设置成 桥接网卡 , 应该也可以 |
62
iijboom 2017-08-12 15:32:06 +08:00
老夫 iperf3 测速这么多年,都是直接单线程梭哈!能跑满就继续上网,跑不动就下海干活(x
|
63
KCheshireCat 2017-08-12 15:44:47 +08:00
@wangyucn #55
如果 fack-tcp 完全工作在 2 层或者 3 层,隧道内部承载真实 TCP 流的话, 就可以让承载的流自己完成拥塞检测和重传. 把这个 fack-tcp 当作 TCP/IP 里的一层,不重复劳动,只完成本职工作. |
64
wangyucn OP @iijboom 我这个是 udp2raw+openvpn 测的,只应对 qos,没用 kcptun/finalspeed 这种加速工具,所以只有用多线程才能测出吞吐。 kcptun finalspeed 这种工具通过自定的拥塞 /重传 /ACK 策略可以让单线程达到很高的速度,所以单线程测大概也能反映出信道的吞吐率。
udp2raw+finalspeed 之前我测过一次,移动 20m 带宽,单线程 1.6MByte/s。 @KCheshireCat faketcp 通过 openvpn 承载真实 tcp 确实是让上层承担拥塞和重传的,这种用法里 faketcp 相当于 ip 层的作用。 |
67
wangyucn OP "用 docker,网络设置成 桥接网卡 , 应该也可以"
@linhua 我看了一下 docker,它只有在 linux 上才是原生的,在 windows 上和 mac 上都是跑在 virtualbox 虚拟机里的。 所以。。还是直接用虚拟机更轻量吧。我在 release 里发布了预装了 udp2raw 的 ova image(容量也是 4.4m),用独立的 virtualbox 可以运行,用安装 docker tools 时自带的那个 virtualbox 应该也行。 |
68
has 2017-09-06 01:46:33 +08:00
希望能早日推出 osx 编译版
|
70
fcymk2 2017-12-11 13:12:45 +08:00
win 下要虚拟机好麻烦...
|
71
bclerdx 2018-08-07 20:52:35 +08:00
怎么测试被运营商进行了 UDP QOS ?
|
72
zhouyut001 2018-12-16 05:31:56 +08:00
老哥,有沒有捐贈🐴
|
73
1KN6sAqR0a57no6s 2019-12-19 20:48:27 +08:00
这两天第一次遇到了这个问题。。。试一试你的方法先。
|
74
1KN6sAqR0a57no6s 2019-12-19 22:22:59 +08:00
@YuxiangLuo linux 服务端配合 windows(非虚拟机)客户端成功了,遇到的问题是在 powershell 里面 ip 地址要加引号。感谢楼主大佬。
|
76
fan88 2022-09-11 04:41:00 +08:00
对于 tcp 代理,怎么穿透,有哪些比较好的工具吗
|