Friday, April 8, 2011

Load balance 2 WAN links BASH script

BASH script to load balance 2 WAN links.

# bal_local Load-balance internet connection over two local links
# Version: 1.0.0 - Fri, Sep 26, 2008
# Author: Niels Horn

# Set devices:
DEV1=${1-eth0} # default eth0
DEV2=${2-ppp0} # default ppp0

# Get IP addresses of our devices:
ip1=`ifconfig $DEV1 | grep inet | awk '{ print $2 }' | awk -F: '{ print $2 }'`
ip2=`ifconfig $DEV2 | grep inet | awk '{ print $2 }' | awk -F: '{ print $2 }'`

# Get default gateway for our devices:
gw1=`route -n | grep $DEV1 | grep '^' | awk '{ print $2 }'`
gw2=`route -n | grep $DEV2 | grep '^' | awk '{ print $2 }'`

echo "$DEV1: IP=$ip1 GW=$gw1"
echo "$DEV2: IP=$ip2 GW=$gw2"

### Definition of routes ###

# Check if tables exists, if not -> create them:
if [ -z "`cat /etc/iproute2/rt_tables | grep '^251'`" ] ; then
echo "251 rt_dev1" >> /etc/iproute2/rt_tables
if [ -z "`cat /etc/iproute2/rt_tables | grep '^252'`" ] ; then
echo "252 rt_dev2" >> /etc/iproute2/rt_tables

# Define routing tables:
ip route add default via $gw1 table rt_dev1
ip route add default via $gw2 table rt_dev2

# Create rules:
ip rule add from $ip1 table rt_dev1
ip rule add from $ip2 table rt_dev2

# If we already have a 'nexthop' route, delete it:
if [ ! -z "`ip route show table main | grep 'nexthop'`" ] ; then
ip route del default scope global

# Balance links based on routes:
ip route add default scope global nexthop via $gw1 dev $DEV1 weight 1 nexthop via $gw2 dev $DEV2 weight 1

# Flush cache table:
ip route flush cache

# All done...

To use the script, copy it to /usr/local/bin, make it executable with 'chmod +x' and call it with:


Shafiq Mustapa said...

bro, kau dah test tak script ni? aku test kat ubuntu ada error

Error: an inet address is expected rather than "table".
Error: an IP address is expected rather than "dev"

aku pun tak berapa paham sebab tak pernah main ip route apetah lagi iptables. agak2 ape maksud error tu?


zamri said...

Sorry lambat reply. Pastikan ko check dulu variable $gw1 dan $gw2 ada nilai yg dia dapat dari baris gw1=`route -n | grep $DEV1 | grep '^' | awk '{ print $2 }'`

Shafiq Mustapa said...

thanks for reply.

ip semua dah kasi dan dah dapat. ada error dekat line 38/39 dan 43/44. yang pelik bila aku copy/paste run kat terminal takde error, tapi run dalam script ada error.


zamri said...

Ini shell script. Mmg utk run dalam terminal. Kalau nak run selain dari terminal, maybe perlukan sedikit modification. Kalau run dalam terminal, adakah loadbalance berlaku?

Shafiq Mustapa said...

run dalam terminal ./ . bila run, error diatas yang keluar. cuma apabila part error dilarikan asing as single command, no error detected.

zamri said...

adakah ko run sbg root?

Shafiq Mustapa said...

run as root pun sama error run as user.

zamri said...

hmmm.. maybe ada error di mana2.

Ni hasil aku run dlm laptop aku utk baris dapatkan IP tu:

[root@asus ~]# IP1=`ifconfig wlan0 | grep "inet addr" | awk '{ print $2 }' | awk -F: '{ print $2}'`
[root@asus ~]# echo $IP1

Aku modified sikit utk ambil hanya IPv4. Cuba manually satu2 line utk cari punca error.

Vidyadhar Hullur said...

while running this script am getting error like :
RTNETLINK answers : file exists

zamri said...

That error can be ignored.

Atux Atux said...

how can we have it to run automatically on startup of the system automatically? i am running debian 7

zamri said...

You can put it in startup scripts directory like /etc/init.d/

Atux Atux said...

How do you alter the config to do NAT as well, please?

zamri said...

For NAT, i think this script should be modified to create 1 single device for both of the devices that we load balanced. I never done it though.

You'd better off using some kind of router software pre-configured like pfsense and untangle.

Atux Atux said...

I am using pfsense as my main router. I have to move to Linux, since i have a lot of apps written for debian that they have to be on the router. If you have any ideas for NAT, please let me know.