Tuesday, March 23, 2010

PFSense 1.2.3 BSD and traffic splitting between 2 ISPs

I was once working on a this project in the attempt to migrate from IPCOP... but instead I went for DD-WRT on Linksys, and this project died a quite dead... This was done to split traffic between "Local" and "International" in South Africa, due to that "Local" internet traffic that's much cheaper. Anyways, here is the code:

Install stock PFSense 1.2.3
pkg_add -v -r mpd5 wget
The "get local route" script:
#!/bin/sh

WORKDIR="/tmp"
DATE=`date`

cd $WORKDIR

#Retrieve the local routes file
/usr/local/bin/wget "http://developers.locality.co.za/routes.txt" -O $WORKDIR/routes.raw
cat $WORKDIR/routes.raw | grep "/" | /usr/bin/awk '{print "route add -net "$1" -interface ng0"}' > $WORKDIR/routes.dat

# Make sure downloaded routes file exists
# If file does not exist Restore the backup
if [ ! -s $WORKDIR/routes.dat ]; then
   /usr/bin/logger -t ROUTESET "Local routes download failed. Using backup if routes.dat.bak exists..."
   cp -f $WORKDIR/routes.dat.bak $WORKDIR/routes.dat
else
  /usr/bin/logger -t ROUTESET "Local routes - routes.dat successfully created."

  #Backup new downloaded routes.dat file
  cp $WORKDIR/routes.dat $WORKDIR/routes.dat.bak

  #Add the new local routes
  chmod 777 $WORKDIR/routes.dat
  route flush
  $WORKDIR/routes.dat
  /usr/bin/logger -t ROUTESET "Local routes sucessfully added."

  #Clean up
  rm -f $WORKDIR/routes.raw $WORKDIR/routes.txt $WORKDIR/routes.dat
fi
Then to make PFSense dial 2 PPP connections, I had to do the following:

vi /usr/local/etc/mpd5/mpd.conf
startup:

default:
        load local
        load international

local:
        create bundle static Local
        set iface route default
        set iface up-script /usr/local/sbin/ppp-linkup
        set ipcp ranges 0.0.0.0/0 0.0.0.0/0
        create link static Local pppoe
        set link action bundle Local
        set auth authname your_local_account_username
        set auth password your_local_account_password
        set link max-redial 0
        set link mtu 1462
        set link mru 1462
        set link keep-alive 10 60
        set pppoe iface fxp0
        set pppoe service "Local"
        open

international:
        create bundle static International
        set iface route default
        set iface up-script /usr/local/sbin/ppp-linkup
        set ipcp ranges 0.0.0.0/0 0.0.0.0/0
        create link static International pppoe
        set link action bundle International
        set auth authname your_international_account_username
        set auth password your_international_account_password
        set link max-redial 0
        set link mtu 1462
        set link mru 1462
        set link keep-alive 10 60
        set pppoe iface fxp0
        set pppoe service "International"
        open
Then you can connect by doing /usr/local/sbin/mpd5. This will create two PPP interfaces called ng0 for local and ng1 for international.

The problem still exists that I do not know how to do the routing between these two PPP interfaces to make this work. I do get only local access this way. PFSense uses the Packet Filter Firewall... and here is where I've lost track and went for DD-WRT that uses iptables...