- Notifications
You must be signed in to change notification settings - Fork2.6k
A Quantum-Safe Secure Tunnel based on QPP, KCP, FEC, and N:M multiplexing.
License
xtaci/kcptun
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Disclaimer: kcptun maintains a single website —github.com/xtaci/kcptun. Any websites other thangithub.com/xtaci/kcptun are not endorsed by xtaci.
Target | Minimum | Recommended |
---|---|---|
System | aix darwin dragonfly freebsd linux netbsd openbsd solaris windows | linux |
Memory | >20MB | >32MB |
CPU | ANY | amd64 with AES-NI & AVX2 |
NOTE: if you are using kvm, make sure the guest os can do AES instructions
Download:
curl -L https://raw.githubusercontent.com/xtaci/kcptun/master/download.sh | sh
Increase the number of open files on your server, as:
ulimit -n 65535
, or write it in~/.bashrc
.
Suggestedsysctl.conf
parameters for better handling of UDP packets:
net.core.rmem_max=26214400 // BDP - bandwidth delay productnet.core.rmem_default=26214400net.core.wmem_max=26214400net.core.wmem_default=26214400net.core.netdev_max_backlog=2048 // proportional to -rcvwnd
You can also increase the per-socket buffer by adding parameter(default 4MB):
-sockbuf 16777217
forslow processors, increasing this buffer isCRITICAL to receive packets properly.
Download a corresponding one from precompiledReleases.
KCP Client: ./client_darwin_amd64 -r "KCP_SERVER_IP:4000" -l ":8388" -mode fast3 -nocomp -autoexpire 900 -sockbuf 16777217 -dscp 46KCP Server: ./server_linux_amd64 -t "TARGET_IP:8388" -l ":4000" -mode fast3 -nocomp -sockbuf 16777217 -dscp 46
The above commands will establish port forwarding channel for 8388/tcp as:
Application ->KCP Client(8388/tcp) -> KCP Server(4000/udp) -> Target Server(8388/tcp)
which tunnels the original connection:
Application -> Target Server(8388/tcp)
$ git clone https://github.com/xtaci/kcptun.git$ cd kcptun$ ./build-release.sh$ cd build
All precompiled releases are generated frombuild-release.sh
script.
Practical bandwidth graph with parameters: -mode fast3 -ds 10 -ps 3
Q: I have a high-speed network link. How can I maximize bandwidth?
A: Increase
-rcvwnd
on the KCP Client and-sndwnd
on the KCP Serversimultaneously and gradually. The minimum of these values determines the maximum transfer rate of the link, aswnd * mtu / rtt
. Then, try downloading something to see if it meets your requirements. (The MTU is adjustable with-mtu
.)
Q: I'm using kcptun for gaming and want to avoid any lag.
A: Lag often indicates packet loss. You can reduce lag by changing the
-mode
parameter.
For example:
-mode fast3
Aggressiveness/Responsiveness on retransmission for embedded modes:
fast3 > fast2 > fast > normal > default
Since streams are multiplexed into a single physical channel, head-of-line blocking may occur. Increasing-smuxbuf
to a larger value (default is 4MB) may mitigate this problem, though it will use more memory.
For versions >= v20190924, you can switch to smux version 2. Smux v2 has options to limit per-stream memory usage. Set-smuxver 2
to enable smux v2, and adjust-streambuf
to limit per-stream memory usage. For example:-streambuf 2097152
limits per-stream memory usage to 2MB. Limiting the stream buffer on the receiver side applies back-pressure to the sender, preventing the sender from overwhelming the buffer along the link. (The-smuxver
settingMUST beIDENTICAL on both sides, the default is 1.)
kcptun usesReed-Solomon Codes to recover lost packets, which requires substantial computation. Low-end ARM devices may not perform well with kcptun. For optimal performance, a multi-core x86 home server CPU like AMD Opteron is recommended. If you must use ARM routers, it's best to disableFEC
and usesalsa20
as the encryption method.
> ./client_freebsd_amd64 -hNAME: kcptun - client(with SMUX)USAGE: client_freebsd_amd64 [global options] command [command options] [arguments...]VERSION: 20240729COMMANDS: help, h Shows a list of commands or help for one commandGLOBAL OPTIONS: --localaddr value, -l value local listen address (default: ":12948") --remoteaddr value, -r value kcp server address, eg: "IP:29900" a for single port, "IP:minport-maxport" for port range (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, null (default: "aes") --mode value profiles: fast3, fast2, fast, normal, manual (default: "fast") --QPP enable Quantum Permutation Pads(QPP) --QPPCount value the prime number of pads to use for QPP: The more pads you use, the more secure the encryption. Each pad requires 256 bytes. (default: 61) --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 --pprof start profiling server on :6060 --help, -h show help --version, -v print the version > ./server_freebsd_amd64 -hNAME: kcptun - server(with SMUX)USAGE: server_freebsd_amd64 [global options] command [command options] [arguments...]VERSION: 20240729COMMANDS: help, h Shows a list of commands or help for one commandGLOBAL OPTIONS: --listen value, -l value kcp server listen address, eg: "IP:29900" for a single port, "IP:minport-maxport" for port range (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, null (default: "aes") --QPP enable Quantum Permutation Pads(QPP) --QPPCount value the prime number of pads to use for QPP: The more pads you use, the more secure the encryption. Each pad requires 256 bytes. (default: 61) --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
kcptun supports multi-port dialer like below:
client: --remoteaddr IP:minport-maxportserver: --listen IP:minport-maxporteg:client: --remoteaddr IP:3000-4000server: --listen 0.0.0.0:3000-4000
by specifying port-range, kcptun will automatically switch to next random port within port-range when establishing each new connection.
In coding theory, theReed–Solomon code belongs to the class of non-binary cyclic error-correcting codes. The Reed–Solomon code is based on univariate polynomials over finite fields.
It is able to detect and correct multiple symbol errors. By adding t check symbols to the data, a Reed–Solomon code can detect any combination of up to t erroneous symbols, or correct up to ⌊t/2⌋ symbols. As an erasure code, it can correct up to t known erasures, or it can detect and correct combinations of errors and erasures. Furthermore, Reed–Solomon codes are suitable as multiple-burst bit-error correcting codes, since a sequence of b + 1 consecutive bit errors can affect at most two symbols of size b. The choice of t is up to the designer of the code, and may be selected within wide limits.
Differentiated services or DiffServ is a computer networking architecture that specifies a simple, scalable and coarse-grained mechanism for classifying and managing network traffic and providing quality of service (QoS) on modern IP networks. DiffServ can, for example, be used to provide low-latency to critical network traffic such as voice or streaming media while providing simple best-effort service to non-critical services such as web traffic or file transfers.
DiffServ uses a 6-bit differentiated services code point (DSCP) in the 8-bit differentiated services field (DS field) in the IP header for packet classification purposes. The DS field and ECN field replace the outdated IPv4 TOS field.
setting each side with-dscp value
, Here are someCommonly used DSCP values.
kcptun is shipped with builtin packet encryption powered by various block encryption algorithms and works inCipher Feedback Mode, for each packet to be sent, the encryption process will start from encrypting anonce from thesystem entropy, so encryption to same plaintexts never leads to a same ciphertexts thereafter.
The contents of the packets are completely anonymous with encryption, including the headers(FEC,KCP), checksums and contents. Note that, no matter which encryption method you choose on you upper layer, if you disable encryption by specifying-crypt none
to kcptun, the transmit will be insecure somehow, since the header isPLAINTEXT to everyone it would be susceptible to header tampering, such as jamming thesliding window size,round-trip time,FEC property andchecksums.aes-128
is suggested for minimal encryption since modern CPUs are shipped withAES-NI instructions and performs even better thansalsa20
(check the table below).
Other possible attacks to kcptun includes: a)traffic analysis, dataflow on specific websites may have pattern while interchanging data, but this type of eavesdropping has been mitigated by adaptingsmux to mix data streams so as to introduce noises, perfect solution to this has not appeared yet, theoretically by shuffling/mixing messages on larger scale network may mitigate this problem. b)replay attack, since the asymmetrical encryption has not been introduced into kcptun for some reason, capturing the packets and replay them on a different machine is possible, (notice: hijacking the session and decrypting the contents is stillimpossible), so upper layers should contain a asymmetrical encryption system to guarantee the authenticity of each message(to process message exactly once), such as HTTPS/OpenSSL/LibreSSL, only by signing the requests with private keys can eliminate this type of attack.
Important:
-crypt
and-key
must be the same on both KCP Client & KCP Server.-crypt xor
is also insecure and vulnerable toknown-plaintext attack, do not use this unless you know what you are doing. (cryptanalysis note: any type ofcounter mode is insecure in packet encryption due to the shorten of counter period and leads to iv/nonce collision)
Benchmarks for crypto algorithms supported by kcptun:
BenchmarkSM4-4 50000 32087 ns/op 93.49 MB/s 0 B/op 0 allocs/opBenchmarkAES128-4 500000 3274 ns/op 916.15 MB/s 0 B/op 0 allocs/opBenchmarkAES192-4 500000 3587 ns/op 836.34 MB/s 0 B/op 0 allocs/opBenchmarkAES256-4 300000 3828 ns/op 783.60 MB/s 0 B/op 0 allocs/opBenchmarkTEA-4 100000 15359 ns/op 195.32 MB/s 0 B/op 0 allocs/opBenchmarkXOR-4 20000000 90.2 ns/op33249.02 MB/s 0 B/op 0 allocs/opBenchmarkBlowfish-4 50000 26885 ns/op 111.58 MB/s 0 B/op 0 allocs/opBenchmarkNone-4 30000000 45.8 ns/op65557.11 MB/s 0 B/op 0 allocs/opBenchmarkCast5-4 50000 34370 ns/op 87.29 MB/s 0 B/op 0 allocs/opBenchmark3DES-4 10000 117893 ns/op 25.45 MB/s 0 B/op 0 allocs/opBenchmarkTwofish-4 50000 33477 ns/op 89.61 MB/s 0 B/op 0 allocs/opBenchmarkXTEA-4 30000 45825 ns/op 65.47 MB/s 0 B/op 0 allocs/opBenchmarkSalsa20-4 500000 3282 ns/op 913.90 MB/s 0 B/op 0 allocs/op
Benchmark result from openssl
$ openssl speed -evp aes-128-cfbDoing aes-128-cfb for 3s on 16 size blocks: 157794127 aes-128-cfb's in 2.98sDoing aes-128-cfb for 3s on 64 size blocks: 39614018 aes-128-cfb's in 2.98sDoing aes-128-cfb for 3s on 256 size blocks: 9971090 aes-128-cfb's in 2.99sDoing aes-128-cfb for 3s on 1024 size blocks: 2510877 aes-128-cfb's in 2.99sDoing aes-128-cfb for 3s on 8192 size blocks: 310865 aes-128-cfb's in 2.98sOpenSSL 1.0.2p 14 Aug 2018built on: reproducible build, date unspecifiedoptions: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_ASMThe 'numbers' are in 1000s of bytes per second processed.type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytesaes-128-cfb 847216.79k 850770.86k 853712.05k 859912.39k 854565.80k
The encryption performance in kcptun is as fast as in openssl library(if not faster).
Quantum Resistance, also known as quantum-secure, post-quantum, or quantum-safe cryptography, refers to cryptographic algorithms that can withstand potential code-breaking attempts by quantum computer.In kcptun, after v20240701, it adaptsQPP based onKuang's Quantum Permutation Pad for quantum-resistent communication.
To enable QPP in kcptun, you need to set:
--QPP enable Quantum Permutation Pads(QPP) --QPPCount value the prime number of pads to use for QPP: The more pads you use, the more secure the encryption. Each pad requires 256 bytes. (default: 61)
Your could also specify
"qpp":true,"qpp-count":61,
in your client and server side json file. These 2 parameters must be identical on both sides.
- To achieveEffective Quantum-Resistance,, specify at least211 bytes in the
-key
parameter and ensure-QPPCount
is no less than7. - Make sure
-QPPCount
isCOPRIME(互素) to8(or simply set to aPRIME number) like:101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199...
Routers, mobile devices are susceptible to memory consumption; by setting GOGC environment(eg: GOGC=20) will make the garbage collector to recycle faster.Reference:https://blog.golang.org/go15gc
Primary memory allocation are done from a global buffer poolxmit.Buf, in kcp-go, when we need to allocate some bytes, we can get from that pool, and afixed-capacity 1500 bytes(mtuLimit) will be returned, therx queue,tx queue andfec queue all receive bytes from there, and they will return the bytes to the pool after using to preventunnecessary zer0ing of bytes.The pool mechanism maintained ahigh watermark for slice objects, thesein-flight objects from the pool will survive from the periodical garbage collection, meanwhile the pool kept the ability to return the memory to runtime if in idle,-sndwnd
,-rcvwnd
,-ds
,-ps
, these parameters affect thishigh watermark, the larger the value, the bigger the memory consumption will be.
-smuxbuf
also affects the maximum memory consumption, this parameter maintains a subtle balance betweenconcurrency andresource, you can increase this value(default 4MB) to boost concurrency if you have many clients to serve and you get a powerful server at the same time, and also you can decrease this value to serve only 1 or 2 clients and hope this program can run under some embedded SoC system with limited memory and only you can access. (Notice that the-smuxbuf
value is not proportional to concurrency, you need to test.)
kcptun has builtin snappy algorithms for compressing streams:
Snappy is a compression/decompression library. It does not aim for maximumcompression, or compatibility with any other compression library; instead,it aims for very high speeds and reasonable compression. For instance,compared to the fastest mode of zlib, Snappy is an order of magnitude fasterfor most inputs, but the resulting compressed files are anywhere from 20% to100% bigger.
Reference:http://google.github.io/snappy/
Compression may save bandwidth forPLAINTEXT data, it's quite useful for specific scenarios as cross-datacenter replications, by compressing the redologs in dbms or kafka-like message queues and then transfer the data streams across the continent can be much faster.
Compression is enabled by default, you can disable it by setting-nocomp
onBOTH KCP Client & KCP ServerMUST beIDENTICAL.
typeSnmpstruct {BytesSentuint64// bytes sent from upper levelBytesReceiveduint64// bytes received to upper levelMaxConnuint64// max number of connections ever reachedActiveOpensuint64// accumulated active open connectionsPassiveOpensuint64// accumulated passive open connectionsCurrEstabuint64// current number of established connectionsInErrsuint64// UDP read errors reported from net.PacketConnInCsumErrorsuint64// checksum errors from CRC32KCPInErrorsuint64// packet input errors reported from KCPInPktsuint64// incoming packets countOutPktsuint64// outgoing packets countInSegsuint64// incoming KCP segmentsOutSegsuint64// outgoing KCP segmentsInBytesuint64// UDP bytes receivedOutBytesuint64// UDP bytes sentRetransSegsuint64// accumulated retransmitted segmentsFastRetransSegsuint64// accumulated fast retransmitted segmentsEarlyRetransSegsuint64// accumulated early retransmitted segmentsLostSegsuint64// number of segs inferred as lostRepeatSegsuint64// number of segs duplicatedFECRecovereduint64// correct packets recovered from FECFECErrsuint64// incorrect packets recovered from FECFECParityShardsuint64// FEC segments receivedFECShortShardsuint64// number of data shards that's not enough for recovery}
Sending aSIGUSR1
signal to KCP Client or KCP Server will dump SNMP information to console, just like/proc/net/snmp
. You can use this information to do fine-grained tuning.
https://github.com/skywind3000/kcp/blob/master/README.en.md#protocol-configuration
-mode manual -nodelay 1 -interval 20 -resend 2 -nc 1
Low-level KCP configuration can be altered by using manual mode like above, make sure you reallyUNDERSTAND what these means before doingANY manual settings.
These parametersMUST beIDENTICAL onBOTH side:
- -key
- -crypt
- -nocomp
- -smuxver
- https://github.com/skywind3000/kcp -- KCP - A Fast and Reliable ARQ Protocol.
- https://github.com/xtaci/kcp-go/ -- A Production-Grade Reliable-UDP Library for golang
- https://github.com/klauspost/reedsolomon -- Reed-Solomon Erasure Coding in Go.
- https://en.wikipedia.org/wiki/Differentiated_services -- DSCP.
- http://google.github.io/snappy/ -- A fast compressor/decompressor.
- https://www.backblaze.com/blog/reed-solomon/ -- Reed-Solomon Explained.
- http://www.qualcomm.cn/products/raptorq -- RaptorQ Forward Error Correction Scheme for Object Delivery.
- https://en.wikipedia.org/wiki/PBKDF2 -- Key stretching.
- http://blog.appcanary.com/2016/encrypt-or-compress.html -- Should you encrypt or compress first?
- https://github.com/hashicorp/yamux -- Connection multiplexing library.
- https://tools.ietf.org/html/rfc6937 -- Proportional Rate Reduction for TCP.
- https://tools.ietf.org/html/rfc5827 -- Early Retransmit for TCP and Stream Control Transmission Protocol (SCTP).
- http://http2.github.io/ -- What is HTTP/2?
- http://www.lartc.org/ -- Linux Advanced Routing & Traffic Control
- https://en.wikipedia.org/wiki/Noisy-channel_coding_theorem -- Noisy channel coding theorem
- https://zhuanlan.zhihu.com/p/53849089 -- kcptun开发小记
(注意:我没有任何社交网站的账号,请小心骗子。)
About
A Quantum-Safe Secure Tunnel based on QPP, KCP, FEC, and N:M multiplexing.