A BPF-based tool for tunneling UDP traffic over ICMP, serving as an alternative to udp2raw's ICMP mode.
It is recommended to use this tool together with kcptun, hysteria, wireguard, and similar tools. This combination helps to effectively bypass increasingly strict UDP QOS and packet loss policies imposed by the GFW or ISPs, greatly improving penetration capability and connection stability.
- Several times faster than
udp2rawin maximum throughput under the same CPU load, while consuming significantly less CPU resources. See Performance Benchmarks. - Secure by design and implementation.
- Supports running on
OpenWrt. - Supports
ICMP/ICMPv6for bothIPv4/IPv6. - Allows for secure and rapid synchronization of server/client configurations using
tuctl_server.
tutuicmptunnel consists of two parts: a server and a client. Each host can only act as one role, not both.
To distinguish packets from different clients, each client connected to the server is assigned a unique UID ranging from 0 to 255.
This UID corresponds to the code field in the ICMP protocol, meaning each server can support up to 256 clients.
A client can also map to different servers. For instance, traffic to host 1.2.3.4 on port 3322 can be mapped to UID 100,
while traffic to 2.3.4.5 on port 2233 can be mapped to UID 101.
This allows a client to flexibly manage access to multiple servers using different UIDs.
Clients are allowed to use the same UID on different servers, as the UID only identifies the client's identity on a specific server.
In other words, the UID is unique only within the scope of each server and can be reused across different servers.
- The client uses a 3-tuple [
UID, ServerIP, Destination Port (port)] to identify which UDP packets need to be converted to ICMP. - The server uses a 3-tuple [
UID, ClientIP, Destination Port (port)] to identify which ICMP packets need to be restored and forwarded as UDP. - The
IPaddress can beIPv4orIPv6.tutuicmptunnelwill automatically selectICMPorICMPv6for encapsulation and forwarding based on the IP type.
tutuicmptunnel can be paired with tools like WireGuard, xray-core+kcptun, and hysteria.
Since these applications already provide encryption and integrity checks, tutuicmptunnel does not handle data encryption, obfuscation, or validation, focusing solely on data encapsulation and forwarding.
tutuicmptunnel does not modify the payload of data packets, nor does it add extra IP headers.
Forwarding rules on the server are configured entirely by the user manually adding the aforementioned 3-tuples via commands.
The client can invoke server commands via SSH: using the tuctl command to manually modify the 3-tuples (including updating the client's own IP address).
To facilitate dynamic updates, the tuctl_client tool can be used to synchronize configuration via the UDP protocol, allowing the client to notify the server of its new IP and port information.
tuctl_server and tuctl_client communicate over UDP, using a timestamp-based mechanism combined with the XChaCha20-Poly1305 encryption algorithm, Argon2id key derivation function, and a Pre-Shared Key (PSK) for secure authentication. This scheme enables clients to securely and efficiently notify the server of new configuration information in real-time.
Version: At least 20.04, with version 24.04 LTS or newer recommended.
Dependencies:
sudo apt install -y git libbpf-dev clang llvm cmake libsodium-dev dkms linux-tools libsodium-dev libelf-devNote: If you are not using the standard ubuntu kernel, please install the corresponding linux-tools for your kernel.
Or you can compile your own bpftool with cmake option: -DUSE_SYSTEM_LIBBPF_BPFTOOL=0.
Version: Latest is sufficient
Dependency Preparation:
sudo pacman -S git base-devel libbpf clang cmake libsodium dkms libsodiumVersion: At least 24.10.1, please see the OpenWrt Guide
-
Check out the code and install
git clone https://github.com/hrimfaxi/tutuicmptunnel cd tutuicmptunnel cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_HARDEN_MODE=1 -DUSE_SYSTEM_LIBBPF_BPFTOOL=1 .
Note: For
Ubuntu20.04, you need to use thegitversion oflibbpf/bpftooland disablebpf timersupport.cmake -DCMAKE_BUILD_TYPE=Release -DUSE_SYSTEM_LIBBPF_BPFTOOL=0 -DDISABLE_BPF_TIMER=1 -DBPF_CPU_VERSION="" .
make sudo make install
-
Kernel Module
Both the server and client need to install the tutu_csum_fixup kernel module, which is used to fix the ICMP packet checksum that
bpfcannot modify.cd tutu_csum_fixup sudo dkms remove tutu_csum_fixup/x.x --all # If an older version was previously installed, use dkms status to check past versions sudo make dkms sudo tee -a /etc/modules-load.d/modules.conf <<< tutu_csum_fixup sudo modprobe tutu_csum_fixup
Some systems require setting the
force_sw_checksumparameter. For details, see tutu_csum_fixup. -
Server: Set up the system service and enable the optional
tuctl_servertuctl_serverallows clients to control thetutuicmptunnelconfiguration on the server side.Please meet the following requirements:
- To prevent brute-force attacks, remember to choose a sufficiently strong
PSKpassword before use. It is best to generate one using theuuidgen -rcommand. - Since timestamps are used for validation, both the server and client require accurate system time.
# Automatically load the tutuicmptunnel service and restore configuration on boot sudo cp contrib/etc/systemd/system/[email protected] /etc/systemd/system/ sudo systemctl enable --now [email protected] # where eth0 is the server's network interface # Optional tuctl_server sudo cp contrib/etc/systemd/system/tutuicmptunnel-tuctl-server.service /etc/systemd/system/ # Modify psk, port, etc. sudo vim /etc/systemd/system/tutuicmptunnel-tuctl-server.service timedatectl | grep "System clock synchronized:" # Check if the system time is synchronized with NTP # Reload configuration sudo systemctl daemon-reload # Enable the tuctl_server service sudo systemctl enable --now tutuicmptunnel-tuctl-server
At this point, you can use the
tuctlcommand to check the server status:sudo tuctl tutuicmptunnel: Role: Server, BPF build type: Release, no-fixup: off Peers: ....
Alternatively, you can manually start
tutuicmptunnelin server mode without using thesystemdservice:sudo tuctl unload iface eth0 # First, clean up sudo tuctl load iface eth0 # Load bpf to the eth0 interface sudo tuctl server # Set to server mode sudo tuctl server-add uid 123 address 1.2.3.4 port 1234 # Add a client (id 123) with IP 1.2.3.4 and destination UDP port 1234 sudo tuctl server-del uid 123 # Delete the previous client
- To prevent brute-force attacks, remember to choose a sufficiently strong
-
Optional: Set up a
UIDand hostname mapping tableTo facilitate
UIDmanagement,tutuicmptunnelsupports mapping client hostnames toUIDs via the/etc/tutuicmptunnel/uidsmapping file. You can create and edit this file as follows:sudo mkdir -p /etc/tutuicmptunnel sudo vim /etc/tutuicmptunnel/uids
The format is as follows:
# # Format: UID hostname # Optional comment # 0 alice # alice's laptop 1 bob # bob's laptopAfter configuration, in the
tuctlcommand, any place that requires specifying aUID(e.g.,uid 0) can be replaced with the hostname (e.g.,user alice), making management more intuitive and convenient. -
Client: Set up the system service and enable
tutuicmptunnel# Set tutuicmptunnel to start on boot sudo cp contrib/etc/systemd/system/[email protected] /etc/systemd/system/ sudo systemctl enable --now tutuicmptunnel-client@enp4s0 # Assuming your internet interface is enp4s0
Now you can try out
tutuicmptunnel:export ADDRESS=yourserver.com # Server domain name or IP export PORT=3322 # UDP port to be converted to ICMP export TUTU_UID=123 # tutuicmptunnel user ID export PSK=yourlongpsk # PSK for tuctl_server export SERVER_PORT=14801 # Port for tuctl_server export COMMENT=yourname # A description of your client's identity, the comment can be viewed in the tuctl command output on the server after the command succeeds # Set to client mode sudo tuctl client # Set the server's endpoint configuration sudo tuctl client-add uid $TUTU_UID address $ADDRESS port $PORT # Verify if correct sudo tuctl status # Use 3322.net to get the client's public IP IP=$(curl -s ip.3322.net) # Use tuctl_client to notify the server of the new client settings tuctl_client psk $PSK server $ADDRESS server-port $SERVER_PORT <<< "server-add uid $TUTU_UID address $IP port $PORT comment $COMMENT"
At this point, you can go to the server and use the
sudo tuctlcommand to view the rules added by the client:tutuicmptunnel: Role: Server, BPF build type: Release, no-fixup: off Peers: User: xxxx, Address: xxx.xxx.xxx.xxx, Sport: 37926, Dport: 3322, ICMP: 11403, Comment: yourname
If everything is configured correctly, the
UDPcommunication between the client and the server, originally with the client as the source address and 3322 as the destination port, will be automatically converted intoICMPpackets bytutuicmptunnelon the client side. After the server receives theICMPpacket, it will restore it to aUDPpacket and continue forwarding. Throughout the transmission process, intermediate network nodes can only seeICMP Echo/Replypackets.
| Name | Introduction |
|---|---|
| iperf3 | A powerful network performance testing tool used to measure bandwidth, jitter, and packet loss. |
| hysteria | A proxy tool based on the QUIC protocol, optimized for unstable and high-loss networks. |
| xray+kcptun | A combination of the Xray core and the KCPtun protocol, used to accelerate and stabilize network connections. |
| wireguard | A modern, high-performance, and easy-to-configure secure VPN tunnel. |
| openwrt | A highly customizable Linux operating system for embedded devices, especially routers. |
During its design, implementation, and performance tuning, tutuicmptunnel has referenced and benefited from numerous excellent open-source projects and technical articles. We extend our sincere gratitude to their authors and community contributors!
Special thanks to [@hack3ric] and all contributors for their continuous maintenance, making UDP→fakeTCP obfuscation on eBPF possible.
This project as a whole adheres to the GNU General Public License v2.0.
The libbpf and bpftool submodules retain their respective original licenses (LGPL-2.1 / BSD-2-Clause).