skcptun
skcptun is encrypted KCP tunnel for OpenWRT and Linux and MacOS, implemented in C language and Lua.
state
- “It’s not like it can’t be used”
- Currently, it is a version with Lua added, and the pure C version is no longer maintained.
characteristic
- Based on reliable UDP encrypted tunnel, the encrypted transmission data has no characteristics.
- It can be used to accelerate network connections, with rapid mode and normal mode. The measured transmission speed of rapid mode is much greater than TCP transmission. (bench mark)
- Currently supports two modes: TUN mode and TCP mode
- In TUN mode, the client and server each create a virtual network card on the same network segment. The client transparently transmits all IP packets to the server through the encrypted KCP tunnel, similar to the traditional VPN mode.
- In TCP mode, the client listens to one (or more) ports and transparently transmits all received data to the server through the encrypted KCP tunnel. The server transparently transmits the data to the designated server. It is generally used when TUN mode is blocked.
- You can use Lua scripts to implement your own customized services based on the API provided by skcptun.
Install
Operating environment: Linux, MacOS
Dependent libraries: OpenSSL, libev
After downloading the source code and unzipping it:
cd skcptun
mkdir build
cd build
cmake ..
make
If you clone directly, you need to update the submodule:
git submodule update --init --recursive
Environment configuration
TCP mode
- Configure the config file and start it to use
TUN mode
- Since the tunnel is established through virtual network card technology, necessary network settings need to be made.
- Taking Linux (Debian) as an example, the kernel needs to support the tun module. Confirm with "modinfo tun" command.
- Requires "iproute2" and "iptables" toolkits installed.
Server
- Enable IP forwarding, add the following configuration to the "/etc/sysctl.conf" file, and execute "sysctl -p" to take effect.
net.ipv4.ip_forward=1
net.ipv4.conf.all.route_localnet = 1
net.ipv4.conf.default.route_localnet = 1
net.ipv4.conf.[网卡接口].route_localnet = 1
net.ipv4.conf.lo.route_localnet = 1
net.ipv4.conf.[虚拟网卡接口].route_localnet = 1
- Turn on ip forwarding and modify the default forwarding policy "iptables -P FORWARD ACCEPT"
- Modify the source address of nat to the address of the egress network card "iptables -t nat -A POSTROUTING -s 192.168.2.1/24 -o enp1s0 -j MASQUERADE"
client
use
- configfile is the configuration file
- If it is TUN mode, root permissions are required to run.
Configuration file:
The configuration file is a Lua file, refer to "skcptun_config_sample", there are comments inside.
Internal variables provided by skcptun
skt
"skt" is a built-in global variable used by Lua scripts, including "skt.conf.*", "skt.api.*", and "skt.cb.*".
Configuration information of skcptun
"skt.conf.*": Configuration information variables exposed by skcptun to Lua scripts.
skt.conf.tun_ip
The IP of the virtual network card, client and server need to be set to the same network segment, valid in "tun_client" and "tun_server" modes.
skt.conf.tun_mask
The subnet mask of the virtual network card, the client and server settings are consistent, and are valid in "tun_client" and "tun_server" modes.
skt.conf.skcp_serv_conf_list_size
The number of "skcp_serv_conf".
skt.conf.skcp_serv_conf_list[i].raw
The i-th "skcp_serv_conf" itself pointer is used to pass parameters to the API.
skt.conf.skcp_serv_conf_list[i].addr
The IP address of the i-th "skcp_serv_conf"
skt.conf.skcp_serv_conf_list[i].port
The port of the i-th "skcp_serv_conf"
skt.conf.skcp_serv_conf_list[i].key
The encrypted string of the i-th "skcp_serv_conf"
skt.conf.skcp_serv_conf_list[i].ticket
The access ticket agreed between the i-th "skcp_serv_conf" client and server is valid in "tun_client" and "proxy_client" modes.
skt.conf.skcp_serv_conf_list[i].max_conn_cnt
The maximum number of connections for the i-th "skcp_serv_conf", valid in "proxy_server" and "tun_server" modes.
skt.conf.skcp_cli_conf_list* configuration is the same as skt.conf.skcp_serv_conf_list*
skt.conf.etcp_serv_conf_list_size
The number of "etcp_serv_conf_list"
skt.conf.etcp_serv_conf_list[i].raw
The pointer of the tcp server "etcp_serv_conf" itself is used to pass parameters to the API.
skt.conf.etcp_serv_conf_list[i].addr
The listening address of the tcp server.
skt.conf.etcp_serv_conf_list[i].port
The listening port of the tcp server.
skt.conf.etcp_cli_conf_list_size
The number of "etcp_cli_conf_list"
skt.conf.etcp_cli_conf_list[i].raw
The pointer of the tcp client "etcp_cli_conf" itself is used to pass parameters to the API.
skt.conf.etcp_cli_conf_list[i].addr
The connection address of the tcp client, valid in "proxy server" mode.
skt.conf.etcp_cli_conf_list[i].port
The connection port of the tcp client, valid in "proxy server" mode.
Internal Lua API provided by skcptun
"skt.api.*", the API exposed by skcptun to Lua scripts.
skt.api.skcp_init(conf, loop, skcp_mode)
Initialize skcp.
- parameter
- conf: configuration of skcp
- loop: event loop object
- skcp_mode: skcp startup mode, integer, 1 represents server mode, 2 represents client mode
- return value
- Failure returns "nil, error_msg"
- Successfully returns the skcp object
skt.api.skcp_free(skcp)
Destroy and release skcp.
- parameter
- Return value: None
skt.api.skcp_req_cid(skcp, ticket)
Request the connection id from the skcp server.
- parameter
- skcp object
- ticket: the corresponding ticket in the configuration information, string
- return value
- Failure returns "nil, error_msg"
- Return "ok" successfully
skt.api.skcp_send(skcp, cid, buf)
Send messages via skcp.
- parameter
- skcp object
- cid: connection id of skcp, integer
- buf: message content, string
- return value
- Failure returns "nil, error_msg"
- Successfully returns the number of bytes successfully sent >= 0, integer
skt.api.skcp_close_conn(skcp, cid)
Close an skcp connection.
- parameter
- skcp object
- cid: connection id of skcp, integer
- return value
- Failure returns "nil, error_msg"
- Returns 0 successfully, integer
skt.api.skcp_get_conn(skcp, cid)
Get an skcp connection.
- parameter
- skcp object
- cid: connection id of skcp, integer
- return value
- Failure returns "nil, error_msg"
- Success conn object
skt.api.etcp_server_init(conf, loop)
Initialize etcp server.
- parameter
- conf: configuration of skcp
- loop: event loop object
- return value
- Failure returns "nil, error_msg"
- Successfully returns etcp server object
skt.api.etcp_server_free(etcp)
Destroy and release the etcp server.
- parameter
- Return value None
skt.api.etcp_server_send(etcp, fd, buf)
Send messages to clients via etcp.
- parameter
- etcp server object
- fd: corresponding fd, integer
- buf: message content, string
- return value
- Failure returns "nil, error_msg"
- Successfully returns the number of bytes successfully sent > 0, integer
skt.api.etcp_server_get_conn(etcp, fd)
Obtain a connection to an etcp server.
- parameter
- etcp server object
- fd: corresponding fd, integer
- return value
- Failure returns "nil, error_msg"
- Successfully returns the conn object
skt.api.etcp_server_close_conn(etcp, fd, silent)
Close an etcp server connection.
- parameter
- etcp server object
- fd: corresponding fd, integer
- Silent: Whether to close silently. If it is not closed silently, the "on_close" event will be triggered. 1 means silent closing, 0 means non-silent closing.
- Return value: None
skt.api.etcp_client_init(conf, loop)
Initialize etcp client.
- parameter
- conf: configuration of skcp
- loop: event loop object
- return value
- Failure returns "nil, error_msg"
- Successfully returns etcp client object
skt.api.etcp_client_free(etcp)
Destroy and release the etcp client.
- parameter
- Return value: None
skt.api.etcp_client_send(etcp, fd, buf)
Send messages to the server through etcp.
- parameter
- etcp client object
- fd: corresponding fd, integer
- buf: message content, string
- return value
- Failure returns "nil, error_msg"
- Successfully returns the number of bytes successfully sent > 0, integer
skt.api.etcp_client_create_conn(etcp, addr, port)
Create an etcp connection.
- parameter
- etcp client object
- addr: Need to connect to the server address, string
- port: Need to connect to the server port
- return value
- Failure returns "nil, error_msg"
- Successfully returns the created fd, integer type
skt.api.etcp_client_close_conn(etcp, fd)
Close an etcp client connection.
- parameter
- etcp client object
- fd: corresponding fd, integer
- Return value: None
skt.api.etcp_client_get_conn(etcp, fd)
Get an etcp client connection.
- parameter
- etcp client object
- fd: corresponding fd, integer
- return value
- Failure returns "nil, error_msg"
- Successfully returns the conn object
skt.api.tuntap_write(fd, buf)
Write data to the virtual network card.
- parameter
- fd: fd of the virtual network card, integer
- buf: data to be written, string
- return value
- Failure returns "nil, error_msg"
- Number of bytes successfully written, integer
skt.api.get_from_skcp(skcp, name)
Get the corresponding field value in the skcp object, namely: "skcp.name".
- parameter
- skcp object
- name: field name in skcp, currently only supports "fd" field, string
- return value
- Failure returns "nil, error_msg"
- Successfully returns the value corresponding to name, any
skt.api.get_ms()
Get the number of milliseconds since 1970 for the current system.
- Parameters: None
- Return value:
skt.api.hton32(i)
Convert 32-bit integer variables from host byte order to network byte order.
- parameter
- i: Integer type in host byte order
- return value
- Returns an integer in network byte order
skt.api.ntoh32(i)
Convert 32-bit integer variables from network byte order to host byte order.
- parameter
- i: Integer type in network byte order
- return value
- Returns an integer in host byte order
skt.api.band(a, b)
Perform a bitwise logical AND operation on two integers and return the result
skt.api.bor(a, b)
Perform a bitwise logical OR operation on two integers and return the result
skt.api.bxor(a, b)
Perform a bitwise XOR operation on two integers and return the result
skt.api.blshift(i, n)
Shift the integer to the left by n bits and return the result
skt.api.brshift(i, n)
Shift the integer to the right by n bits and return the result
skt.api.lookup_dns(domain)
Domain name resolution
- parameter
- domain: domain name to be resolved, string
- return value
- Returns the corresponding IP in dotted format (IPV4), string
The callback interface that Lua script needs to implement
"skt.cb.*" needs to implement different interfaces according to different startup modes for skcptun callback.
skt.cb.on_init(loop)
The first callback interface called when the script starts, and is only called once
- Valid range: all modes
- parameter
- Return value: None
skt.cb.on_skcp_accept(skcp, cid)
The skcp server successfully creates a cid and is only called once for each connection.
- Valid range: "proxy_server", "tun_server"
- parameter
- skcp object
- cid: connection id of skcp, integer
- Return value: None
skt.cb.on_skcp_check_ticket(skcp, ticket)
The skcp server verifies whether the ticket is correct.
- Valid range: "proxy_server", "tun_server"
- parameter
- skcp object
- ticket: ticket that needs to be verified, string
- Return value:
- Returns 0 if verification is successful
- If verification fails, a non-zero value is returned.
skt.cb.on_skcp_recv_cid(skcp, cid)
skcp receives a cid, indicating that a connection has been successfully established with the skcp server. That is, the asynchronous structure of "skt.api.skcp_req_cid(skcp, ticket)" is returned.
- Valid range: "proxy_client", "tun_client"
- parameter
- skcp object
- cid: connection id of skcp, integer
- Return value: None
skt.cb.on_skcp_recv_data(skcp, cid, buf)
skcp receives the data corresponding to the connection of cid.
- Valid range: all modes
- parameter
- skcp object
- cid: connection id of skcp, integer
- buf: received message content, string
- Return value: None
skt.cb.on_skcp_close(skcp, cid)
The callback when skcp closes a connection may generally be caused by a timeout or receiving a close command from the peer. The connection has not been truly closed at this time.
- Valid range: all modes
- parameter
- skcp object
- cid: connection id of skcp, integer
- Return value: None
skt.cb.on_tcp_accept(fd)
The tcp server receives a connection request.
- Valid range: "proxy_client", "tun_client"
- parameter
- fd: fd requested by the connection, integer
- Return value: None
skt.cb.on_tcp_recv(fd, buf)
Receive the tcp data corresponding to the connection of fd.
- Valid range: all modes
- parameter
- fd: fd of the connection, integer
- buf: received message content, string
- Return value: None
skt.cb.on_tcp_close(fd)
Close the tcp connection corresponding to fd. The connection has not been truly closed at this moment.
- Valid range: all modes
- parameter
- fd: fd of the connection, integer
- Return value: None
skt.cb.on_tun_read(buf)
Receive data from virtual network card.
- Valid range: "tun_client", "tun_server"
- parameter
- buf: received message content, string
- Return value: None
skt.cb.on_beat()
Triggers a call every second.
- Valid range: "proxy_client", "tun_client"
- Parameters: None
- Return value: None
test
environment
- Server:Linux/1C/1G
- Client:MacOS/8C/8G
- Network status, ping value:
21 packets transmitted, 20 packets received, 4.8% packet loss
round-trip min/avg/max/stddev = 159.492/164.087/171.097/3.232 ms
Process data (RTT)
- Number of connections: 1; data packets: 1000; sending interval: 100ms
TCP RTT:
------------
Min = 161.0
Max = 1239.0
Average = 293.956
NR = 1000
Skcptun RTT:
------------
Min = 160.0
Max = 487.0
Average = 181.618
NR = 1000
- Number of connections: 10; data packets: 1000; sending interval: 100ms
TCP RTT:
------------
Min = 159.0
Max = 1076.0
Average = 262.500
NR = 10000
Skcptun RTT:
------------
Min = 159.0
Max = 534.0
Average = 174.251
NR = 10000
in conclusion
- Under the same network environment, the speed improvement effect is about 30%-40%.
Notice
- Just finished writing, for personal use and the functions are being perfected
- Please be sure not to use it to accelerate encryption sock5 proxy?