
Im IP-Routing-Subsystem bietet Linux 2.2 neue Möglichkeiten: Es erlaubt Routen, die nicht nur von der IP-Adresse des Empfängers abhängen, sondern auch von der des Absenders, vom gewünschten Type Of Service oder sogar vom benutzten Dienst oder Protokoll - man könnte also zum Beispiel wichtige Dienste oder die Daten besonderer Kunden über separate Verbindungen leiten, wenn die Hauptkanäle zu stark verstopft sind.
Ein ankommendes IP-Paket muss zuerst den Input-Filter des Routers überwinden. Mit diesem Filter kann der Administrator wie gewohnt unerwünschte Pakete von der weiteren Bearbeitung ausschließen oder Verbindungen zu anderen Rechnern zwangsweise auf den Router umleiten, zum Beispiel um alle Zugriffe auf WWW-Seiten durch einen lokalen Proxy zu schleusen, ohne dass die Benutzer davon etwas merken (Transparent Proxy). Neu in Linux-Version 2.2 ist die Möglichkeit, ausgewählte IP-Pakete im Input-Filter mit einer Markierung (firewall mark, kurz fwmark) zu versehen und diese bei der Bestimmung der Route für das Paket als zusätzliches Auswahlkriterium zu verwenden.
Der nächste Schritt des Kernels besteht darin, das weitere Schicksal der noch verbliebenen Pakete zu erkunden. An dieser Stelle haben wohl die radikalsten Änderungen stattgefunden: Früher stellte der Kernel erst einmal fest, welche Pakete für den Router selbst bestimmt waren, und lieferte sie aus. Später konsultierte er seine Routing Table, um geeignete Abnehmer für die übrigen Pakete zu finden - entweder die tatsächlichen Empfänger oder weitere Router, die näher am Empfänger liegen. Der aktuelle Linux-Kernel arbeitet effizienter und vor allem eleganter: Er bestimmt das Ziel jedes Pakets in nur einem Arbeitsgang. Die dafür notwendigen Daten stehen in einer kernel-internen Mini-Datenbank, der Forwarding Information Base (FIB). Diese besteht aus mehreren Routing-Tabellen und einem Satz von Regeln (nicht zu verwechseln mit den Firewall-Regeln), die bestimmen, welche Tabellen der Kernel in welcher Reihenfolge durchsucht.
Da die einzelnen Routing Tables als sortierte Liste von Hash-Tabellen organisiert sind, die wiederum sortierte Einträge enthalten, kann der Kernel einen Datensatz schnell finden, ohne die gesamte Tabelle durchsuchen zu müssen. Als Schlüssel für die Suche dienen die Adresse des Empfängers und das TOS-Feld (Type Of Service) aus dem empfangenen IP-Paket; das Ergebnis ist der Eintrag, der die größtmögliche Übereinstimmung mit der Zieladresse aufweist (longest match) und dessen TOS-Wert entweder Null ist oder zu dem des IP-Pakets passt. Der RFC 1812 beschreibt den Algorithmus im Detail (siehe Kasten Quellen).
FIB-Regeln erlauben die gezielte Behandlung eines IP-Pakets anhand seiner Quell- und Zieladressen, seines TOS-Feldes, einer vom Firewall-Input-Filter angebrachten Markierung und des Netz-Interface, über das der Router das Paket empfangen hat. Jede Regel verknüpft eine beliebige Kombination dieser fünf Parameter mit einer Aktion, üblicherweise mit der Benutzung einer der Routing-Tabellen. Der Systemadministrator kann aber auch eine Verbindung explizit sperren, indem er eine der Aktionen prohibit, reject oder unreachable auswählt.
Nach dem Booten enthält die FIB drei Regeln, die auf drei verschiedene Routing-Tabellen verweisen. Die erste Tabelle heißt local und enthält Routen für die Adressen aller lokalen Netz-Interfaces, einschließlich der verwendeten Broadcast-Adressen. Der Kernel legt diese Einträge automatisch an oder löscht sie wieder, wenn sich die Konfiguration der Schnittstellen ändert, der Systemverwalter muss sich darum also nicht kümmern. Die zweite Tabelle, main, enthält alle normalen Routen und entspricht etwa der klassischen Routing Table. Der Superuser kann sie wie gewohnt mit dem Programm route ansehen und bearbeiten; dadurch ist die Kompatibilität mit älteren Kernel-Versionen gewährleistet. Die dritte Tabelle ist normalerweise leer und hört auf den Namen default.
Der Kernel durchläuft alle FIB-Regeln, die zu dem empfangenen Paket passen, und führt die dazugehörigen Aktionen aus. Sobald eine Aktion zu einem konkreten Ergebnis führt, sei es positiv (Route gefunden) oder negativ (Route gesperrt), bricht er die Suche ab. Die Regeln sind nach ihrer Priorität geordnet: Die Regel für die Tabelle local hat die höchstmögliche Priorität, main und default dagegen haben eine sehr niedrige. Der Systemverwalter kann weitere Regeln einbauen oder die bestehenden löschen und durch andere ersetzen, nur die Regel für die lokalen Routen ist unantastbar.
Da die Suche in der FIB trotz aller Optimierungen immer noch ein zeitaufwändiger Vorgang ist, hält der Kernel die Ergebnisse in einem internen Cache fest. Eine regelmäßige Garbage Collection entfernt alte, nicht mehr benutzte Einträge; die Haltezeit ist aber so groß bemessen, dass ein Eintrag, den der Kernel zu Beginn einer TCP-Verbindung gemacht hat, in den meisten Fällen auch das Ende der Verbindung noch erleben dürfte.
Zurück zum empfangenen Paket. Der Router weiß jetzt, ob er das Paket lokal zustellen, weiterleiten oder unter den Teppich kehren muss; der Rest ist ein Kinderspiel. Zuerst wertet der Kernel noch einmal das Ergebnis des Firewall-Input-Filters aus, reicht umgeleitete Pakete an die lokalen Proxies weiter und verschickt per ICMP Rückmeldungen für die abgewiesenen Pakete (sofern er diese nicht gleich bei der Filterung kommentarlos hat verschwinden lassen). Anschließend trennen sich die Wege der lokal zustellbaren und der weitergeleiteten Pakete endgültig. Die gerouteten Pakete verlassen den Rechner auf dem üblichen Weg: durch die Forward- und Output-Filter zum Netz-Interface. Vom Router selbst erzeugte Pakete müssen nur die Routing-Einheit und den Output-Filter durchlaufen, bevor sie ins Netz gelangen.
Auch im Firewall-Code von Linux 2.2 hat sich einiges getan. Geblieben ist die Aufteilung in drei Paketfilter, hinter denen sich je eine Kette von Regeln verbirgt. Jede Regel verknüpft ein Muster mit einer Aktion, und der Kernel vergleicht IP-Pakete der Reihe nach mit allen Mustern und führt die dazugehörige Aktion aus, wenn das Paket zum Muster passt.
Ein Muster kann eine oder mehrere der folgenden Komponenten enthalten: die IP-Adressen von Absender und Empfänger des Pakets, das benutzte Netz-Interface (beim Input-Filter ist dies das Interface, über das der Rechner das Paket empfangen hat, bei den anderen Filtern das Sende-Interface), das verwendete Protokoll und die Portnummern von Absender und Empfänger (bei TCP und UDP). Außerdem ist es möglich, Fragmente - Teile von IP-Paketen, die für die Übertragung in einem Stück zu groß waren - oder TCP-Pakete mit gesetztem SYN-Bit, die den Beginn einer Verbindung anzeigen, auszusondern und getrennt zu behandeln. Der Clou ist, dass jedes einzelne Teilmuster wahlweise ein- oder ausschließende Wirkung haben kann; dadurch lassen sich kürzere Ketten bilden, was wiederum die Übersichtlichkeit und den Durchsatz der Filter erhöht.
Welche Aktionen in einer Regel sinnvoll sind, hängt davon ab, in welcher Kette sie sich befindet. Die Standardaktionen ACCEPT, REJECT und DENY, die ein Paket durch den Filter lassen, zurückweisen oder kommentarlos wegwerfen, funktionieren in allen Ketten. MASQ lässt Pakete ebenfalls durch den Filter, aktiviert aber zusätzlich das Masquerading - der Router ersetzt die Absenderadresse des Pakets durch seine eigene - und ist nur im Forward-Filter sinnvoll. REDIRECT sorgt im Input-Filter dafür, dass der Kernel Pakete nicht an den richtigen Empfänger weiterreicht, sondern an einen lokalen Proxy.
Darüber hinaus kann der Systemverwalter zusätzliche Regelketten (user-defined chains) erzeugen und aus anderen Ketten heraus aufrufen, indem er die neue Kette (beziehungsweise ihren Namen) als Aktion in eine Regel einer anderen Kette einbaut. Benutzerdefinierte Ketten können beliebig tief verschachtelt sein, sie dürfen sich nur nicht rekursiv selbst aufrufen.
Erreicht der Kernel das Ende einer Kette oder trifft er auf eine passende Regel mit der Aktion RETURN, verlässt er die gerade aktuelle Kette, kehrt zur aufrufenden zurück und macht dort mit der nächsten Regel weiter. Die drei fest eingebauten Ketten besitzen eine Default-Aktion (chain policy), die der Kernel beim Verlassen der Kette ausführt.
Firewall-Regeln können diverse Nebenwirkungen haben. Sie enthalten zum Beispiel zwei Zähler, in denen der Kernel Anzahl und Länge aller Pakete addiert, die zum Muster der Regel passten. Diese eignen sich sowohl zur Beobachtung der Netzaktivität als auch zum Debuggen der manchmal recht umfangreichen Firewall-Konfiguration. Jede Regel kann die gefundenen Pakete auf Wunsch als Hexdump auf der Konsole beziehungsweise in den Log-Dateien des Systems verewigen oder Kopien zur Auswertung an ein beliebiges Programm weiterreichen. Interessant ist auch die oben bereits erwähnte Möglichkeit, Pakete im Vorbeigehen zu markieren und die Markierungen bei der Auswahl der Routing Table auszuwerten.
Diese untergeordneten Aufgaben führt der Kernel aus, bevor er die Aktion einer Regel auswertet, die dann über das Schicksal des Pakets entscheidet. In manchen Fällen ist es angebracht, solchen Regeln gar keine Aktion zuzuordnen und nur die Nebeneffekte auszunutzen; der Kernel geht dann automatisch zur nächsten Regel über.
Um in den Genuss dieser neuen Features zu kommen, muss der Superuser oft zuerst den Kernel neu konfigurieren. Die erweiterten Routing-Fähigkeiten verstecken sich hinter der Option IP: advanced router - nur wenn diese eingeschaltet ist, lassen sich die einzelnen Funktionen auswählen: Policy Routing, Multipath, TOS-basiertes Routing und Network Address Translation (NAT). Den Firewall-Code sollte man ebenfalls einschalten, auch wenn man ihn gerade nicht braucht.
Die Unix-Systemprogramme ifconfig und route funktionieren mit dem neuen Kernel wie gewohnt, mit einer Ausnahme: Beim Einrichten von Netz-Interfaces legt der Kernel automatisch passende Routen an, der Aufruf von route kann an dieser Stelle entfallen. Viele dieser Routen liegen in der Tabelle local und sind deshalb für route oder netstat -r nicht sichtbar; dazu gehört auch die Route für localhost (127.0.0.1), was alte Linux-Adepten ebenso verwirren kann wie das gelegentlich auftretende, scheinbar mehrfache Vorkommen derselben Route.
Ein neues Tool namens ip bringt Licht ins Dunkel. Es kann nicht nur alle Routing-Tabellen sowie die dazugehörigen FIB-Regeln anzeigen und verändern, sondern beinahe die ganze Familie der Netz-Konfigurationsprogramme ersetzen, einschließlich ifconfig und arp. Leider besitzt ip eine andere Aufrufsyntax als seine Vorgänger, der Systemverwalter muss also umdenken. Dabei können neben der Dokumentation im Linux-Quellcode auch die schriftlich fixierten Erfahrungen anderer Benutzer eine große Hilfe sein, zum Beispiel das Advanced routing mini-HOWTO und das Policy based routing MICRO-HOWTO (siehe Kasten Quellen).
Listing 1 zeigt am Beispiel eines einfachen Hosts die Netzinitialisierung - noch mit den gewohnten Tools - und die Abfrage der verschiedenen Routing Tables mit dem Kommando ip route. Vom Kernel erzeugte Routen sind an den zwei Wörtern proto kernel erkennbar, ein Routing-Dämon könnte hier seinen Namen oder das verwendete Routing-Protokoll eintragen, zum Beispiel gated oder ospf. Die Namen boot und static haben eine besondere Bedeutung: Manche Routing-Dämonen löschen beim Start alle Routen vom Typ boot, mit static markierte Einträge dagegen bleiben erhalten. Routen ohne explizite Angabe, wie die Default-Route im Beispiel, haben den Typ boot.
Den Einzugsbereich einer Route gibt der Parameter scope an: host steht für den lokalen Rechner, link für direkt angeschlossene Netze und global - oder gar keine Angabe - für den Rest der Welt. dev und src zeigen, auf welchem Weg ein IP-Paket den Rechner verlässt und welche Absenderadresse es tragen soll, via hat als Argument die Adresse des gewünschten Routers.
ip route akzeptiert dieselben Parameter auch als Argumente. Um beispielsweise die angegebene Default-Route mit ip einzurichten, muss man nur ip route add default via 192.168.0.42 dev eth0 eintippen. Parameter, deren Wert offenkundig ist, wie in diesem Fall das dev eth0, oder die den Default-Werten entsprechen, dürfen fehlen. IP-Adressen und Netze müssen grundsätzlich in numerischer Form angegeben werden. Routen lassen sich mit ip route del wieder löschen, mit change verändern oder mit replace komplett ersetzen. ip route help liefert eine kurze Zusammenfassung aller möglichen Argumente.
Ohne den Parameter table beziehen sich alle Kommandos auf die Haupt-Routing-Tabelle main. Der Kernel erzeugt neue Tabellen dynamisch beim Eintragen der ersten Route, der Superuser muss nur den Namen oder die Nummer einer freien Tabelle an ip übergeben. Die Zuordnung von Namen und Nummern ist in der Konfigurationsdatei /etc/iproute2/rt_tables festgelegt; für andere Parameter existieren ähnliche Dateien.
Eine frisch erzeugte Tabelle ist nutzlos, solange keine der FIB-Regeln auf sie verweist. Listing 2 zeigt, wie man selbstdefinierte Routing-Tabellen in das System einbindet. Die Syntax von ip rule ähnelt der von ip route, insbesondere existieren auch hier die drei Subkommandos add, del und list zum Anlegen, Löschen und Anzeigen der Regeln.
Der Parameter pref bestimmt die Priorität eines Eintrags - kleine Zahlen bedeuten hohe Priorität - und sollte eindeutig sein. Wenn er fehlt, fügt ip die neue Regel zwischen dem ersten und zweiten Eintrag ein, mit der niedrigsten möglichen Priorität; ein fünfter Eintrag im Beispiel bekäme demnach den Wert 9999 zugeordnet.
Bis zum Policy Routing ist es jetzt nur noch ein kleiner Schritt. Das Kommando ip rule add versteht fünf weitere Parameter, die den Wirkungsbereich eines Eintrags einschränken können: Mit from und to kann der Systemadministrator die Absender- und Empfängeradressen festlegen, für die die Routing-Tabelle gilt. dev oder iif sortiert alle Pakete aus, die nicht über das angegebene Netz-Interface in den Router gelangt sind, und tos legt den Type of Service fest - hier kann als Argument wahlweise eine Zahl stehen, oder einer der in der Datei /etc/iproute2/rt_dsfield definierten Namen.
In besonders kniffligen Fällen kann die eingangs erwähnte Markierungstechnik zum Einsatz kommen: Der Firewall-Input-Filter kann zum Beispiel alle Pakete markieren, die zu SMTP-Verbindungen gehören (sie sind leicht an der TCP-Portnummer zu erkennen). Die Markierung - eine vorzeichenlose ganze Zahl - wird mit ip rule add fwmark <markierung> ... in die FIB eingetragen.
Auch das Programm ipfwadm hat ausgedient. Sein Nachfolger ipchains ist bereits das dritte Firewall-Utility in der Linux-Geschichte, und sicher nicht das letzte - das ist der Preis des Fortschritts. Eine Veränderung war unnötig: Bei den meisten Optionen haben Groß- und Kleinbuchstaben die Plätze getauscht, statt ipfwadm -a heißt es jetzt ipchains -A, und aus ipfwadm -S wurde ipchains -s. Neu hinzugekommen sind unter anderem die Optionen -N und -X, die benutzerdefinierte Firewall-Ketten erzeugen beziehungsweise löschen.
Für Policy-Routing ist hauptsächlich die Option -m zum Markieren von Paketen interessant. Das Listing unter diesem Absatz zeigt die praktische Anwendung am Beispiel SMTP: die ipchains-Aufrufe sorgen dafür, dass der Input-Filter alle Pakete von oder nach TCP-Port 25 mit der Markierung 1 versieht; da keine andere Aktion angegeben ist, findet auch keine Filterung statt, es sei denn, es folgen weitere Regeln. Die dritte Zeile bewirkt, dass der Kernel für die so markierten Pakete die zusätzliche Routing-Tabelle 25 konsultiert.
$ ipchains -I input -p tcp -s 0/0 25 -m 1 $ ipchains -I input -p tcp -d 0/0 25 -m 1 $ ip rule add fwmark 1 table 25
Dieser Artikel endet zwar hier, aber die Liste der Features noch lange nicht. Die Routing-Fähigkeiten des neuen Linux-Kernels gehen weit über das hinaus, was man von Unix oder Unix-Clones gewohnt ist, allerdings dauert es eine gewisse Zeit, sich einzuarbeiten - die Dokumentation zum Thema ist leider weder üppig noch leicht zu finden.
MICHAEL RIEPE
studiert Elektrotechnik an der Universität Hannover.
| iX-TRACT |
|
Dieser Text ist der Zeitschriften-Ausgabe 09/1999 von iX entnommen.
iOS, Android, Windows Phone 7 und HTML5 - das neue Sonderheft von heise Developer führt Einsteiger und Profis in die Programmierung mobiler Geräte ein.