neunzehn83.de

Ein Mann, ein Blog, kein Plan.

Policy based routing auf Debian Lenny/Etch mit Squid Proxyserver

Folgendes Szenario: Ein Debian Lenny Server und zwei Router mit je einer Internetverbindung befinden sich im selben (lokalen) Netzwerk. Wir wollen beide Router (sprich Internetverbindungen) für verschiedene Anwendungen nutzen.

Routing-Tabelle

Routing im privaten Netzwerk ist eigentlich ganz einfach: Liegt die Ziel-IP nicht im selben Subnetz, wird das Paket an den Default-Gateway geschickt. Das nennt sich dann static routing. Verwaltet wird das über sog. Routing-Tabellen. Unter Debian sieht das ungefähr so aus:
~$ sudo route
Kernel-IP-Routentabelle
Ziel            Router          Genmask         Flags Metric Ref    Use Iface
192.168.123.0   *                255.255.255.0   U     0      0        0 eth0
default         192.168.123.99   0.0.0.0         UG    0      0        0 eth0

192.168.123.0 ist das eigene, private Netz, 192.168.123.99 der Router an dem eine DSL oder Kabel-Verbindung hängt. Das sieht bei jedem Client-PC übrigens ähnlich aus. Windows-Benutzer müssen aber "route print" ins cmd tippen.

Policy Based Routing

So weit, so einfach. Was ist aber, wenn wir bestimmte Dienste über einen anderen Gateway leiten wollen? Dann brauchen wir policy based routing. Damit lassen sich unheimlich tolle Sachen machen - wir beschränken uns aber erstmal auf das unterschiedliche Routen anhand der Source-IP-Adresse.

Konkret: Der Lenny-Server bekommt eine zweite (virtuelle) IP, den Squid-Proxyserver binden wir exklusiv auf diese IP, und per PBR schicken wir alle Pakete die vom Squid-Proxy kommen über einen bestimmten Gateway. Der Rest geht nach wie vor zum Default-Gateway.

Mit PBR könnte man natürlich auch nach dem Desination-Port routen, und sich somit die zweite IP-Adresse sparen. Leider bietet  "ip rule" keine Möglichkeit direkt den TCP destination port als Kriterium auszuwählen. Deshalb müssten die entsprechenden Pakete erst mit iptables markiert, und dann nach dieser Markierung gefiltert werden. Was diesen Post betrifft, blieben wir also bei zwei IPs und somit dem routing anhand der Source-IP.

Ein paar Zahlen zum Verständnis:

- Lenny-Server: 192.168.123.1 & 192.168.123.2 - Router1: 192.168.123.99 - Router2: 192.168.123.98

Die Software

Als Software brauchen wir iproute2 und iptables. Beide Tools sollten selbst bei einer minimalen Debian Installation schon vorhanden sein. Wenn nicht, installieren wir die Tools nach: apt-get install iproute iptables.

Die Konfiguration

Routing-Tabelle anlegen

Zunächst legen wir zwei neue Routing-Tabellen an. Eine für jede ausgehende Leitung. Dazu fügen wir folgenden Zeilen an das Ende von /etc/iproute2/rt_tables hinzu.
#
# reserved values
#
255     local
254     main
253     default
0       unspec
#
# local
#
#1      inr.ruhep
100 arcor
200 kabelbw

Der Name ist jeweils frei wählbar. Ich habe hier die Namen der jeweiligen Provider genommen. Die ID ist auch frei wählbar, muss aber zwischen 1 und 254 liegen.

Routing-Konfiguration

Wir bearbeiten /etc/network/interfaces, fügen ein zweite, virtuelle IP-Adresse hinzu, und teilen Debian mit, mit welchem Adapter welche Routing-Tabellen genutzt werden sollen.
# The loopback network interface
auto lo
iface lo inet loopback
# The primary network interface
#allow-hotplug eth0
auto eth0
iface eth0 inet static
        address 192.168.123.1
        netmask 255.255.255.0
        network 192.168.123.0
        broadcast 192.168.123.255
        post-up ip route add default via 192.168.123.99 dev eth0 table main
        pre-down ip route del default via 192.168.123.99 dev eth0 table main
auto eth0:1
iface eth0:1 inet static
        address 192.168.123.2
        netmask 255.255.255.0
        network 192.168.123.0
        broadcast 192.168.123.255
        post-up ip route add default via 192.168.123.98 dev eth0:1 table arcor
        post-up ip rule add from 192.168.123.2 table arcor
        pre-down ip route del default via 192.168.123.98 dev eth0:1 table arcor
        pre-down ip rule del from 192.168.123.2 table arcor

Die post-up & pre-down Einträge legen automatisch die entsprechenden Regeln in der Routing-Tabelle an, wenn die Netzwerkkarte aktiviert bzw. deaktiviert wird. Von Hand angelegte Einträge verschwinden sonst nämlich nach einem Neustart. Der Traffic über eth0 (192.168.123.1) geht demnach an den Router mit der .99. Traffic über das virtuelle Interface eth0:1 (192.168.123.2) geht an den Router mit der .98.

Squid-Konfiguration

Da nun sämtlicher Traffic der IP 192.168.123.2 über einen speziellen Gateway geht, müssen wir nur noch den Squid-Proxy explizit auf diese IP binden. Dazu öffnen wir die Datei /etc/squid/squid.conf und passen die http_port-Zeile an:
http_port 192.168.99.2:3128

Der Port ist natürlich frei wählbar - wichtig ist hier nur die IP-Adresse. Nach einem Squid-Neustart sollte jetzt sämtlicher Proxy-Traffic über die 192.168.123.98 laufen - der restliche Traffic nach wie vor über die 192.168.123.99.

Sinn?

Gute Frage! PHP-Skripte können zum Beispiel über PHP-Proxy die zwei unterschiedlichen Leitungen benutzen. Selbiges gilt natürlich auch für Clients, die in Ihrem Browser die virtuelle IP des Squid als Proxy eintragen. Somit kann man mit wenigen Klicks mal eben die IP wechseln...

Geschrieben am Montag, 01. Februar 2010 und abgelegt unter Webtechnik.