High-performance bandwidth aggregation across multiple internet connections
ChainLightning is a UDP-based bonding tunnel that aggregates bandwidth from multiple WAN links (DSL, cable, fiber, Starlink, LTE, etc.) into a single high-throughput tunnel. It features intelligent traffic distribution, Forward Error Correction (FEC), and dynamic link quality monitoring.
- ✓ Multi-WAN Aggregation: Combine up to 5+ WAN links
- ✓ Intelligent Load Balancing: Traffic distributed based on link quality and capacity
- ✓ Forward Error Correction (FEC): Automatic packet recovery without retransmits
- ✓ Real-time Link Monitoring: Latency and bandwidth tracking per link
- ✓ Automatic Failover: Seamless switching when links degrade
- ✓ TUN Interface: Standard Linux networking integration
- Throughput: Aggregate bandwidth from all WAN links
- Latency: Smart routing via fastest available link
- Reliability: FEC provides resilience against packet loss
- Tested: 5 WAN links (2x Starlink + 3x ADSL) in production
LAN Clients → TUN Interface → CLIENT (striping) → [Multi-WAN UDP] → SERVER → Internet
Client Side:
- Creates TUN interface (default: 10.99.0.2)
- Binds UDP sockets to each WAN interface
- Strips traffic across all available links
- Monitors link quality and adjusts distribution
Server Side:
- Receives aggregated traffic from all client links
- Reassembles packets and forwards to internet
- Returns traffic via best available client link
- Linux (Ubuntu 20.04+ / Debian 11+ recommended)
- Root/sudo access (for TUN interface creation)
- Rust toolchain (1.70+)
- Client: Multiple WAN interfaces with internet access
- Server: VPS with public IP address
- UDP ports 9001-9005 (or configured range) open on server
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/envgit clone https://github.com/cronos3k/chainlightning.git
cd chainlightningEdit config.toml and replace placeholders with your network configuration:
[general]
server_ip = "<YOUR_SERVER_IP>" # Your VPS public IP
tun_name = "tun-bond"
tun_local_ip = "10.99.0.2" # Client TUN IP
tun_remote_ip = "10.99.0.1" # Server TUN IP
tun_netmask = "255.255.255.0"
[links]
source_ips = [
"<YOUR_WAN1_IP>", # IP of your first WAN interface
"<YOUR_WAN2_IP>", # IP of your second WAN interface
"<YOUR_WAN3_IP>", # IP of your third WAN interface
# Add more WAN IPs as needed
]
start_port = 9001
links_per_wan = 2 # 2 UDP streams per physical WAN
[performance]
fec_group_size = 10 # Packets per FEC group
fec_repair_packets = 3 # Redundancy packets per group
heartbeat_interval_ms = 100 # Link health check intervalFinding Your WAN IPs:
# List all network interfaces and their IPs
ip addr show
# Example output:
# 2: eth0: inet 192.168.1.100/24 ← This is a WAN IP
# 3: eth1: inet 192.168.2.50/24 ← This is another WAN IPcargo build --releaseBinaries will be in target/release/:
client- Run on your router/gatewayserver- Run on your VPS
# Run server (listens on all interfaces, ports 9001-9005)
sudo ./target/release/serverServer will:
- Listen for client connections on UDP ports 9001-9005
- Create TUN interface with IP 10.99.0.1
- Forward decrypted traffic to internet
# Run client
sudo ./target/release/clientClient will:
- Create TUN interface with IP 10.99.0.2
- Bind UDP sockets to each configured WAN IP
- Connect to server and start traffic bonding
- Display link statistics every 10 seconds
# On client, ping server through tunnel
ping -I tun-bond 10.99.0.1
# Check tunnel interface
ip addr show tun-bond# Route all traffic through bonded tunnel
sudo ip route add default via 10.99.0.2 dev tun-bond table 100
sudo ip rule add from 10.99.0.0/24 lookup 100
# Or use iptables for specific traffic
sudo iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j MASQUERADEThe number of WAN links is determined by the source_ips array in config.toml:
source_ips = [
"192.168.1.100", # WAN 1
"192.168.2.50", # WAN 2
# Add more as needed - no hard limit
][performance]
# FEC Configuration
fec_group_size = 10 # Larger = more efficient, more latency
fec_repair_packets = 3 # More = better loss recovery, more overhead
# Link Monitoring
heartbeat_interval_ms = 100 # How often to check link health
rtt_weight = 0.7 # Weight for latency in scoring
loss_weight = 0.3 # Weight for packet loss in scoring# Ensure TUN module is loaded
sudo modprobe tun# Check client logs
sudo journalctl -u chainlightning-client -f
# Verify UDP ports are reachable
nc -u <SERVER_IP> 9001- Increase
fec_repair_packetsin config.toml - Check individual WAN link quality
- Verify server has sufficient bandwidth
- Verify WAN IP is correct in config.toml
- Check firewall rules on client
- Ensure WAN interface has internet access
chainlightning/
├── src/
│ ├── client.rs # Client main logic
│ ├── server.rs # Server main logic
│ ├── fec.rs # Forward Error Correction
│ ├── probes.rs # Link quality monitoring
│ ├── traffic_shaper.rs # Traffic distribution
│ └── obfuscation.rs # Optional traffic obfuscation
├── config.toml # Configuration template
├── Cargo.toml # Rust dependencies
└── README.md # This file
# Debug build (faster compile, slower runtime)
cargo build
# Release build (optimized)
cargo build --release
# Run tests
cargo test
# Check for issues
cargo clippy- Latency: Adds ~10-30ms depending on FEC settings
- Overhead: ~5-15% from FEC and headers
- CPU: Minimal (<5% on modern hardware)
- Memory: ~50MB per instance
MIT License - see LICENSE file
Contributions welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Submit a pull request
- Issues: https://github.com/cronos3k/chainlightning/issues
- Discussions: https://github.com/cronos3k/chainlightning/discussions
- Built with Rust and Tokio async runtime
- Inspired by multi-path TCP and MPTCP projects
- FEC implementation based on Reed-Solomon erasure coding