kcptun 基于KCP的稳定安全隧道,具有N:M多路复用和FEC,双边加速端口转发工具(可以用于加速shadowsocks,ssr及各种vpn加速)

免责声明:kcptun维护一个网站 - github.com/xtaci/kcptun除 github.com/xtaci/kcptun 以外的任何网站均未得到xtaci的认可。

要求

目标最低推荐
系统aix darwin dragonfly freebsd linux netbsd openbsd solaris windowslinux
记忆>20MB>32兆字节
中央处理器任何amd64 with AES-NI & AVX2

快速入门

增加服务器上打开的文件数,如下所示:

ulimit -n 65535,或将其写在 中。~/.bashrc

更好地处理 UDP 数据包的建议参数:sysctl.conf

net.core.rmem_max=26214400 // BDP - bandwidth delay product
net.core.rmem_default=26214400
net.core.wmem_max=26214400
net.core.wmem_default=26214400
net.core.netdev_max_backlog=2048 // proportional to -rcvwnd

您还可以通过添加参数(默认为 4MB)来增加每个套接字缓冲区:

-sockbuf 16777217

对于速度较慢的处理器,增加此缓冲区对于正确接收数据包至关重要

从预编译的版本中下载相应的版本。

KCP Client: ./client_darwin_amd64 -r "KCP_SERVER_IP:4000" -l ":8388" -mode fast3 -nocomp -autoexpire 900 -sockbuf 16777217 -dscp 46
KCP Server: ./server_linux_amd64 -t "TARGET_IP:8388" -l ":4000" -mode fast3 -nocomp -sockbuf 16777217 -dscp 46

上述命令将为 8388/tcp 建立端口转发通道,如下所示:

应用程序 -> KCP 客户端(8388/tcp) -> KCP 服务器(4000/udp) -> 目标服务器(8388/tcp)

哪个隧道传输原始连接:

应用程序 -> 目标服务器(8388/tcp)

从源代码构建

$ git clone https://github.com/xtaci/kcptun.git
$ cd kcptun
$ ./build-release.sh
$ cd build

所有预编译版本都是从脚本中分离出来的。build-release.sh

性能

fast.com

带宽

火焰

带参数的实际带宽图:-模式快速3 -ds 10 -ps 3

基本调优指南

优化思考

问:我有高速网路,如何达到最大带宽?

一个:在KCP客户端和KCP服务器上同时增加,逐渐增加,最小值决定链路的最大传输速率,如;然后尝试下载一些东西,看看它是否符合你的要求。(mtu 可调节-rcvwnd-sndwndwnd * mtu / rtt-mtu)

改善延迟

问:我在游戏中使用kcptun,我不希望发生任何延迟。

一个:滞后意味着大部分时间丢包,滞后可以通过改变来改善。-mode

例如:-mode fast3

嵌入式模式重传的响应性/响应性包括:

快速3 >快速2 >正常>默认值>快速

HOLB

由于流被多路复用到单个物理通道中,因此在某些情况下可能会出现线头阻塞,通过增加到更大的值(默认4MB)可以缓解这个问题,显然这将花费更多的内存。-smuxbuf

对于版本 >= v20190924,您可以切换到 smux 版本 2,smux v2 具有限制每个流内存使用量的选项,现在设置为启用 smux v2,并调整为限制每个流的内存使用量,例如:可以将每个流的内存使用量限制为 2MB。通过限制接收端的流缓冲区,将对发送方进行背压并限制读取,最后防止源发送太多数据以占用链路上的每个缓冲位。(设置 -smuxver 在两侧必须相同,默认值为 1。-smuxver 2-streambuf-streambuf 2097152

慢速设备

kcptun利用ReedSolomon-Codes来恢复丢失的数据包,这需要大量的计算,低端ARM设备不能很好地满足kcptun。为了释放kcptun的全部潜力,建议使用像AMD皓龙这样的多核x86家庭服务器CPU。如果您坚持在某些ARM路由器下运行,则最好关闭并用作加密方法。FECsalsa20

专业调优指南

概述

参数

用法

➜  ~ ./client_linux_amd64 -h
NAME:
   kcptun - client(with SMUX)

USAGE:
   client_linux_amd64 [global options] command [command options] [arguments...]

VERSION:
   20190924

COMMANDS:
   help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --localaddr value, -l value      local listen address (default: ":12948")
   --remoteaddr value, -r value     kcp server address (default: "vps:29900")
   --key value                      pre-shared secret between client and server (default: "it's a secrect") [$KCPTUN_KEY]
   --crypt value                    aes, aes-128, aes-192, salsa20, blowfish, twofish, cast5, 3des, tea, xtea, xor, sm4, none (default: "aes")
   --mode value                     profiles: fast3, fast2, fast, normal, manual (default: "fast")
   --conn value                     set num of UDP connections to server (default: 1)
   --autoexpire value               set auto expiration time(in seconds) for a single UDP connection, 0 to disable (default: 0)
   --scavengettl value              set how long an expired connection can live (in seconds) (default: 600)
   --mtu value                      set maximum transmission unit for UDP packets (default: 1350)
   --sndwnd value                   set send window size(num of packets) (default: 128)
   --rcvwnd value                   set receive window size(num of packets) (default: 512)
   --datashard value, --ds value    set reed-solomon erasure coding - datashard (default: 10)
   --parityshard value, --ps value  set reed-solomon erasure coding - parityshard (default: 3)
   --dscp value                     set DSCP(6bit) (default: 0)
   --nocomp                         disable compression
   --sockbuf value                  per-socket buffer in bytes (default: 4194304)
   --smuxver value                  specify smux version, available 1,2 (default: 1)
   --smuxbuf value                  the overall de-mux buffer in bytes (default: 4194304)
   --streambuf value                per stream receive buffer in bytes, smux v2+ (default: 2097152)
   --keepalive value                seconds between heartbeats (default: 10)
   --snmplog value                  collect snmp to file, aware of timeformat in golang, like: ./snmp-20060102.log
   --snmpperiod value               snmp collect period, in seconds (default: 60)
   --log value                      specify a log file to output, default goes to stderr
   --quiet                          to suppress the 'stream open/close' messages
   --tcp                            to emulate a TCP connection(linux)
   -c value                         config from json file, which will override the command from shell
   --help, -h                       show help
   --version, -v                    print the version
   
➜  ~ ./server_linux_amd64 -h
NAME:
   kcptun - server(with SMUX)

USAGE:
   server_linux_amd64 [global options] command [command options] [arguments...]

VERSION:
   20190924

COMMANDS:
   help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --listen value, -l value         kcp server listen address (default: ":29900")
   --target value, -t value         target server address, or path/to/unix_socket (default: "127.0.0.1:12948")
   --key value                      pre-shared secret between client and server (default: "it's a secrect") [$KCPTUN_KEY]
   --crypt value                    aes, aes-128, aes-192, salsa20, blowfish, twofish, cast5, 3des, tea, xtea, xor, sm4, none (default: "aes")
   --mode value                     profiles: fast3, fast2, fast, normal, manual (default: "fast")
   --mtu value                      set maximum transmission unit for UDP packets (default: 1350)
   --sndwnd value                   set send window size(num of packets) (default: 1024)
   --rcvwnd value                   set receive window size(num of packets) (default: 1024)
   --datashard value, --ds value    set reed-solomon erasure coding - datashard (default: 10)
   --parityshard value, --ps value  set reed-solomon erasure coding - parityshard (default: 3)
   --dscp value                     set DSCP(6bit) (default: 0)
   --nocomp                         disable compression
   --sockbuf value                  per-socket buffer in bytes (default: 4194304)
   --smuxver value                  specify smux version, available 1,2 (default: 1)
   --smuxbuf value                  the overall de-mux buffer in bytes (default: 4194304)
   --streambuf value                per stream receive buffer in bytes, smux v2+ (default: 2097152)
   --keepalive value                seconds between heartbeats (default: 10)
   --snmplog value                  collect snmp to file, aware of timeformat in golang, like: ./snmp-20060102.log
   --snmpperiod value               snmp collect period, in seconds (default: 60)
   --pprof                          start profiling server on :6060
   --log value                      specify a log file to output, default goes to stderr
   --quiet                          to suppress the 'stream open/close' messages
   --tcp                            to emulate a TCP connection(linux)
   -c value                         config from json file, which will override the command from shell
   --help, -h                       show help
   --version, -v                    print the version

前向纠错

在编码理论中,里德-所罗门码属于非二元循环纠错码类。里德-所罗门码基于有限域上的单变量多项式。

它能够检测和纠正多个符号错误。通过向数据中添加 t 校验符号,Reed-Solomon 代码可以检测最多 t 个错误符号的任意组合,或者更正最多 ⌊t/2⌋ 符号。作为擦除代码,它可以纠正最多已知的擦除,也可以检测和更正错误和擦除的组合。此外,里德-所罗门码适合作为多连发位错校正码,因为一系列 b + 1 个连续的位错误最多可以影响两个大小为 b 的符号。t的选择取决于代码的设计者,并且可以在很宽的范围内选择。

美联储

DSCP

差异化服务或 DiffServ 是一种计算机网络体系结构,它指定了一种简单、可扩展且粗粒度的机制,用于对网络流量进行分类和管理,并在现代 IP 网络上提供服务质量 (QoS)。例如,DiffServ 可用于为关键网络流量(如语音或流媒体)提供低延迟,同时为非关键服务(如 Web 流量或文件传输)提供简单的尽力而为的服务。

DiffServ 在 IP 报头的 8 位差分服务字段(DS 字段)中使用 6 位差分服务代码点 (DSCP) 进行数据包分类。DS 字段和 ECN 字段将替换过时的 IPv4 TOS 字段。

设置每边,这里有一些常用的DSCP值-dscp value

加密分析

kcptun附带了由各种块加密算法驱动的内置数据包加密,并在密码反馈模式下工作,对于要发送的每个数据包,加密过程将从加密系统熵中的随机数开始,因此加密到相同的明文之后永远不会导致相同的密文。

数据包的内容是完全匿名的加密,包括标头(FEC,KCP),校验和和内容。请注意,无论您在上层选择哪种加密方法,如果通过指定 kcptun 来禁用加密,则传输将以某种方式不安全,因为标头对每个人都是明文,因此容易受到标头篡改的影响,例如干扰滑动窗口大小往返时间FEC 属性校验和。 建议进行最小加密,因为现代CPU附带AES-NI指令,并且性能甚至更好(请查看下表)。-crypt noneaes-128salsa20

对kcptun的其他可能攻击包括:a)流量分析,特定网站上的数据流在交换数据时可能有模式,但是这种类型的窃听已经通过调整smux来混合数据流以引入噪声来缓解,对此的完美解决方案尚未出现,通过更大规模的网络上的混洗/混合消息可以缓解这个问题。b)重放攻击,由于某种原因非对称加密尚未引入kcptun,因此可以捕获数据包并在另一台机器上重放它们,(注意:劫持会话并解密内容仍然是不可能的),因此上层应包含非对称加密系统,以保证每条消息的真实性(处理消息恰好一次), 比如HTTPS/OpenSSL/LibreSSL,只有通过用私钥对请求进行签名,才能消除这类攻击。

重要:

  1. -crypt并且在 KCP 客户端和 KCP 服务器上必须相同。-key
  2. -crypt xor也是不安全的,容易受到已知的明文攻击,除非你知道你在做什么,否则不要使用它。(密码分析说明:由于计数器周期缩短,任何类型的计数器模式在数据包加密中都是不安全的,并导致iv / nonce冲突)

kcptun 支持的加密算法的基准测试:

BenchmarkSM4-4                 	   50000	     32087 ns/op	  93.49 MB/s	       0 B/op	       0 allocs/op
BenchmarkAES128-4              	  500000	      3274 ns/op	 916.15 MB/s	       0 B/op	       0 allocs/op
BenchmarkAES192-4              	  500000	      3587 ns/op	 836.34 MB/s	       0 B/op	       0 allocs/op
BenchmarkAES256-4              	  300000	      3828 ns/op	 783.60 MB/s	       0 B/op	       0 allocs/op
BenchmarkTEA-4                 	  100000	     15359 ns/op	 195.32 MB/s	       0 B/op	       0 allocs/op
BenchmarkXOR-4                 	20000000	        90.2 ns/op	33249.02 MB/s	       0 B/op	       0 allocs/op
BenchmarkBlowfish-4            	   50000	     26885 ns/op	 111.58 MB/s	       0 B/op	       0 allocs/op
BenchmarkNone-4                	30000000	        45.8 ns/op	65557.11 MB/s	       0 B/op	       0 allocs/op
BenchmarkCast5-4               	   50000	     34370 ns/op	  87.29 MB/s	       0 B/op	       0 allocs/op
Benchmark3DES-4                	   10000	    117893 ns/op	  25.45 MB/s	       0 B/op	       0 allocs/op
BenchmarkTwofish-4             	   50000	     33477 ns/op	  89.61 MB/s	       0 B/op	       0 allocs/op
BenchmarkXTEA-4                	   30000	     45825 ns/op	  65.47 MB/s	       0 B/op	       0 allocs/op
BenchmarkSalsa20-4             	  500000	      3282 ns/op	 913.90 MB/s	       0 B/op	       0 allocs/op

来自 openssl 的 Benchmark 结果

$ openssl speed -evp aes-128-cfb
Doing aes-128-cfb for 3s on 16 size blocks: 157794127 aes-128-cfb's in 2.98s
Doing aes-128-cfb for 3s on 64 size blocks: 39614018 aes-128-cfb's in 2.98s
Doing aes-128-cfb for 3s on 256 size blocks: 9971090 aes-128-cfb's in 2.99s
Doing aes-128-cfb for 3s on 1024 size blocks: 2510877 aes-128-cfb's in 2.99s
Doing aes-128-cfb for 3s on 8192 size blocks: 310865 aes-128-cfb's in 2.98s
OpenSSL 1.0.2p  14 Aug 2018
built on: reproducible build, date unspecified
options:bn(64,64) rc4(ptr,int) des(idx,cisc,16,int) aes(partial) idea(int) blowfish(idx)
compiler: clang -I. -I.. -I../include  -fPIC -fno-common -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -arch x86_64 -O3 -DL_ENDIAN -Wall -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM -DECP_NISTZ256_ASM
The 'numbers' are in 1000s of bytes per second processed.
type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
aes-128-cfb     847216.79k   850770.86k   853712.05k   859912.39k   854565.80k

kcptun 中的加密性能与 openssl 库中的一样快(如果不是更快的话)。

内存控制

路由器,移动设备容易受到内存消耗的影响;通过设置GOGC环境(例如:GOGC=20)将使垃圾回收器回收更快。参考资料: https://blog.golang.org/go15gc

主内存分配是从全局缓冲池 xmit 完成的。Buf,在kcp-go中,当我们需要分配一些字节时,我们可以从该池中获取,并且将返回固定容量的1500字节(mtuLimit),rx队列tx队列fec队列都从那里接收字节,并且它们将在使用后将字节返回到池中,以防止不必要的字节的zer0。池机制为切片对象保持了高水位线,池中的这些动态对象将从异常垃圾回收中存活下来,同时池保持了在空闲时将内存返回到运行时的能力,,,, ,这些参数影响这个高水位线,值越大,内存消耗就越大。-sndwnd-rcvwnd-ds-ps

-smuxbuf还会影响最大内存消耗,此参数在并发和资源之间保持微妙的平衡,如果您有许多客户端要服务并且同时获得功能强大的服务器,则可以增加此值(默认4MB)以提高并发性,并且还可以减小此值以仅为1或2个客户端提供服务,并希望该程序可以在一些内存有限的嵌入式SoC系统下运行,并且只有您可以访问。(请注意,该值与并发性无关,您需要进行测试。-smuxbuf

压缩

kcptun内置了用于压缩流的快速算法:

Snappy 是一个压缩/解压缩库。它不以最大压缩或与任何其他压缩库的兼容性为目标;相反,它的目标是非常高的速度和合理的压缩。例如,与zlib的最快模式相比,Snappy对于大多数输入来说快了一个数量级,但生成的压缩文件要大20%到100%。

参考资料: http://google.github.io/snappy/

压缩可以节省明文数据的带宽,对于跨数据中心复制的特定方案非常有用,通过压缩dbms或类似kafka的消息队列中的redologs,然后在整个大陆传输数据流可以更快。

默认情况下启用压缩,您可以通过在KCP客户端和KCP服务器上设置必须相同来禁用它。-nocomp

SNMP

type Snmp struct {
    BytesSent        uint64 // bytes sent from upper level
    BytesReceived    uint64 // bytes received to upper level
    MaxConn          uint64 // max number of connections ever reached
    ActiveOpens      uint64 // accumulated active open connections
    PassiveOpens     uint64 // accumulated passive open connections
    CurrEstab        uint64 // current number of established connections
    InErrs           uint64 // UDP read errors reported from net.PacketConn
    InCsumErrors     uint64 // checksum errors from CRC32
    KCPInErrors      uint64 // packet iput errors reported from KCP
    InPkts           uint64 // incoming packets count
    OutPkts          uint64 // outgoing packets count
    InSegs           uint64 // incoming KCP segments
    OutSegs          uint64 // outgoing KCP segments
    InBytes          uint64 // UDP bytes received
    OutBytes         uint64 // UDP bytes sent
    RetransSegs      uint64 // accmulated retransmited segments
    FastRetransSegs  uint64 // accmulated fast retransmitted segments
    EarlyRetransSegs uint64 // accmulated early retransmitted segments
    LostSegs         uint64 // number of segs infered as lost
    RepeatSegs       uint64 // number of segs duplicated
    FECRecovered     uint64 // correct packets recovered from FEC
    FECErrs          uint64 // incorrect packets recovered from FEC
    FECParityShards  uint64 // FEC segments received
    FECShortShards   uint64 // number of data shards that's not enough for recovery
}

向 KCP 客户端或 KCP 服务器发送信号会将 SNMP 信息转储到控制台,就像 .您可以使用此信息进行细粒度调整。SIGUSR1/proc/net/snmp

手动控制

https://github.com/skywind3000/kcp/blob/master/README.en.md#protocol-configuration

-mode manual -nodelay 1 -interval 20 -resend 2 -nc 1

可以使用上述手动模式更改低级KCP配置,请确保在进行任何手动设置之前真正了解这些含义。

相同的参数表

这些参数在必须相同

  1. -key
  2. -crypt
  3. -nocomp
  4. -smuxver

引用

  1. https://github.com/skywind3000/kcp -- KCP - 一种快速可靠的 ARQ 协议。
  2. https://github.com/xtaci/kcp-go/ -- 用于 golang 的生产级可靠 UDP 库
  3. https://github.com/klauspost/reedsolomon -- Reed-Solomon Erasure Coding in Go.
  4. https://en.wikipedia.org/wiki/Differentiated_services -- DSCP.
  5. http://google.github.io/snappy/ -- 快速压缩机/减压器。
  6. https://www.backblaze.com/blog/reed-solomon/--里德-所罗门解释道。
  7. http://www.qualcomm.cn/products/raptorq -- RaptorQ 用于对象交付的前向纠错方案。
  8. https://en.wikipedia.org/wiki/PBKDF2 -- 按键拉伸。
  9. http://blog.appcanary.com/2016/encrypt-or-compress.html -- 应该先加密还是压缩?
  10. https://github.com/hashicorp/yamux -- 连接多路复用库。
  11. https://tools.ietf.org/html/rfc6937 -- TCP 的成比例速率降低。
  12. https://tools.ietf.org/html/rfc5827 -- TCP 和流控制传输协议 (SCTP) 的早期重新传输。
  13. http://http2.github.io/ -- 什么是 HTTP/2?
  14. http://www.lartc.org/ -- Linux Advanced Routing & Traffic Control
  15. https://en.wikipedia.org/wiki/Noisy-channel_coding_theorem -- 噪声信道编码定理
  16. https://zhuanlan.zhihu.com/p/53849089 -- kcptun开发小记

(注意:我没有任何社交网站的账号,请小心骗子。)




本文翻译自 https://github.com/xtaci/kcptun

Comments

Popular posts from this blog

Python Receiving and parse JSON Data via UDP protocol

ubus lua client method and event registration code demo/example