Policy Based Routing

Aus Linupedia
Wechseln zu: Navigation, Suche

Dieser Artikel will die Grundlagen von Policy Based Routing sowie die zugehörigen Konfigurationsmöglichkeiten unter Linux erklären. Der Artikel setzt voraus, dass der Leser grundlegendes Verständnis im Thema Routing unter Linux hat. route, netstat, Routing Table, NAT, Masquerading und ähnliches sollten also keine Fremdwörter für den Leser sein.

Was ist Policy Based Routing?

Unter dem Begriff "Policy Based Routing" versteht man die Möglichkeit, Routing-Entscheidungen an Hand eines vordefinierten Regelwerkes zu treffen. Dies unterscheidet sich stark von den bisher eingesetzten Routingmöglichkeiten, bei welchen ein Router nur an Hand des Zieles, eines Datenpaketes entscheidet, an welchen Next Hop das Paket weitergereicht wird.

Mit PBR ist es nun möglich, dass ein Router auch die Quelle eines Paketes, die Größe des Paketes, bestimmte Flags, das Protokoll und noch vieles mehr berücksichtigt und dann entscheidet, was der Next Hop für das Paket sein soll.

Für Weiteres siehe Quelle [1].

Vorteile von PBR (Oder: Wozu braucht man das überhaupt?)

Sie auch Quelle [2].

Ereichen des gleichen Ziels über zwei Verbindungen

In der Vergangenheit als das Internet noch überschaubar war, hatte man oftmals zwei Anbindungen an seine Kommunikationspartner. Eine über ein kommerzielles Netz, welches zuverlässig, aber teuer war und eine Anbindung über das Internet, welche günstig aber unzuverlässig war.

Je nachdem, von wo nun Daten zum Partner geschickt wurden, wurde entweder die kommerzielle oder die öffentliche Anbindung genutzt. Man musste also anhand der Quelle der Daten unterscheiden, welche Daten wie geroutet werden sollten. Das sonst übliche Routing auf Basis des Zieles konnte man hier nicht einsetzen, da das Ziel ja jedesmal identisch war.

QoS

Heute dürfte QoS (Quality of Service) eine größere Rolle spielen.

Angenommen, ein Internetprovider hat zwei Kundengruppen: Privatkunden und Firmenkunden. Die Privatkunden zahlen nur einen geringen Preis für die Internetanbindung, wärend die Firmenkunden einen hohen Preis zahlen. Nun möchten die Firmenkunden natürlich auch einen höhere Verbindungsgeschwindigkeit garantiert bekommen als dies für die Privatkunden üblich ist. In einem solchen Umfeld könnte der Internetprovider anhand der Quelle eines Datenpaketes entscheiden, ob dieses mit Vorgang behandelt wird oder nicht.

Ein weiteres Szenario kennt man von VoIP (Voice over IP). Die Datenpakete eines Telefongespräches müssen zügig beim Empfänger ankommen, wenn man vermeiden will, dass dieser ein Echo, oder einfach eine "schlechte Leitung" im Gespräch hört. Bandbreite steht leider nicht unbegrenzt zur Verfügung, so dass man entscheiden muss, welches Datenpaket über eine bessere Leitung (weil schneller) übertragen wird und welche nicht. Auch hier kann PBR wieder helfen. Anhand des im Paket eingesetzten Protokolls kann ein Router der PBR-fähig ist entscheiden, ob ein Datenpaket über ein gute Leitung geschickt werden muss, oder ob es eine weniger gute Leitung nehmen kann.

Sonstiges

In letzter Zeit kam leider auch das Thema "Netzneutralität" in den Medien auf. Auch dies wäre ein Anwendungsfall für PBR.

Nachteile von PBR

Die Nachteile von PBR liegen vor allem im höhren Administrationsaufwand. Das Regelwerk für die Router muss erstellt und gepflegt werden. Dynamisches Routing wird schwieriger einzubinden und auch die Fehlersuche im Netzwerk wird komplizierter, da man nicht einfach ein Traceroute absetzen kann, um zu sehen welche Route die Daten nehmen würden (dies kann sich von der Route des Traceroutes nämlich unterscheiden).

Konfiguration von PBR unter Linux

Voraussetzungen

Damit PBR unter Linux funktioniert, muss der Kernel dies unterstützen. Die Kernel der größeren Distributionen sind heute standardmäßig mit den notwendigen Optionen übersetzt worden, so dass man sich nicht selbst darum kümmern muss. Wer seinen Kernel selbst kompiliert sollte darauf achten, dass CONFIG_IP_ADVANCED_ROUTER und CONFIG_IP_MULTIPLE_TABLES auf "y" gesetzt sind.

Des Weiteren benötigt man das Programm "ip" welches sich, je nach Distribution, im Paket "iproute" bzw. "iproute2" befindet. Dieses Programm wird heute meist automatisch bei der Installation mitgeliefert, so dass man es in den seltensten Fällen nachinstallieren muss.

Prinzip (oder: Erklär mir wie es funktioniert, ohne mir die Sourcecodekommentare zu zeigen)

Wie muss man sich das Policy Based Routing technisch vorstellen?

Vorweg eine kurze Anmerkung. Ich verwende nachfolgend sowohl die Begriffe Router und Firewall gleichwertig. Zwar kann eine Firewall mehr als ein Router, allerdings ist dies für das Policy Based Routing vorerst nicht von Interesse.

Das klassische Destination-based Routing arbeitet folgendermaßen: Ein Datenpaket erreicht den Router/die Firewall und durchläuft erstmal die PREROUTING-Kette (in Netfilter heißen sie chains) des Firewallsystems (vergleiche: PacketFlow-new.png ). Unter Umständen kann das Paket hier verändert werden. Dies erläutere ich später noch genauer. Nach der PREROUTING-Kette steht die Routing-Entscheidung an, d.h. der Router muss nun entscheiden, ob und wohin das Paket weitergeleitet werden muss. Diese Entscheidung traf der Router bisher anhand einer Tabelle, der sogenannten Routing-Tabelle. In dieser Tabelle stand nur drin, was der Next Hop, also der nächste Weiterleitungspunkt für ein Paket mit einem bestimmten Ziel ist. Anbei eine klassische Routingtabelle, wie sie der (klassische) Befehl route -n liefert:

 Ziel            Router          Genmask         Flags Metric Ref    Use Iface
 192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 ra0
 192.168.181.0   0.0.0.0         255.255.255.0   U     0      0        0 vmnet1
 172.16.143.0    0.0.0.0         255.255.255.0   U     0      0        0 vmnet8
 0.0.0.0         192.168.1.2     0.0.0.0         UG    0      0        0 ra0


Policy Based Routing erweitert dieses Konzept nun folgendermaßen: Statt einer Routingtabelle gibt es gleich mehrere. Man kann sogar eigene Tabellen anlegen. Jede Tabelle hat eigene Einträge wie sie auch die klassiche Routingtabelle hat. Der Router hat nun also mehrere Tabellen in denen er nachschauen kann, was der Next Hop für ein bestimmtes Ziel hat. So weit, so gut, jedoch muss der Router nun noch wissen, in welcher der vielen neuen Tabellen er jetzt tatsächlich nachschauen muss.

Hier kommt ein Rule List (= Regel Liste) ins Spiel. Innerhalb dieser Liste steht, in welcher Routingtabelle der Router nachschauen soll. Als Kriterium kommen bestimmte Eigenschaften des Datenpaketes in Frage, wie Quelladresse, Type of Service, Firewall-Markierung oder auch das Netzwerkinterface über welches das Paket reinkam.

Auf gut Deutsch kann in der Liste also drin stehen:

 Wenn ein Paket von 192.168.2.17 kommt, dann siehe in Routing Tabelle 5 nach.

Natürlich steht das nicht wirklich so drin. Eine echte Rulelist sieht so aus:

 0:      from all lookup local
 2000:   from all lookup 2
 3000:   from all lookup 3
 3500:   from all tos 04 lookup 32
 4000:   from 192.168.0.14 lookup 4
 4000:   from 192.168.0.3 lookup 4
 4000:   from 192.168.0.121 lookup 4
 4000:   from 192.168.0.30 lookup 4
 32000:  from all lookup 32
 32766:  from all lookup main
 32767:  from all lookup default

(Quelle siehe: Quellen am Ende der Seite, Quelle Nr. 5)

Die Zahlen vor den Anweisungen stellen die Priorität dar. Das heißt, das System geht die Liste in der Reihenfolge der Zahlen durch. Wenn das Kriterum, in diesem Fall die "from ..." Anweisungen auf das Paket passen, wird die Regel ausgeführt. In diesem Fall sind es die verschieden "lookup"s. Das bedeutet, wenn eine Regel greift, wird in der zugehörigen Routingtabelle nachgeschaut. Findet sich in der Routingtabelle ein Eintrag der auf das Paket zutrifft, wird also das Ziel des Paketes in der Tabelle erwähnt, so ist die Abarbeitung abgeschlossen. Der Router hat sich also entschieden. Findet der Router in der Tabelle keinen Routingeintrag, so geht er zum nächsten Eintrag der _Regelliste_ über und prüft diese. Dieses passiert so lange, bis eine Route gefunden wurde, oder die Regelliste komplett durchlaufen ist.

Übrigens: die Zahlen hinter den Lookups sind natürlich die verschiedenen Routingtabellen. Diese "nummerischen" Tabellen sind von root manuell angelegt worden. Die Routingtabellen "local", "main" und "default" sind standardmäßig enthalten. local enthält alle Regeln die sich aus der Konfiguration der Netzwerkkarten ergeben. "main" enthält die Routingtabelle wie man sie vom normalen Destination-based-Routing kennt. Man kann sich diese Tabelle mit dem Befehl "route" ansehen. "default" wird normalerweise als letzte ausgeführt und dient dem Aufräumen. Alles was bisher zu keinem Ergebniss geführt hat sollte hier abgehandelt werden. Standardmäßig ist diese Tabelle allerdings leer.


Die Praxis

Genug der Theorie, nun ein wenig Praxis. Nachfolgend die Erklärung, wie man eigene Regeln zur Rulelist hinzufügt. Hierzu braucht man das Programm "ip". ip ist ein echtes Schwergewicht in Sachen IP-Konfiguration. Es bietet unzählige Möglichkeiten und eine entsprechend lange Manpage. Darüber hinaus hat ip sogar noch eine eigenbaute Hilfefunktion, die man mit "ip help" aufrufen kann.

Wie man Regeln und Routen anlegt

Nun endlich genug der Worte. Wir wollen nun eine Regel anlegen, die auf Deutsch aussagt:

 Wenn die Quelle des Paketes gleich 192.168.1.17 ist, dann schaue in Routingtabelle 17 nach.

Das geht so. Einfach als root folgendes eintippen:

 ip rule add from 192.168.1.17 table 17

Anschließend kann man sich das Ergebnis, also die veränderte Rulelist so ansehen:

 ip rule list

oder wer es gerne kurz mag kann auch

 ip ru l

verwenden. Das ganze sollte jetzt so aussehen:

 0:      from all lookup local 
 32765:  from 192.168.1.17 lookup 17 
 32766:  from all lookup main 
 32767:  from all lookup default 

Wie man sehen kann, wurde die Regel als erste der letzten eingefügt, also also die höchste noch frei Priorität bekommen. Man kann dies beeinflussen, indem man die Priorität selbst festlegt. Das geht so:

 ip rule add from 192.168.1.17 prio 2 table 17

Wenn man sich nun die Liste wieder ansieht, erhält man folgendes:

 0:      from all lookup local 
 2:      from 192.168.1.17 lookup 17 
 32765:  from 192.168.1.17 lookup 17 
 32766:  from all lookup main 
 32767:  from all lookup default 

Unsere Regel steht zweimal drin. Das war eigentlich nicht beabsichtigt, ist aber kein Problem, man kann Regeln natürlich wieder löschen, und zwar so:

 ip rule del from 192.168.1.17 prio 32765 table 17

Nun sollte die Regelliste wieder so aussehen:

 0:      from all lookup local 
 2:      from 192.168.1.17 lookup 17 
 32766:  from all lookup main 
 32767:  from all lookup default 


Wie gesagt kann man noch mehr als nur die Quelle als Selektionskriterum verwenden. Z.B. das TOS Feld:

 ip rule add tos 0x4 table 18

Zu deutsch würde diese Regel bedeuten:

 Wenn ein Paket, egal welche QuellIP, beim TOS Feld den Wert 0x4 hat, dann siehe in Tabelle 18 nach.


Die Regelliste ist logischerweise nur die halbe Miete, denn damit kann man zwar sagen welche Routingtabelle genutzt werden soll, allerdings nützt einem dies gar nichts, wenn die ganzen Routingtabellen leer sind. Diese muss man auch noch erstellen und füllen. Dies funktioniert auch mit "ip". Folgendermaßen fügt man eine Route einer Tabelle zu:

 ip route add a.b.c.d table 2 via 192.168.1.1 dev ra0

Das a.b.c.d soll das Ziel darstellen, welches man in der Realität natürlich durch eine echte IP-Adresse ersetzen muss. "via 192.168.1.1" stellt natürlich den Gateway dar und "dev ra0" bezeichnet die Netzwerkkarte. Mit "table 2" bestimmt man das die Route der Tabelle 2 hinzugefügt werden soll.

Nun kann man sich die Routingtabelle auch ansehen:

 ip route list table 2
  a.b.c.d via 192.168.1.1 dev ra0

Übrigens: sollte man sich beim Anlegen einer Route vertippt haben sollen, kann man die Route natürlich auch wieder löschen. So würde man die erste Route löschen:

 ip route del a.b.c.d table 2 via 192.168.1.1 dev ra0

Auch ein ändern einer bestehenden Regel wäre möglich:

 ip route change a.b.c.d table 2 via 192.168.1.1 dev ra0 via 192.168.1.2

Damit wäre nicht 192.168.1.1 der Next Hop sondern 192.168.1.2.


Beispielhafte Konfiguration - Unterschiedliches Routing für verschiedene Dienste

Das ist alles schon recht nett, richtig spannend wird es aber erst, wenn man das ganze mit netfilter kombiniert. Dann entfalltet PBR erst seine ganze Herrlichkeit. Netfilter ist in der Lage, ein Paket abhängig von bestimmten Werten (wie z.B. den Serviceport) zu markieren. Diese Markierung kann der Routing-Code im Kernel wiederum erkennen und als Kritierum verwenden. Ein kleines Realweltbeispiel:

Angenommen man hat einen Server im Internet mit der IP Adresse a.b.c.d. Diese IP-Adresse erreicht man über das Internet oder über eine spearate VPN-Verbindung vom eigenen PBR-fähigen Router. Nun möchte man, dass die Benutzer im eigenen Netzwerk Mails über die verschlüsselte VPN-Verbindung senden. Normale https-Verbindungen sollen aber nicht über die VPN-Verbindung laufen, da eine zusätzliche Verschlüssung hier nur unnötigen Balast darstellt.

Der Router hat nun also zwei Routingtabellen (Nr. 2 und Nr. 3). Nr. 2 ist die Verbindung über das Internet, d.h. der Next Hop für das Ziel a.b.c.d ist 192.168.1.1 über das Netzwerkinterface ra0. Tabelle Nr. 3 stellt die Tabelle für die VPN-Verbindung dar. In dieser Tabelle ist der Next Hop für Ziel a.b.c.d die IP-Adresse 10.0.0.10 über das Interface tun0 (tun0 ist das VPN-Interface) eingetragen.

Da ip rule add keine Möglichkeit bietet, das TCP Destination Port Feld als Kriterium auszuwählen, kann man keine direkte Regel erzeugen. Stattdessen muss man mit iptables die Pakete markieren und anhand dieser Markierung filtern. Das geht nun so. Zuerst markieren wir das Paket:

 iptables -A PREROUTING -t mangle -p tcp -d a.b.c.d --dport 443 -j MARK --set-mark 2
 iptables -A PREROUTING -t mangle -p tcp -d a.b.c.d --dport 25  -j MARK --set-mark 3

Zu gut Deutsch:

  Füge zur PREROUTING-Kette folgendes hinzu: Wenn das Ziel a.b.c.d ist und der Zielport 443, dann gebe dem Paket die Markierung 2
  Füge zur PREROUTING-Kette folgendes hinzu: Wenn das Ziel a.b.c.d ist und der Zielport 25, dann gebe dem Paket die Markierung 3
 

Alle https-Pakete tragen nun also die Markierung 2, alle SMTP-Pakete die Markierung 3.

Nun muss man noch die entsprechende Regeln setzen:

 ip rule add fwmark 2 table 2
 ip rule add fwmark 3 table 3

Somit werden Pakete mit gleichem Ziel, aber unterschiedlichen TCP-Ports anhand unterschiedlicher Routingtabellen geroutet. Das war es, was wir _im Prinzip_ erreichen wollten. Einige Hinweise noch: Es macht keinen Sinn, die Markierung erst in der FORWARD- oder POSTROUTING-Kette zu setzen. Wie der Name schon sagt wurde die Routingentscheidung ja schon getroffen bevor die POSTROUTING-Kette durchlaufen wird. ip würde von der gesetzten Marke also längst nichts mehr mitbekommen.

Nun muss man noch die Routingtabellen 2 und 3 anlegen bzw. füllen. Dies geht so:

 ip route add a.b.c.d table 2 via 192.168.1.1 dev ra0
 ip route add a.b.c.d table 3 via 10.0.0.10 dev tun0

Die erste Zeile fügt der Tabelle 2 ein Eintrag hinzu, wodurch alle Daten für das Ziel a.b.c.d an 192.168.1.1 über das Interface ra0 geschickt werden.

Die zweite Zeile fügt der Tabelle 3 ein Eintrag hinzu, wodurch alle Daten für das Ziel a.b.c.d. an 10.0.0.10 über das Interface tun0 geschickt werden.

Das war es, was erreicht werden soll. Dank iptables und ip werden Pakete mit dem gleichen Ziel, aber unterschiedlichen Protokollen auch unterschiedlich geroutet. SMTP wird über die sichere VPN-Verbindung geschickt, HTTPS über das normale Internet. Das alles ohne dass die Clients im Netzwerk davon etwas mitbekommen.

Abschlussbemerkung

Ich hoffe die Grundlagen von Policy Based Routing mit Linux konnte ich in diesem Artikel erläutern. Natürlich sind nicht alle Möglichkeiten von PBR ausgeschöpft. Allein ip und iptables bieten schier unendlich viele Möglichkeiten, deren komplette Auflistung den Rahmen dieses Artikels bei weitem sprengen würden. Falls noch Fragen zum Thema offen sind stehe ich gerne für Antworten bereit. Meine Kontaktdaten finden sich auf meiner Homepage: http://www.benjaminfleckenstein.de

Quellen

  1. Englischer Wikipedia Eintrag zum Thema Policy Based Routing
  2. Policy Based Routing with Linux - Online Edition
  3. Homepage von iproute2
  4. Gentoo Seite welchen den Kernelsupport erläutert
  5. Policy based routing MICRO-HOWTO
  6. Wie man mit iptables Pakete markiert

zurück zum Netzwerk