Linux Loadbalancing with two adsl modems

2009 May 23
by rumytaulu

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 0×1 lookup rt_link1 2>/dev/null
$IP rule del from all fwmark 0×2 lookup rt_link2 2>/dev/null
$IP rule del from all fwmark 0×2 2>/dev/null
$IP rule del from all fwmark 0×1 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!

5 Responses leave one →
  1. 2009 May 26

    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.

    • 2009 May 27
      rumytaulu permalink

      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. 2009 June 18

    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.

    • 2009 June 18
      rumytaulu permalink

      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. 2009 June 21

    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

Note: You can use basic XHTML in your comments. Your email address will never be published.

Subscribe to this comment feed via RSS