Dual WAN Load Balancing

Network

In diesem Artikel beschreibe ich Dual WAN Load Balancing im – aber nicht ausschließlich – Round Robin-/(Rundlauf-)Verfahren und optionalen Failover.
Getestet habe ich das Vorgehen unter Debian Wheezy und Ubuntu Server LTS, jedoch lässt es sich bis auf wenige Kleinigkeiten, zum Beispiel die Netzwerkkonfiguration, auf andere Linux-Derivate mit „iproute2“ sinngemäß übertragen.

Die fiktive Umgebung

Zur besseren Übersicht wähle ich folgende Konfiguration:

eth0, SDSL1, Netzwerk 65.10.10.0/24, Adresse 65.10.10.1, Gateway 65.10.10.254, Tabelle „uplink1
eth1, SDSL2, Netzwerk 65.20.20.0/24, Adresse 65.20.20.1, Gateway 65.20.20.254, Tabelle „uplink2
eth2, Internal Link, Netzwerk 192.168.100.0/24, Adresse 192.168.100.1

IPv4-Forwarding setze ich als konfiguriert voraus.

Konfiguration

Zu Beginn definiere ich alternative DNS-Server. Das kann notwendig sein, da ISP1 womöglich nicht auf den DNS-Server des ISP2 zugreifen darf.
Da ich mit der Leistung der Google DNS-Server sehr zufrieden bin, wähle ich diese:

sudo nano /etc/resolv.conf

Und der Inhalt:

nameserver 8.8.8.8
nameserver 8.8.4.4

Sollte ich auf die DNS-Server der ISP bestehen, würde eine Route für die jeweiligen IPs notwendig, damit der Zugriff stets via Gateway des jeweiligen ISP erfolgt.

Eine weitere Möglichkeit wäre ein DNS-Server im internen Netzwerk, etwa via Windows Domain Controller. Hierzu könnte die IP ohne zusätzliche Route als Nameserver definiert werden, da der Zugriff sowieso via eth2 erfolgen würde.
Aber Vorsicht, ist der hier besprochene Router auch für besagten Domain Controller zuständig, stöße dieser schlussendlich auf das selbe Problem, wenn er zum Forwarden die IPs des ISP eingetragen hätte.

Mit einem Editor erstelle ich zwei neue Tabellen für das Routing, die Beschreibung ist individuell wählbar, darf jedoch – selbstverständlich – noch nicht vorhanden sein:

sudo nano /etc/iproute2/rt_tables

Am Ende folgendes einfügen:

201 uplink1
202 uplink2

Die Netzwerkkonfiguration gewohnt via „/etc/network/interfaces“ vornehmen.

sudo nano /etc/network/interfaces

Hier die gesamte Konfiguration inklusive Loopback:

auto lo eth0 eth1 eth2

iface lo inet loopback

iface eth0 inet static
	address 65.10.10.1
	netmask 255.255.255.0
	post-up ip route add 65.10.10.0/24 dev eth0 src 65.10.10.1 table uplink1
	post-up ip rule add from 65.10.10.1 table uplink1
	post-down ip rule del from 65.10.10.1 table uplink1
	
iface eth1 inet static
	address 65.20.20.1
	netmask 255.255.255.0
	post-up ip route add 65.20.20.0/24 dev eth1 src 65.20.20.1 table uplink2
	post-up ip rule add from 65.20.20.1 table uplink2
	post-down ip rule del from 65.20.20.1 table uplink2
	
iface eth2 inet static
	address 192.168.100.1
	netmask 255.255.255.0
	broadcast 192.168.100.255
	network 192.168.100.0
	post-up ip route add default scope global nexthop via 65.10.10.254 dev eth0 weight 1 nexthop via 65.20.20.254 dev eth1 weight 1

Zu sehen ist, dass die Einrichtung von Adresse und Netzwerk gewöhnlich erfolgt. „Post-up“ führt Aktionen aus, nachdem das übergeordnete Interface gestartet wurde. Dies können beinahe beliebige Befehle sein.
Die Reihenfolge der Abarbeitung erfolgt gemäß „auto 1. 2. 3. 4.“ in erster Zeile.

In letzter Zeile des Beispiels, erfolgt das eigentliche Load-Balancing, indem ein Bereich für die Standardroute mit beiden Gateways definiert wird:

ip route add default scope global nexthop via 65.10.10.254 dev eth0 weight 1 nexthop via 65.20.20.254 dev eth1 weight 1

Der „nexthop“ für alle Pakete nach außen, kann nun entweder via SDSL1 oder SDSL2 erfolgen. Durch die Gewichtung „weight 1“ sind beide Wege von gleicher Priorität.
Hinweis: Dieser Befehl kann auch an anderer Stelle ausgeführt werden, die Wahl traf ich eher willkürlich. Natürlich müssen die Links eth0 und eth1 bereits verfügbar sein.

Optional: Gewichtung der Ports

Genauso einfach wie es mutmaßen lässt, ist die Konfiguration zur Bevorzugung eines Weges, einen Haken gibt es dennoch zu beachten.
Letzte Zeile des Beispiels aus „/etc/network/interfaces“, ersetze ich folgendermaßen:

[...]
	post-up ip route add default scope global nexthop via 65.10.10.254 dev eth0 weight 10 nexthop via 65.20.20.254 dev eth1 weight 90
[...]

Im Gegensatz zu simplen numerischen Prioritäten, setzt „weight“ ein Verhältnis. Obiges Beispiel ergäbe demnach 10:90, also 10 Anteile eth0, 90 Anteile eth1.
Eine Aufteilung der Last zu 20% auf eth0 und 80% auf eth1 wäre 20:80, also „weight 20“ für eth0 und „weight 80“ für eth1.

Optional: Testen

Um zuverlässig zu testen, ob das Routing auch die definierte Gewichtung beachtet, reicht eine einfache FOR-Schleife via Bash:

for x in $(seq 1 20)
do
ip r g 1.2.3.$x
done

Hierbei werden die Routen zur jeweiligen IP in der Abfolge 1.2.3.1 bis 1.2.3.20 untereinander angezeigt, für Round Robin etwa:

[...]
1.1.2.4 via 65.10.10.254 dev eth0 src 65.10.10.1
1.1.2.5 via 65.20.20.254 dev eth0 src 65.20.20.1
1.1.2.6 via 65.10.10.254 dev eth0 src 65.10.10.1
1.1.2.7 via 65.20.20.254 dev eth0 src 65.20.20.1
[...]

Optional: Failover

Auf dem Weg durchs Internet stieß ich auf ein nützliches Script (http://fatalsite.net/?p=90, edit: Leider nicht mehr erreichbar.), das ununterbrochen in definiertem Zeitabstand (Standard: 10s) einen Ping via „uplink1“ und „uplink2“ auf eine IP/einen Hostnamen ausführt, dabei eine Auswertung durchführt und je nach Konfiguration des Scripts eine „Route abschaltet“.
Das Script ist gut dokumentiert, daher belasse ich es bei dem Hinweis, helfe aber gerne bei der Einrichtung/Fragen.

Optional: Statische Routen

Eine sich dauernd ändernde IP, könnte diverse (Web-)Dienste irritieren. Abhilfe verschafft eine statische Route, die besagt für Dienst X immer über „uplink1“ (Beispiel) oder „uplink2“ zu gehen:

ip route add Web.Dienst.X.IP via 65.10.10.254

Achtung: Bitte beachten, dass falls Failover via obigem Script ausgeführt wird, dieses zu bearbeiten ist, damit die Routen im Zweifelsfall nicht über den toten Link ins Nirvana geschickt werden. :-)

11 Antworten auf “Dual WAN Load Balancing

  1. Jens

    Hallo,

    ich habe es gestern mal testweise versucht zum laufen zu bekommen.
    Leider mit mäßigem Erfolg.
    Bei mir sieht es so aus, dass ich einen DSL Anschluss über eine Fritz Box habe (eth0) und den anderen über WLAN (wlan0).
    Gleichzeitig möchte ich eth0 für mein Lokales Netz nutzen (wegen dem WLAN AP der Fritz Box).

    Der Server geht scheinbar über beide Gateways ins Internet jedoch nicht die anderen Computer, welchen den Server als Gateway eingetragen haben es scheint so, als ob iptables nicht so recht damit klar kommt, trotz NAT.

    Jens

  2. john

    in my case the eth0 and eth1 are private IP addresses.
    WAN1-eth0: 192.168.1.79/24 with gateway 192.168.1.1
    WAN2-eth1: 192.168.2.79/24 with gateway 192.168.2.1
    LAN – eth2: 10.10.10.1/24

    how can i add NAT functionality to the above config so i can have a fully functional router? PLEASE?

  3. john

    hi. how this will be altered if i have
    eth0:adsl 192.168.0.2/24 gateway 192.168.0.1
    eth1:LAN:192.168.1.1/24
    usb0:wifi SSID:home_router, WPA2, IP:192.168.2.49/24 gw:192.168.2.1
    3G usb modem

    try to aggregate all of them. if some LINK is missing then access the internet from the available WANs.
    some help please

  4. Torsten

    Hi Andre, ich habe hier zu Hause noch nen APU1C4 rumfliegen der wäre bestimmt ganz gut dafür.
    Hast du vielleicht noch bei dir irgendwo das Failover Script rumfliegen? Fatalsite.net ist ja leider nicht mehr erreichbar.

    Danke

  5. Fabian

    Hallo Andre,

    danke für die klasse Anleitung, hat bei mir auf Anhieb funktioniert! *top*

    Nur eine Frage noch: wird auf Quell- oder Zieladresse unterschieden welche Route genommen wird? Ich hatte bei einem kurzen Test den Eindruck das es die Quelladresse ist (was natürlich besser wäre :) ).

    Viele Grüße,

    Fabian

    1. André P. Autor

      Hi Fabian,

      danke für deine Rückmeldung, freut mich zu hören, dass der Beitrag noch besucht wird.

      Wenn du keine Regel angelegt hast, wird nach außen die Gewichtung entscheiden. Eingehend entscheidet die Quelle, welchen Weg sie wählt. Das lässt sich natürlich alles durch Regeln und Routen verändern.

      Schau am besten auch mal den Output von netstat -cn an, dort können die gewählten Wege ganz gut nachvollzogen werden, wie ich finde.

      Viele Grüße
      André

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.