Policy-Routing: Endlich Absenderadresse bei ungewöhnlicher Routing-Konstruktion

Aus NOBAQ
Zur Navigation springenZur Suche springen

Dieser Server befindet sich in einem Netzwerk 192.168.200.0/24, das ein Gateway auf 192.168.200.120 hat; das soll auch die default-route sein. Das Gateway führt über ISDN ins internet. Andererseits ist das Netz ans WLAN (192.168.0.0/24) angeschlossen, über den Router (pylon) 192.168.200.110 bzw fürs WLAN 192.168.0.2. Im WLAN gibts den Router ‘ianus’, der eine xDSL Verbindung ins Internet hat. Nachdem xDSL schneller ist, soll der Webserver www.stiftingtal.net über das WLAN ansprechen, jedoch soll die Defaultroute über ISDN gehen. Wie ich es vorher gelöst habe (einfach) und wie es jetzt vieeeeeeel besser funktioniert, beschreibe ich hier!


Der komplette Anfang

Gaaaaaanz am Anfang lief der komplette Traffic über ISDN. Das war langsam.

Das WLAN bekommt Internet, der ianus portforwaring

(Dann) ganz am Anfang hatte nobaq 2 Netzwerkinterfaces: eth0 (192.168.200.121/24) für das interne Netzwerk und eth1 (192.168.0.0/24) für das WLAN, an das direkt der Accesspoint angeschlossen war. Portforwaring war so kein Problem.

Der Router pylon kommt ins Spiel

Aber irgendwann sollte nobaq nicht mehr in meinem Zimmer stehen. Aber nur in meinem Zimmer kann ich beide Netzwerkkabeln (WLAN, intern) anschließen. Damit ich das von überall machen kann, habe ich ‘pylon’ geschaffen, einen fli4l-Linux-Router, der im Spitzboden steht, ein Minimallinux auf nur einer Diskette fährt und weder Bildschirm, Tastatur, Maus, Festplatte etc auf einem alten Compaq Contura 410C Notebook hat. Zwei PCMCIA Netzwerkkarten routen zwischen dem lokalen Netzwerk und dem WLAN.

Bis heute wurde das Portforwarind dann so gelöst, das der ianus sowohl DNAT als auch SNAT gemacht hat:

# Maskiert alles fürs WLAN:
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

# 02.04.05: nobaq ist hinterm fli4l Router also Erweiterung
iptables -t nat -A POSTROUTING -s ! 192.168.0.0/16 -d 192.168.200.111 -j MASQUERADE

# Und nun DNAT für das Portforwarding, z.B.
iptables -t nat -A PREROUTING -i ppp0 -p tcp –dport 80 -j DNAT –to-destination 192.168.200.121:80

Pakete, die weitergeleitet wurden, wurden also doppelt verändert: Einerseits die Zieladresse auf 192.168.200.121 um zu nobaq zu kommen, andererseits die Queladresse auf 192.168.0.1. Also Masquerading ins *interne* Netz! Somit wurden die Pakete zu nobaq weitergeleitet. Wären sie nicht geSNATtet, wären die Antwortpakete über das ISDN-Defaultgateway gelaufen. Abgesehen davon, dass sie eine andere Absenderadresse durch NAT hätten und so nie angekommen wären, dürften sie das interne Netz wohl nie verlassen haben, weil keine bestehende Verbindung in der NAT-Tabelle von 192.168.200.120 eingetragen war.

Das ganze hatte einen rieesen Schönheitsfehler: Da alle Paktete nun “intern” waren, kannte ich auf “nobaq” die Absenderadresse nicht mehr!! Ich konnte ledliglich feststellen, dass es sich um externe Pakete vom WLAN handelt (wenn sie von 192.168.0.1, also ianus kamen).

Die erste Idee

Lange hat mich das gestört, aber ich hab es hingenommen. Ich wusste zwar, dass der Schlüssel in LARTC verborgen lag, aber ich war zu faul, es zu lesen ;-)


Der extrem umständliche Ansatz (gestern)

Gestern gebar ich dann einen vollständig neuen Ansatz: Man muss eigentlich nur erkennen, ob die Pakete von ianus kommen. Also wollte ich die weitergeleiteten Pakete am ianus markieren:

iptables -t mangle -A POSTROUTING -d 192.168.200.121 -j MARK –set-mark 10

Das POSTROUTING ist wichtig, weil die Zieladresse ja erst nach dem DNAT stimmt (also nach dem Routing). Das Kommando sollte die IP Pakete markieren.

Am nobaq sollte ich sie mittels

iptables -t filter -A INPUT -m mark –mark 10

erkennen können. Über connection Tracking hätte ich die Antwortpakete ebenfalls markieren können und mittels ipt_route (iptables Modul) das Gateway auf 192.168.111 umschreiben können.

Der "kleine" Schönheitsfehler: MARK markiert Pakete nur lokal und wird nicht ins Paket selbst geschrieben. Und, naja, selbst wenn, ipt_route ist erst ab 2.6 verfügbar, denn ich nicht will (oder als Patch für 2.4., den ich auch nicht will).

Weitere Überlegungen betrafen ein Muster bei Setzung von TOS und TTL Felder. Aber diese stupiden Ideen wurden sofort fallengelassen.

Die letzte Idee wäre über die IP options genangen, aber erstens ist mir da kein Modul bekannt, das diese setzen könnte und andererseits wäre diese Methode alles andere als schön!


Der finale, saubere Lösung

Was könnte man am Paket sonst noch verändern. Quelladresse geht ja nicht. Wenn ich sie verändere, habe ich keinen Vorteil gegenüber jetzt, wenn ich sie nicht verändere, kann ich nicht mehr feststellen, dass das Paket von ianus kommt. Die Idee: Die Zieladresse !!!

Das ist es! Es wird ein virtuelles Netzwerkinterface angelegt (alias), an welches der ianus weiterleitet:

ifconfig eth0:0 192.168.200.111 netmask 255.255.255.0 up

Dauerhaft in Debian in /etc/network/interfaces:

auth eth0.0
iface eth0:0
    address 192.168.200.111
    netmask 255.255.255.0
    network 192.168.200.0
    broadcast 192.168.200.255

Das sollte also das neue Interface für das WLAN werden. Jeglicher WLAN Traffic sollte nach 192.168.200.111 gehen. Jetzt brauche ich am nobaq nur mehr schauen, ob die Absenderadresse 192.168.200.111 ist und wenn ja, das Gateway auf 192.168.200.110 ändern. Da der pylon als default-gateway 192.168.0.1 eigentragen hat, findet das Paket den richtigen Weg zurück. Handelt es sich um ein internes Paket macht das auch nix, weil der pylon dann das Paket wieder zurück ins interne Netz schickt.

Alle Forwarding-Regeln auf ianus, die DNS Server, DHCP Server, SMB und alles andere wurde nach 192.168.200.111 umgerüstet.

Eine neue Diskette wurde für pylon erstellt, die statt 121 nur mehr 111.

Auf nobaq wurden alle Dienste angewiesen, auch auf 192.168.200.111 zu binden.

Soweit so gut. DNAT+SNAT auf dem ianus gibt es noch immer, denn ich habe nach wie vor das Problem: Wie ändere ich das default-Gateway? IPT_Route braucht Kernel 2.6, den ich nicht habe!


Die Lösung: iproute2

Die Lösung bringt iproute2. Meine 13 Tage uptime muss ich trotzdem abwürgen, denn ich muss den Kernel neu übersetzen und installieren. Es muss nämlich die Option “Linux Advanced Router” in den “network settings” gewählt werden. Dadurch erhält man “policy routing”, d.h. Routing wird nicht mehr nur anhand der Zieladresse, sondern auch anhand anderen Eigenschaften wie Absendet, TOS, MARK etc entschieden.

Nachdem der Kernel neu übersetzt, installiert und nobaq neu gebootet wurde, ging es an die Konfiguration.

Das Dokument auf http://www.compendium.com.ar/policy-routing.txt ist hervorragend kurz und verständlich!

Zuerst muss eine neue Regel erstellt werden, für die irgendwas passieren soll. Die Regel soll lauten: “Ist die Absenderadresse 192.168.200.111″. Da mache ich mir zunutze, dass die Absenderadresse 192.168.200.111 ist, sofern man dort was hinschickt, sonst aber das Hauptinterface ist, also 192.168.200.121, die nach wie vor durch die default route gehen sollen

ip rule add from 192.168.200.111 table 20

Lies: “Ist die Absenderadresse 192.168.200.111, konsultiere Tabelle 20″.

Nun muss man nur mehr die passende Route hinzufügen:

ip route add default dev eth0 via 192.168.200.110 table 20

Lies: “Mach eine Defaultroute nach 192.168.200.110, die dann angewendet wird, wenn die Regel(n) in Tabelle 20 zutreffen”.


Die Kontrolle

Der SNAT Eintrag aus ianus wurde entfernt und die tests ergaben: POSTIV!


Auf ianus lief tcpdump, um zu überprüfen, ob die passenden Pakete den Weg finden. Ein externer Rechner (engelbart.htu.tugraz.at) diente als Testmaschine:

$ tail -f /var/log/apache2/access.log
192.168.0.1 - - [11/May/2006:16:47:17 +0200] “GET / HTTP/1.0″ 200 11249 “-” “-”
129.27.203.27 - - [11/May/2006:16:49:39 +0200] “GET / HTTP/1.0″ 200 11249 “-” “-”

Yeah! Oben alt, unten neu! Und tcpdump am ianus hat den Traffic angezeigt. Fehlt nur mehr die Kontrolle, ob normaler Traffic eh nicht übers WLAN geht:

ping www.google.at verhält sich verdächtig schnell (wie im WLAN), jedoch sieht man auf tcpdump am ianus nichts davon.

Ein gültiger Test:

root@nobaq:~ # telnet checkip.dyndns.org 80
Trying 204.13.250.51...
Connected to checkip.sjc.dyndns.org.
Escape character is ‘^]’.
GET / HTTP/1.0

HTTP/1.1 200 OK
Content-Type: text/html
Server: DynDNS-CheckIP/0.2
Connection: close
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 105

Current IP CheckCurrent IP Address: 62.46.175.123
Connection closed by foreign host.
root@nobaq:~ # nslookup 62.46.175.123
Server: 192.168.200.121
Address: 192.168.200.121#53

Non-authoritative answer:
123.175.46.62.in-addr.arpa name = L0892P27.dipool.highway.telekom.at.

Authoritative answers can be found from:
175.46.62.in-addr.arpa nameserver = kdns1.highway.telekom.at.
175.46.62.in-addr.arpa nameserver = kdns2.highway.telekom.at.
kdns1.highway.telekom.at internet address = 195.3.96.85
kdns2.highway.telekom.at internet address = 195.3.96.86

root@nobaq:~ #

was eindeutig meiner externen IP Adresse entspricht.

Zum Schluss trage ich die “ip” Kommandos noch in /etc/network/interfaces ein, damit sie automatisch gesetzt werden (mittels up/down).

Kommentare

  1.
     Leo sagt,
     am 16. Jun. 2007

     Danke! Hatte gerade ein sehr ähnliches Problem.

     Wir hatten hier im Büro seit vielen Jahren eine schnarchlangsame 64kBit-ISDN-Leitung als
     Internet-Zugang. Gestern konnte ich endlich eine zweite WAN-Anbindung einrichten, die aber
     stark gefirewalled ist.

     Nachdem ich mich früher über die ISDN-Leitung per SSH zur Fernwartung einloggen konnte,
     ging das nun natürlich nicht mehr (denn die Default Route zeigt ja auf die “dicke” Leitung).

     Dank iproute2 laufen die Antwortpakete auf ISDN-Verbindungen nun auch wieder in das richtige Interface.

     Danke für Deine großartige Dokumentation!!

     Viele Grüße
     Leo.