Linux Loadbalancing with two adsl modems

Posted: May 23, 2009 in Linux

My Client, a cybercafe in Tondano, North Celebes, Indonesia, using two speedy adsl modems for the Internet and other connections and they want to use both of the connection together to share the load.

After search the Internet for the example with no luck, I finally manage to made a working script based on all the example I’ve got.

I put the simple and short script (I’ve made a long one with transparent proxy and more complex iptables rule) here so anyone looking for same configuration or script won’t stumble on internet looking for the working script (like myself).

Save the script below as rc.firewall or other named according to your like, don’t forget to #chmod +x rc.firewall

I use Slackware Linux for the server/gateway so I saved it as /etc/rc.d/rc.firewall.

#!/bin/sh

# EXT1 = network interface #1 that connect to adsl modem #1
# EXT2 = network interface #2 that connect to adsl modem #2
# INT  = network interface for internal network
# IPEXT1 = ip address for network interface #1
# IPEXT2 = ip address for network interface #2
# GWEXT1 = gateway ip address for network interface #1
# GWEXT2 = gateway ip address for network interface #2

IPT=”/usr/sbin/iptables”
IP=”/sbin/ip”
EXT1=”eth0″
EXT2=”eth1″
INT=”eth2″
IPEXT1=”192.168.1.2″
IPEXT2=”192.168.0.2″
GWEXT1=”192.168.1.1″
GWEXT2=”192.168.0.1″

echo 1 >| /proc/sys/net/ipv4/ip_forward
echo 0 >| /proc/sys/net/ipv4/conf/all/rp_filter

# flush all IPT entries
$IPT -t filter -F
$IPT -t filter -X
$IPT -t nat -F
$IPT -t nat -X
$IPT -t mangle -F
$IPT -t mangle -X
$IPT -t filter -P INPUT ACCEPT
$IPT -t filter -P OUTPUT ACCEPT
$IPT -t filter -P FORWARD ACCEPT

# initialise chains that will do the work and log the packets
$IPT -t mangle -N CONNMARK1
$IPT -t mangle -A CONNMARK1 -j MARK –set-mark 1
$IPT -t mangle -A CONNMARK1 -j CONNMARK –save-mark
$IPT -t mangle -A CONNMARK1 -j LOG –log-prefix ‘IPT-mark1: ‘ –log-level info

$IPT -t mangle -N CONNMARK2
$IPT -t mangle -A CONNMARK2 -j MARK –set-mark 2
$IPT -t mangle -A CONNMARK2 -j CONNMARK –save-mark
$IPT -t mangle -A CONNMARK2 -j LOG –log-prefix ‘IPT-mark2: ‘ –log-level info

$IPT -t mangle -N RESTOREMARK
$IPT -t mangle -A RESTOREMARK -j CONNMARK –restore-mark
$IPT -t mangle -A RESTOREMARK -j LOG –log-prefix ‘restore-mark: ‘ –log-level info

$IPT -t nat -N SNAT1
$IPT -t nat -A SNAT1 -j LOG –log-prefix ‘snat-to-192.168.1.2: ‘ –log-level info
$IPT -t nat -A SNAT1 -j SNAT –to-source $IPEXT1

$IPT -t nat -N SNAT2
$IPT -t nat -A SNAT2 -j LOG –log-prefix ‘snat-to-192.168.0.2: ‘ –log-level info
$IPT -t nat -A SNAT2 -j SNAT –to-source $IPEXT2

# restore the fwmark on packets that belong to an existing connection
$IPT -t mangle -A PREROUTING -i $INT -p tcp \
-m state –state ESTABLISHED,RELATED -j RESTOREMARK

# if the mark is zero if means the packet does not belongs to an existing connection
$IPT -t mangle -A PREROUTING -p tcp -m state –state NEW \
-m statistic –mode nth –every 2 –packet 0 -j CONNMARK1
$IPT -t mangle -A PREROUTING -p tcp -m state –state NEW \
-m statistic –mode nth –every 2 –packet 1 -j CONNMARK2

$IPT -t nat -A POSTROUTING -o $EXT1 -j SNAT1
$IPT -t nat -A POSTROUTING -o $EXT2 -j SNAT2

if ! cat /etc/iproute2/rt_tables | grep -q ‘^251’
then
echo ‘251     rt_link1’ >> /etc/iproute2/rt_tables
fi
if ! cat /etc/iproute2/rt_tables | grep -q ‘^252’
then
echo ‘252     rt_link2’ >> /etc/iproute2/rt_tables
fi

$IP route flush table rt_link1 2>/dev/null
$IP route add table rt_link1 default via $GWEXT1 dev $EXT1

$IP route flush table rt_link2 2>/dev/null
$IP route add table rt_link2 default via $GWEXT2 dev $EXT2

$IP rule del from all fwmark 0x1 lookup rt_link1 2>/dev/null
$IP rule del from all fwmark 0x2 lookup rt_link2 2>/dev/null
$IP rule del from all fwmark 0x2 2>/dev/null
$IP rule del from all fwmark 0x1 2>/dev/null
$IP rule add fwmark 1 table rt_link1
$IP rule add fwmark 2 table rt_link2

$IP route flush cache

BTW … I set the MTU for both EXT1 and EXT2 card to 1454 according to this Optimal MTU for PPPOE ADSL

Have fun!

Advertisements
Comments
  1. todd says:

    How have you managed the dns? Or do you route the incoming and outgoing differently or use opendns? I guess I’d like to see your more extensive script if possible.
    looks good though. I’ll try to give it a test this week.

    • rumytaulu says:

      The rule and route has nothing to do with dns, in my case I assign DNS automatically via dhcpd server, but you can put it manually on the client without any problem.

  2. rexluther says:

    Are GWEXT1 and GWEXT2 the modems’ IP Address?
    How about the modems mode? Act as Bridge or what?
    How can we dial those two ADSL modems all together from Slackware?
    Thank you.

    • rumytaulu says:

      Yes, GWEXT1 and GWEXT2 is the modem’s IP Address and the modem is set as GATEWAY.

      I believe I read somewhere in internet how to dial two ADSL modems from Slackware, I’ll post it here if I find it again.

  3. rexluther says:

    allright! can’t wait any longer for its next explaination.. and, please provide also with example of resolv.conf if needed, because I always found and set 2 files (resolv.conf on /etc and /etc/ppp) to run my box properly as gateway, proxy cache and DNS on my cyber-cafe.

    is there any GUI to manage firewall, routing tables, and bandwidth management all together like mikrotik’s winbox? I saw Easy Firewall Generator somewhere in internet but it just can handle firewall.

    Thank you very much for your nice guide..

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s