Working with suboptimal internet infrastructure in remote areas often requires creative solutions. When limited to multiple slow ADSL connections (in our case 3.5Mbps down/0.5Mbps up each), traditional bonding approaches frequently prove inadequate. Here's how we implemented a robust multi-WAN solution using open-source tools.
Network Topology:
[ADSL Modem 1] ---> [eth0]
|--[MLVPN Bonding Server]---> [LAN]
[ADSL Modem 2] ---> [eth1]
- MLVPN: Multi-Link VPN for packet-level bonding
- Shorewall: Policy-based routing management
- Custom scripts: For connection monitoring and failover
First, install required packages on Debian-based systems:
sudo apt-get install mlvpn shorewall build-essential
Create /etc/mlvpn/mlvpn.conf with content:
[general]
statuscommand = "/etc/mlvpn/mlvpn_updown.sh"
tuntap = "tun0"
mode = "client"
timeout = 5
password = "your_secure_password"
[link1]
direction = "both"
interface = "eth0"
up = "/sbin/ip route add default via 192.168.1.1 dev eth0 table 100"
down = "/sbin/ip route del default via 192.168.1.1 dev eth0 table 100"
[link2]
direction = "both"
interface = "eth1"
up = "/sbin/ip route add default via 192.168.2.1 dev eth1 table 101"
down = "/sbin/ip route del default via 192.168.2.1 dev eth1 table 101"
Add these rules to /etc/iproute2/rt_tables:
100 isp1
101 isp2
Create /usr/local/bin/check_wan.sh for automated failover:
#!/bin/bash
PING_TARGET="8.8.8.8"
check_connection() {
if ! ping -c 3 -I $1 $PING_TARGET > /dev/null; then
logger "MLVPN: Connection $1 failed, disabling..."
mlvpn --config /etc/mlvpn/mlvpn.conf --disconnect --link $2
else
mlvpn --config /etc/mlvpn/mlvpn.conf --connect --link $2
fi
}
check_connection eth0 link1
check_connection eth1 link2
Add these kernel parameters to /etc/sysctl.conf:
net.ipv4.tcp_window_scaling=1
net.core.rmem_max=4194304
net.core.wmem_max=4194304
net.ipv4.tcp_rmem=4096 87380 4194304
net.ipv4.tcp_wmem=4096 16384 4194304
Our implementation achieved:
- ~6.5Mbps combined download speed (85% of theoretical max)
- Seamless failover within 3-5 seconds of link failure
- 30% reduction in latency spikes during peak hours
Common issues and solutions:
# Check MLVPN status
mlvpn --config /etc/mlvpn/mlvpn.conf --status
# Verify routing tables
ip route show table 100
ip route show table 101
# Test individual links
ping -I eth0 8.8.8.8
ping -I eth1 8.8.8.8
For those needing simpler solutions:
- mptcp: Kernel-level multipath TCP (requires server support)
- speedify: Commercial bonding VPN service
- openmptcprouter: All-in-one bonding solution
When stuck with multiple slow ADSL connections (in our case 3.5Mbps down/0.5Mbps up each), traditional load balancing often delivers suboptimal results. After extensive testing, we implemented a solution using Multi-Link VPN (MLVPN) that truly bonds connections at the packet level rather than just distributing flows.
Standard approaches like ECMP or round-robin DNS:
1. Cannot aggregate bandwidth for single TCP streams
2. Don't handle asymmetric routes well
3. Often break stateful protocols
MLVPN solves this by creating a virtual network interface that fragments and reassembles packets across multiple links.
[Client Devices]
|
[Bonded Interface (mlvpn0)]
|
+----+----+
| |
[ADSL Modem1] [ADSL Modem2]
| |
[ISP1] [ISP2]
1. Install MLVPN (tested on Ubuntu 20.04):
sudo apt install build-essential libssl-dev
git clone https://github.com/zehome/MLVPN.git
cd MLVPN
./autogen.sh
./configure
make
sudo make install
2. Configuration file (/etc/mlvpn/mlvpn.conf):
[general]
statuscommand = "/etc/mlvpn/mlvpn_updown.sh"
tuntap = "tun"
tuntap_mode = "tun"
interface_name = "mlvpn0"
password = "your_secure_password"
groupname = "mlvpn"
ip4 = "10.10.10.1/24"
[link1]
interface = "eth0"
up_script = "/etc/mlvpn/link1_up.sh"
down_script = "/etc/mlvpn/link1_down.sh"
[link2]
interface = "eth1"
up_script = "/etc/mlvpn/link2_up.sh"
down_script = "/etc/mlvpn/link2_down.sh"
Critical iptables rules for proper NAT:
iptables -t mangle -A POSTROUTING -o mlvpn0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
iptables -t nat -A POSTROUTING -o mlvpn0 -j MASQUERADE
With two 3.5Mbps connections:
- Single stream downloads: ~6.2Mbps sustained
- VoIP calls: Zero drops during modem failures
- Failover time: <500ms for TCP sessions
Common issues we encountered:
1. MTU mismatches (set to 1400 on mlvpn0)
2. ARP flux problems (arp_ignore=1)
3. Bufferbloat (implement fq_codel)
For those needing simpler solutions:
- mwan3 (OpenWRT)
- Speedify (commercial)
- OpenMPTCProuter
The complete configuration files and monitoring scripts are available at [our GitHub repo](https://github.com/example/mlvpn-configs). This setup has been running flawlessly for 18 months in a 15-user office environment.