Ich nutze seit einiger Zeit einen 2. DSL-Zugang als Backup und wollte diesen unter einen Hut mit dem schon bestehenden ursprünglichen Zugang bringen.
In meinem LAN nutze ich einen Router ähnlich dem allseits beliebten Linksys WRT54G mit Tomato-Firmware. Da diese Router bzw. auch die dafür erhältlichen Firmwares prinzipiell nur für die Nutzung eines Internet-Zugangs ausgelegt sind, habe ich mein System entsprechend angepasst, um beide Internetverbindungen gleichzeitig und parallel nutzen zu können.
Da das Vorhaben in Summe nicht ganz so trivial war, lt. Infos im Internet aber immer wieder mal Interesse so einem DualWAN-Router besteht, habe ich mich entschlossen hier ein kleines HowTo zu schreiben.
HOWTO: Zeitgleicher Betrieb 2er Internet-Verbindungen mit Tomato (Dual-WAN)
Einleitung
Was ermöglicht diese DUAL-WAN-Lösung:
- Anbinden eines 2. WAN-Uplinks (zB 2. Modem eines 2. Zugangs) an einen Tomato-Router
- Übernahme der Remote-Services (SSH, Remote-Webinterface) auf das 2. WAN-Interface (damit sind die Dienste auch über die IP des 2. Zugangs erreichbar)
- Ãœbernahme der Portforwarding-Einstellungen auf das 2. WAN-Interface
- Optional aktivierbar: Round Robin Load-Balancing
- Optional konfigurierbar: Definierbares statisches Routing für bestimmte Verbindungen (zB Verbindungen zum Firmen-VPN-Server generell immer über das 2. Modem, da dieser Zugang zB die erforderliche fixe IP hat)
- Zukünftig / in Arbeit: Failover-Mechanismus: Umlenken des Traffics auf den Ersatz-Zugang, sobald einer ausfällt
Was klappt mit dieser Modifizierung NICHT:
- QOS - habe ich im DUAL-WAN-Betrieb noch nicht aktiviert --> Lösung: Ausweichen auf TCP Vegas, od. Erweiterung der Scripts weiter unten um QOS-Unterstützung
- Volle Anzahl Switch-Ports - leider muss einer der Ethernet-Ports vom LAN-seitigen Switch entkoppelt werden, um daran das Modem des 2. Internet-Zugangs zu betreiben. Die Anzahl der LAN-Ports vermindert sich so um 1
Voraussetzungen:
- TomatoUSB (es reicht die Mini-Version)- leider fehlt der ursprünglichen Version von Tomato die MULTIPATH-Option im verwendeten Kernel, d.h. für den Dual-WAN-Betrieb muss auf TomatoUSB ausgewichen werden, welches die erforderliche Unterstützung im Kernel mit ein kompiliert hat
- Tomato-kompatibler Router - für das System sind alle Tomato-kompatiblen Router geeignet, sowie einige "exklusiv" von TomatoUSB unterstützten Modelle; Übersicht: http://tomatousb.org/doc:build-types
- 2 Modems / Router für die Internet-Zugänge, ansprechbar über verschiedene IP-Adressen in verschiedenen Subnetzen (sind entsprechend zu konfigurieren)
- Optional: Portworwarding auf den Internet-Routern aller Ports auf den jeweils mit dem Modem verbundenen WAN-Port des Tomato-Routers - falls der Router bzw. das eigene LAN von außen erreichbar sein soll; Anmerkung: Meine Speedtouch 585v7 zicken herum, wenn ich alle Port weiterleite. Ich leite deshalb jeweils die Ports 1-65000 (UDP und TCP) an den WAN-Port des Tomto-Routers weiter --> ein guter Kompromiss
Ãœbersicht Netzwerk-Aufbau
- Code: Alles auswählen
/--------------\
| |
10.0.0.138/24| ST585 v7 |IP1
---------------| |---
/------------------------\ / PF 1-65000 | DSL 1 |
| | 10.0.0.1/24 / -> 10.0.0.1 | |
| Linksys |-------------- \--------------/
| WRN2000v2 | vlan1
192.168.0.1/24| | /--------------\
---------------| Firmware | 10.1.0.1/24 | |
br0 ((W)LAN) | TomatoUSB-Mod |--------------\ 10.1.0.138/24| ST585 v7 |IP2
| www.tomatousb.org | vlan2 \---------------| |---
| | PF 1-65000 | DSL 2 |
\------------------------/ -> 10.1.0.1 | |
\--------------/
Einrichtung
1. Vorbereitung / Einrichtung 2. WAN-Port
Wie oben schon angeführt wird einer der Ethernet-Ports die ursprünglich für das LAN verwendet werden, der Port zum Verbinden des 2. Internet-Modems.
Ich hab mich bei mir für den Port unmittelbar neben dem WAN-Port entschieden (bei den LEDs am Gerät als Port 4 bezeichnet)
Um dem Switch einen Ethernet-Port wegzunehmen, sehen wir uns erst mal die aktuelle Port-Zuweisung für die LAN-Schnittstelle (Switch) an:
- Code: Alles auswählen
root@router:/tmp/home/root# nvram get vlan0ports
4 3 2 1 5*
Bei meinem Router war der vorletzte Port (1) jener unmittelbar nebem dem WAN-Interface (Achtung: Hier ist er als "1" bezeichnet, auf der Vorderseite des Gehäuses (LEDs) in umgekehrter Reihenfolge als "4")
Je nach Routermodell könnte der Port neben dem WAN-Interface auch der erste in der obigen Liste sein. Ist man sich nicht ganz sicher muss man probieren - es sollte aber meines Wissens nach entweder der 1. in der Liste oder der vorletzte Port in der Liste sein. Natürlich steht die Wahl des zu verwendeten LAN-Ports einem völlig frei - ich allerdings habe mich für den neben dem WAN-Port entschieden.
Hat man sich für einen Port entschieden (in meinem Fall die Nr. "1" lt. obiger Liste), so muss dieser nun aus dem LAN-Switch ausgehängt werden.
- Code: Alles auswählen
nvram set vlan0ports="4 3 2 5*"
Danach wird gleich noch ein neues Netzwerk-Interface angelegt + der soeben freigemacht Port dem neuen Device zugewiesen --> das ist später das 2. WAN-Device.
- Code: Alles auswählen
nvram set vlan2ports="1 5"
nvram set vlan2hwname=et0
nvram set wan2_ifname=vlan2
Im Anschluss daran setzen wir gleich noch die IP-Konfiguration für das neue WAN-Interface, die in weitere Folge dann von den Init-Scripts weiter unten ausgelesen wird.
- Code: Alles auswählen
nvram set wan2_ipaddr="10.1.0.1"
nvram set wan2_netmask="255.255.255.0"
nvram set wan2_gateway="10.1.0.138"
nvram set wan2_dns="10.1.0.138"
Zum Abschluss noch ein
- Code: Alles auswählen
nvram commit
Damit wäre die Konfiguration auf der Shell abgeschlossen. Nach einem Reboot wird diese übernommen und ifconfig -a sollte bereits ein zusätzliches Netzwerk-Interface "vlan2" anzeigen (das zu diesem Zeitpunkt allerdings noch nicht konfiguriert und aktiv ist)
2. Aktivierung DUAL-WAN-Betrieb
Nun zur eigentlichen Sache, der Inbetriebnahme der Dual-WAN-Fähigkeiten des Routers.
Dies geschieht ganz einfach über das Webinterface des Routers, im Bereich Administration / Scripts
Im Tab Firewall den folgenden Inhalt ablegen, mittels Copy/Paste (anderen Inhalt vorher löschen, falls vorhanden):
- Code: Alles auswählen
#!/bin/sh
######################
#
# Script DUAL-WAN
# CORE
#
# for TomatoUSB 1.28
#
# Date: 2010-09-04
#
######################
####
##
## USER-CONFIG
##
####
### Enables (1) oder disables (0) kernel based
### load balancing between the 2 WAN connections
ENABLE_KERNEL_WAN_LOAD_BALANCING=1
####
##
## CONSTANTS
##
####
### Internal config
FOLDER_DUALWAN=/tmp/dualwan
FILE_DUALWAN_CONFIGURED=$FOLDER_DUALWAN/configured
SCRIPT_EXTENSION_NVRAM=script_shut
SCRIPT_EXTENSION_FS=$FOLDER_DUALWAN/dualwan_extension.sh
CONFIG_FILES_KERNEL_REVERSEPATH_FILTERING=/proc/sys/net/ipv4/conf/*/rp_filter
TABLE_WAN1=100
TABLE_WAN2=200
MARK_WAN1=0x100
MARK_WAN2=0x200
### NVRAM stored config
WAN_IFNAME=`nvram get wan_ifname`
WAN_IPADDR=`nvram get wan_ipaddr`
WAN_GATEWAY=`nvram get wan_gateway`
WAN_DNS=`nvram get wan_dns`
WAN2_IFNAME=`nvram get wan2_ifname`
WAN2_IPADDR=`nvram get wan2_ipaddr`
WAN2_NETMASK=`nvram get wan2_netmask`
WAN2_GATEWAY=`nvram get wan2_gateway`
WAN2_DNS=`nvram get wan2_dns`
LAN_IPADDR=`nvram get lan_ipaddr`
PORT_FORWARDING_CONFIGURATION=`nvram get portforward`
PING_FROM_WAN_BLOCKED=`nvram get block_wan`
HTTPD_REMOTE_ENABELD=`nvram get remote_management`
HTTPD_REMOTE_HTTPS_ENABLED=`nvram get remote_mgt_https`
HTTPD_WANPORT=`nvram get http_wanport`
HTTPD_LANPORT=`nvram get http_lanport`
HTTPD_LANPORT_HTTPS=`nvram get https_lanport`
SSHD_REMOTE_ENABLED=`nvram get sshd_remote`
SSHD_REMOTE_PORT=`nvram get sshd_rport`
SSHD_PORT=`nvram get sshd_port`
###
##
## Function library
##
###
configureWan2Device() {
### skip if already configured
if test -e $FILE_DUALWAN_CONFIGURED;
then
return
fi
logger "Setting up second WAN-device: interface $WAN2_IFNAME, ip $WAN2_IPADDR, netmask $WAN2_NETMASK"
ifconfig $WAN2_IFNAME $WAN2_IPADDR netmask $WAN2_NETMASK up
mkdir -p `dirname $FILE_DUALWAN_CONFIGURED`
touch $FILE_DUALWAN_CONFIGURED
}
expandRoutingTablesAndRules() {
### rules
ip rule flush
ip rule add lookup main prio 32766
ip rule add lookup default prio 32767
ip rule add from $WAN_IPADDR table $TABLE_WAN1 prio 100
ip rule add fwmark $MARK_WAN1 table $TABLE_WAN1 prio 101
ip rule add from $WAN2_IPADDR table $TABLE_WAN2 prio 200
ip rule add fwmark $MARK_WAN2 table $TABLE_WAN2 prio 201
### routing tables
ip route flush table $TABLE_WAN1 >/dev/null 2>&1
ip route flush table $TABLE_WAN2 >/dev/null 2>&1
for TABLE in $TABLE_WAN1 $TABLE_WAN2
do
ip route | grep link | while read ROUTE
do
ip route add table $TABLE to $ROUTE
done
done
ip route add table $TABLE_WAN1 default via $WAN_GATEWAY
ip route add table $TABLE_WAN2 default via $WAN2_GATEWAY
}
expandIptables() {
### filter table
checkIptablesFilterTableExpanded
if [ $? -ne 0 ];
then
expandIptablesFilterTable
fi
### nat table
expandIptablesNatTable
}
checkIptablesFilterTableExpanded() {
iptables --list -v |grep -q $WAN2_IFNAME
}
expandIptablesFilterTable() {
iptables -I INPUT 2 -i br0 -d $WAN2_IPADDR -j DROP
positionWanRules=`iptables --list FORWARD -v --line-numbers | grep -m 1 $WAN_IFNAME | sed -n "s/\([0-9]\+\).*/\1/p"`
iptables -I FORWARD `expr $positionWanRules + 2` -i $WAN2_IFNAME -j wanin
iptables -I FORWARD `expr $positionWanRules + 3` -o $WAN2_IFNAME -j wanout
}
expandIptablesNatTable() {
lanNet=`iptables --list PREROUTING -v -t nat --line-numbers |sed -n "s/^1.* \(\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}\/[0-9]\{2\}\)/\1/p"`
iptables -t nat -I PREROUTING 2 -i $WAN2_IFNAME -d $lanNet -j DROP
iptables -t nat -A POSTROUTING -o $WAN2_IFNAME -j MASQUERADE
}
enableDualWanRouting() {
enableDualWanRoutingSetUpIptablesEntries
enableDualWanRoutingConfigureKernelRpFilter
}
enableDualWanRoutingSetUpIptablesEntries() {
### Set connmark for new incoming (--> not already marked) connections according to their iface
iptables -t mangle -A PREROUTING -i $WAN_IFNAME -m connmark --mark 0 -j CONNMARK --set-mark $MARK_WAN1
iptables -t mangle -A PREROUTING -i $WAN2_IFNAME -m connmark --mark 0 -j CONNMARK --set-mark $MARK_WAN2
### Set packet mark from connmark for already marked (--> established and new incoming-> see rules obove) connections
iptables -t mangle -A PREROUTING -m connmark ! --mark 0 -j CONNMARK --restore-mark
iptables -t mangle -A OUTPUT -m connmark ! --mark 0 -j CONNMARK --restore-mark
### Set connmark if unmarked packages (--> packages of new connections) passing an WAN interface,
### according to the kernel made routing decision
iptables -t mangle -A POSTROUTING -o $WAN_IFNAME -m connmark --mark 0 -j CONNMARK --set-mark $MARK_WAN1
iptables -t mangle -A POSTROUTING -o $WAN2_IFNAME -m connmark --mark 0 -j CONNMARK --set-mark $MARK_WAN2
}
enableDualWanRoutingConfigureKernelRpFilter() {
### Disable reverse path filtering for all devices
for rpFilterConfigFile in `ls $CONFIG_FILES_KERNEL_REVERSEPATH_FILTERING`;
do
echo 0 > $rpFilterConfigFile
done
}
setUpRemoteServices() {
### Remote-Ping
if [ $PING_FROM_WAN_BLOCKED -eq 0 ];
then
iptables -t nat -A PREROUTING -p icmp -d $WAN2_IPADDR -j DNAT --to $LAN_IPADDR
fi
### Remote-Web-Access
if [ $HTTPD_REMOTE_ENABELD -ne 0 ];
then
if [ $HTTPD_REMOTE_HTTPS_ENABLED -ne 0 ];
then
localWanHttpdPort=$HTTPD_LANPORT_HTTPS;
else
localWanHttpdPort=$HTTPD_LANPORT;
fi
iptables -t nat -A PREROUTING -p tcp --dport $HTTPD_WANPORT -d $WAN2_IPADDR -j DNAT --to $LAN_IPADDR:$localWanHttpdPort
fi
### Remote-SSH
if [ $SSHD_REMOTE_ENABLED -ne 0 ];
then
iptables -t nat -A PREROUTING -p tcp --dport $SSHD_REMOTE_PORT -d $WAN2_IPADDR -j DNAT --to $LAN_IPADDR:$SSHD_PORT
fi
}
enablePortForwardingWan2() {
oldIFS="$IFS"
IFS=">"
### traverse each defined rule
for portForwardingEntry in $PORT_FORWARDING_CONFIGURATION;
do
# parse current rule
ruleEnabled=`echo $portForwardingEntry |cut -d "<" -f 1`
protocol=`echo $portForwardingEntry |cut -d "<" -f 2`
sourceAddress=`echo $portForwardingEntry |cut -d "<" -f 3`
sourcePort=`echo $portForwardingEntry |cut -d "<" -f 4`
destinationPort=`echo $portForwardingEntry |cut -d "<" -f 5`
destinationAddress=`echo $portForwardingEntry |cut -d "<" -f 6`
ruleName=`echo $portForwardingEntry |cut -d "<" -f 7`
# skip disabled rules
if [ "$ruleEnabled" -ne 1 ];
then
continue
fi
# deny forwarding of multiple ports --> not yet implemented
if echo $sourcePort |grep -q -e "[:,]";
then
logger "Forwarding of multiple ports not yet implemented! NOT setting up forwarding rule $ruleName for 2nd WAN-device"
continue
fi
### rewrite variables
# source address
if [ -z "$sourceAddress" ];
then
sourceAddress="0.0.0.0"
fi
# destination address
if [ -z "$destinationPort" ];
then
destinationPort=$sourcePort
fi
### set up iptables rules
# tcp
if [ $protocol -eq 1 -o $protocol -eq 3 ];
then
iptables -t nat -A PREROUTING -p tcp --dport $sourcePort -d $WAN2_IPADDR -j DNAT --to $destinationAddress:$destinationPort
fi
# udp
if [ $protocol -eq 2 -o $protocol -eq 3 ];
then
iptables -t nat -A PREROUTING -p udp --dport $sourcePort -d $WAN2_IPADDR -j DNAT --to $destinationAddress:$destinationPort
fi
done
IFS=$oldIFS
}
setUpKernelConnectionLoadBalancing() {
if [ $ENABLE_KERNEL_WAN_LOAD_BALANCING -ne 0 ];
then
ip route change default scope global equalize nexthop via $WAN_GATEWAY dev $WAN_IFNAME nexthop via $WAN2_GATEWAY dev $WAN2_IFNAME
else
ip route change default via $WAN_GATEWAY dev $WAN_IFNAME
fi
}
finalizeConfiguration() {
### Flush routing cache
ip route flush cache
}
###
##
## Execution
##
###
### Core config
configureWan2Device
expandRoutingTablesAndRules
expandIptables
enableDualWanRouting
setUpRemoteServices
enablePortForwardingWan2
setUpKernelConnectionLoadBalancing
finalizeConfiguration
### Extended external config
nvram get $SCRIPT_EXTENSION_NVRAM > $SCRIPT_EXTENSION_FS
chmod u+x $SCRIPT_EXTENSION_FS
$SCRIPT_EXTENSION_FS
Im Tab Shutdown den folgenden Inhalt ablegen, mittels Copy/Paste (anderen Inhalt vorher löschen, falls vorhanden):
Anmerkung: Das Script wird nicht tatsächlich beim Shutdown ausgeführt - die Ablage hier ist lediglich ein Workaround, da im Bereich Firewall die Scriptgröße auf insgesamt 8 KByte beschränkt ist; Das Script hier wird implizit vom Firewall-Script aufgerufen mit zur richtigen Zeit mit ausgeführt
- Code: Alles auswählen
#!/bin/sh
######################
#
# Script DUAL-WAN
# EXTENDED CONFIG
#
# for TomatoUSB 1.28
#
# Date: 2010-09-04
#
######################
### This script is not intended to be executed from Tomato
if echo $0 |grep -q script;
then
exit 0
fi
####
##
## USER-CONFIG
##
####
### List of destinations to be routed via a specific interface,
### delimited by ","
###
### Destination: IP, Port or IP:Port
### Example: 1.2.3.4,4.4.4.4:80,22
DESTINATIONS_WAN1=
DESTINATIONS_WAN2=1.2.3.4,8080,195.3.96.67:53
####
##
## CONSTANTS
##
####
MARK_WAN1=0x100
MARK_WAN2=0x200
###
##
## Function library
##
###
setUpStaticRouting() {
if [ -z $1 -o -z $2 ];
then
return
fi
destinations=$1
connectionMark=$2
oldIFS=$IFS
IFS=","
for destination in $destinations;
do
if echo $destination |grep -q ":";
then
destinationIp=`echo $destination |cut -d ":" -f 1`
destinationPort=`echo $destination |cut -d ":" -f 2`
iptables -t mangle -I PREROUTING -p tcp -d $destinationIp --dport $destinationPort -m connmark --mark 0 -j CONNMARK --set-mark $connectionMark
iptables -t mangle -I PREROUTING -p udp -d $destinationIp --dport $destinationPort -m connmark --mark 0 -j CONNMARK --set-mark $connectionMark
else
if echo $destination |grep -q "\.";
then
iptables -t mangle -I PREROUTING -d $destination -m connmark --mark 0 -j CONNMARK --set-mark $connectionMark
else
iptables -t mangle -I PREROUTING -p tcp --dport $destination -m connmark --mark 0 -j CONNMARK --set-mark $connectionMark
iptables -t mangle -I PREROUTING -p udp --dport $destination -m connmark --mark 0 -j CONNMARK --set-mark $connectionMark
fi
fi
done
IFS=$oldIFS
}
###
##
## Execution
##
###
setUpStaticRouting $DESTINATIONS_WAN1 $MARK_WAN1
setUpStaticRouting $DESTINATIONS_WAN2 $MARK_WAN2
3. Anpassung der Konfiguration
Die so hochgeladene Konfiguration kann nun noch den eigenen Wünschen entsprechend angepasst werden.
Das umfasst folgende Möglichkeiten:
- Aktivierung/Deaktivierung Round Robin Load Balancing
- Festlegen statischer Routen (Ziele zu denen immer über das selbe Modem verbunden wird)
Die Konfiguration ist jeweils zu Beginn der beiden Scripte anpassbar.
Round Robin Load Balancing
CORE-Script (Firewall-Tab)
- Code: Alles auswählen
####
##
## USER-CONFIG
##
####
### Enables (1) oder disables (0) kernel based
### load balancing between the 2 WAN connections
ENABLE_KERNEL_WAN_LOAD_BALANCING=0
Static Routing
EXTENED CONFIG - Script (Shutdown-Tab)
- Code: Alles auswählen
####
##
## USER-CONFIG
##
####
### List of destinations to be routed via a specific interface,
### delimited by ","
###
### Destination: IP, Port or IP:Port
### Example: 1.2.3.4,4.4.4.4:80,22
DESTINATIONS_WAN1=
DESTINATIONS_WAN2=1.2.3.4,8080,195.3.96.67:53
(Das Beispiel hier routet bestimmte Verbindungen immer über den 2. Internet-Zugang - die Konfiguration für den 1. bleibt jedoch leer --> also keine Verbindungen statisch über diese Leitung routen --> kann natürlich jederzeit geändert werden)
4. Abschluss
Nach einem Speichern der so im Webinterface angelegten Scripts und einem Reboot ist die Konfiguration aktiv. Fertig!
Anmerkungen
Für Wünsche, Anregungen und sonstige Vorschläge bin ich natürlich jederzeit offen - auch Ergänzungen und Anpassungen der Skripte werden gerne angenommen
![OK :ok:](./images/smilies/thumb.gif)