Linux – Set up router with 2 WANs and multiple subnets

debianiproute2linuxrouterrouting

I'm trying to set up a Debian box as a router for an office. I need to have 3 subnets in the LAN and 2 WAN connections, and I want one of the subnets to ALWAYS use WAN 1 and the other subnet to ALWAYS use WAN 2 (no load balancing).

For exmaple, I want to have these three subnets:
– 10.1.1.0/24
– 10.1.2.0/24
– 10.1.3.0/24

I want 10.1.1.0/24 to go out to the Internet using ISP #1 and 10.1.2.0/24 and 10.1.3.0/24 to use ISP #2.

And one second level of complication: ISP #2 is a DSL connection with a dynamic IP address.

I think this should be easy to implement, but I've never done it before and I haven't been able to find an example online. I've been reading lartc but I couldn't adapt the examples they provide to what I want to do.

I'll appreciate any lead!

Best Answer

You can do this with ip rule and friends (keyword: source based routing). First you need to build another routing table. Lets call it wan2. add it to /etc/iproute2/rt_tables

Fortunately the output of ip route is in the same format as the input. You can do this to copy the table (without default route)

ip route show table main | grep -Ev "^default" | while read ROUTE; do
  ip route add table wan2 $ROUTE
done

Then add the default route

ip route add table wan2 default via 1.2.3.4 dev ethX

When finished you can use the ip rule command to build rules to select the corresponding routing table:

ip rule add from 10.1.2.0/24 table wan2

I found this script somewhere in the internet, but forgot where. You can use it as template

#!/bin/sh
set -e

MARK=100
TABLE_NAME=wan2
DEV=eth2
GATEWAY=192.168.4.1

IPTABLES=/sbin/iptables
IP=/sbin/ip

$IP route flush table $TABLE_NAME

$IP route show table main | grep -Ev "^default" | while read ROUTE; do
    $IP route add table $TABLE_NAME $ROUTE
done

$IP route add table $TABLE_NAME default dev $DEV via $GATEWAY

while true; do
    ip rule del table $TABLE_NAME 2>/dev/null || break
done

$IP rule add from 10.1.2.0/24 table $TABLE_NAME
....
$IP route flush cache