Aus Linux-Magazin 11/2012

Dynamisches Routing unter Linux mit Quagga

© Markus Feilner

Wenn mehrere Wege ans Ziel führen, muss der Router entscheiden, welcher der beste ist. Cisco und Juniper entwickelten dafür Routingprotokolle, unter Linux hilft Software wie Quagga mit ihrem Zebra-Daemon dabei, automatisch den optimalen Pfad zu finden.

Komplexe, redundant ausgelegte Netze wie das Internet verlangen andere Routingverfahren als jene, die im LAN üblich sind. Idealerweise kennen die Router alle Wege zum Ziel, diese aber manuell zu konfigurieren wird schnell unübersichtlich und kann zu Fehlern führen.

Quagga: Zebra für Admins

Im Internet ist dieses Vorhaben schlicht unmöglich. Dort müssen sich dynamisch ändernde Routeninformationen automatisch verteilt werden – inklusive optionaler Redundanzen, wenn mehrere Wege zum Ziel führen. Die Netzwelt hat dafür spezielle Routingprotokolle entwickelt, die in der Regel nur auf Routern von Cisco oder Juniper Anwendung finden. Aber Quagga [1] erlaubt es Admins, auch mit einem Linux-Rechner am großen Routerverbund teilzunehmen. Das Projekt stammt von den Zebra Routing Daemons des Japaners Kunihiro Ishiguro ab [2], die Software ist in allen gängigen Linux-Distributionen enthalten und läuft auch auf anderen Unix-Derivaten wie Solaris und Free/Net/Open BSD.

Quagga übernimmt dabei nicht das Routing, das erledigt nach wie vor der darunter liegende Kernel des Betriebssystems, es stellt aber die Routingprotokolle RIP (Routing Information Protocol, [3]), RIP-NG [4], OSPF (Open Shortest Path First, [5]), BGP (Border Gateway Protocol, [6]) und IS-IS (Intermediate System To Intermediate System, [7]) bereit und ändert die Routingtabelle des Kernels entsprechend den gelernten Routen.

Pfadfinder-Grundausbildung

Das Internet besteht aus vielen, teils mehrfach verbundenen Teilnetzen, zwischen denen Pakete durch sinnvolles Routing den optimalen Pfad finden. Ein Verbund von Routern, den ein Team von Administratoren verwaltet, heißt “Autonomes System” (AS). Bei den Routingprotokollen unterscheidet man zwischen Protokollen, die innerhalb eines autonomen Systems die Routen verteilen (ein AS mag natürlich wieder unterteilt sein, sodass hier viele Routen von vielen Routern zu verwalten sind) und Protokollen, die die Routen zwischen den autonomen Systemen verteilen.

Die Protokolle innerhalb des AS heißen “Interior Gateway Protocol” (IGP) und jene für außerhalb “Exterior Gateway Protocol” (EGP). IGPs sind RIP, OSPF und IS-IS, das einzige verwendete EGP ist das Border Gateway Protocol. Innerhalb einer Firma dient also meist ein IGP für das Routing, während BGP dies zwischen den Providern und teilweise auch zwischen einem Provider und einem Unternehmen erledigt.

RIP ist das älteste IGP, die erste Version stammt von 1988, aktuell ist Version 2, die auch IPv6 via RIP-NG unterstützt. Trotzdem gilt RIP heute als veraltet und kommt kaum mehr zum Einsatz. OSPF ist dagegen eines der am häufigsten verwendeten IGPs. Es führt eine Hierarchie aus so genannten Areas ein, um das Netz zu unterteilen, wobei eine Area mehrere Netze enthalten kann. Die einstufige Hierarchie beginnt mit der Area 0, der Backbone Area. Jede weitere Area muss mit ihr über einen Router verbunden sein, auch wenn dies in der Praxis nicht physisch umgesetzt sein muss. Angepasste Konfigurationen weisen Interfaces einzelnen Areas zu.

Die Router tauschen sich dann auf den LAN-Interfaces per Multicast (auf der Multicast-IP »224.0.0.5« ) aus, optional per MD5 authentisiert. Zunächst versenden sie »HELLO« -Nachrichten, um ihre Nachbarn zu finden. Dann folgen so genannte Link State Announcements (LSA), die Informationen über die eigene Routingtabelle, Areas und die Bandbreite der Interfaces enthalten. Diese Informationen dienen gegenseitig dazu, die Routingtabellen zu aktualisieren.

Führen zwei Pfade zu einem Netz, aber ein Router ist über Gigabit- und ein anderer nur über ein 100-MBit-Netzwerk angeschlossen, greift der Pfad über den schnelleren Router. Bei gleichberechtigten Pfaden kann der Administrator manuell eine Gewichtung in die Konfiguration eintragen, die sich auch in den LSA-Informationen wiederfindet. Fällt dann eine Route aus, greift der Router fortan zum alternativen Pfad.

Dynamisches Routing

Mit BGP bekommt es der Admin meist erst dann zu tun, wenn er das eigene Netz als eigenes AS redundant ans Internet anbindet oder falls er bei einem ISP arbeitet. Ohne BGP wäre das Internet nicht funktionsfähig: Die Router des Internet-Backbone kennen keine Defaultroute, sondern nur Routen zu den Netzen aller anderen AS. Entsprechend groß sind auch die Routingtabellen (im April 2012 über 400000 Einträge).

Im Gegensatz zu OSPF muss der Admin die Verbindung zwischen zwei Routern, die per BGP Routen austauschen, explizit bei beiden Partnern konfigurieren. Dazu gehört neben der IP des Partners und den Authentisierungsinformationen auch die Nummer des eigenen AS. Führen mehrere Pfade zum Ziel, entscheidet zunächst das Gewicht, das der Admin spezifiziert hat. Linkgeschwindigkeiten wie bei OSPF spielen bei der Auswahl des Pfades allerdings keine Rolle.

Bei BGP geht es im Gegensatz zu OSPF auch nicht nur darum, den kürzesten Weg zu finden, sondern auch Routingpolicies umzusetzen, an denen Verträge und damit auch Kosten der Provider hängen. Genau darum kümmert sich unter Linux der Routingdaemon Quagga.

Quagga-Architektur

Quagga bringt mehrere Daemons mit [8]: Pro Routingprotokoll gibt es einen Dienst (bei OSPF je einen für OSPF und OSPFv6), die der Admin einzeln konfigurieren muss. Den verschiedenen Routingdaemons steht ein Masterdaemon vor, der aus historischen Gründen immer noch Zebra heißt. Jeder Daemon besitzt seine eigene Konfigurationsdatei und lässt sich auf einem eigenen Port einstellen. Der Zebra-Kontrolldaemon steuert und koordiniert das Ganze.

Die Konfiguration der einzelnen Daemons auf der Kommandozeile ist sehr an die von Ciscos IOS angelehnt. Verbindet der Administrator sich an einen der Dienste, muss er sich erst wie bei IOS mit dem »enable« Kommando authentisieren. Um Änderungen an der Konfiguration vorzunehmen, wechselt er mit der Anweisung »conf term« in den Konfigurationsmodus, den er später mit [Ctrl]+[Z] wieder verlässt. Hierarchische Konfigurationsblöcke wie Parameter für eine Schnittstelle oder eine Routerdefinition mit Hilfe von Kommandos wie »interface eth0« kann er nach der Eingabe der Parameter mit »exit« wieder verlassen.

Bis zum Reboot

In der Konfigurationsdatei, üblicherweise »/etc/quagga/zebra.conf« , landen neben den Authentisierungsdaten auch Informationen über das Logfile für alle Daemons, die Interfaces, die Quagga verwaltet (inklusive IP-Adressen, wobei dies auch die Host-Konfiguration übernehmen kann), sowie etwaige statische Routen. Achtung: Wer den Zebra-Dienstes stoppt, wird feststellen, dass von ihm gesetzte IP-Adressen bis zum nächsten Reboot Bestand haben.

Nur der Zebra-Prozess selbst kommuniziert mit dem Kernel und manipuliert die Routingtabelle des Betriebssystems. Dabei kann er – unter Linux – per Konfigurationsparameter auch eine andere als die Standard-Routingtabelle manipulieren, sodass für die von Zebra gelernten Routen erst Policy Routing (»ip rule…« ) zum Einsatz kommt und Pakete, die die Linux-Policies nicht betreffen, unberührt bleiben.

Für OSPF, OSPF6, RIP, RIP-NG, BGP und IS-IS existiert jeweils ein eigener Daemon, den der Administrator am an den Protokollnamen angehängten »d« erkennt. Jeder von ihnen ist über einen eigenen Port ansprech- und konfigurierbar, Tabelle 1 zeigt die Zuordnung. Wer Wert auf Sicherheit legt, sollte diese Dienste nur auf dem lokalen Interface (als Localhost) ansprechen, weil sich die Klartextverbindungen leicht abhören lassen, inklusive der Zugangspasswörter.

Tabelle 1

Ports der Quagga-Dienste

Dienst

Port

Zebra-Kommunikation

2600

Zebra-Administration

2601

RIP

2602

RIP-NG

2603

OSPF

2604

BGP

2605

OPSF6

2606

OSPF-API

2607

IS-IS

2608

Quagga mit OSPF: Ein einfaches Beispiel

Das Beispiel in den Listings 1, 2 und 3 schildert je eine Quagga-, OSPF- und BGP-Konfiguration für ein Linux-System, das mit Cisco-Geräten Routen austauscht. Abbildung 1 zeigt das recht einfache Netzwerksetup. Dabei simuliert die Software des Dynamips-Pakets [9] die virtuellen Cisco-Router.

Listing 1

zebra.conf für OSPF

01 !
02 hostname linuxrouter
03 password 8 7kdoaul4.iSTg
04 enable password 8 ZDF339a.20a3E
05 log file /var/log/quagga/zebra.log
06 service password-encryption
07 !
08 interface eth0
09  multicast
10  ipv6 nd suppress-ra
11 !
12 interface eth1
13  ip address 10.55.55.1/24
14  ipv6 nd suppress-ra
Abbildung 1: Das Beispielnetzwerk besteht aus zwei Linux-Clients, drei per Software simulierten Cisco-Routern und dem Linux-Server mit Quagga.

Abbildung 1: Das Beispielnetzwerk besteht aus zwei Linux-Clients, drei per Software simulierten Cisco-Routern und dem Linux-Server mit Quagga.

Im Beispielnetzwerk führen zwei Pfade aus dem Netz »1.2.3.0/24« auf der linken Seite in das Netz »172.16.1.0/24« auf der rechten. Weil Dynamips nicht mit zwei Routern am selben LAN-Segment des Hostrechners zurechtkommt, mussten die Tester zwei verschiedene LAN-Segmente einrichten. Die Konfiguration mit nur einem Segment unterscheidet sich aber nur in den Netzadressen.

Für das Interface »eth1« des Quagga-Routers setzt Zebra die IP-Adresse. Ansonsten reicht es, auf den Interfaces, die OSPF sprechen sollen, Multicast zu aktivieren, im Beispiel nur für »eth0« . Die Einstellung »ipv6 nd supress-ra« sorgt dafür, dass »zebra« keine Routing-Advertisements losschickt, ohne dass der Admin dies explizit aktiviert. Der relevante Teil der Konfiguration findet sich in »ospfd.conf« (Listing 2).

Listing 2

ospfd.conf

01 !
02 hostname ospfd
03 password zebra
04 enable password secret
05 !
06 interface eth0
07  ip ospf message-digest-key 1 md5 hallo123
08 interface eth3
09  ip ospf message-digest-key 1 md5 hallo123
10 !
11 !
12 router ospf
13  redistribute connected
14  network 172.16.1.0/24 area 0.0.0.0
15  network 172.17.0.0/16 area 0.0.0.0
16  network 192.168.1.0/24 area 0.0.0.0
17  network 192.168.2.0/24 area 0.0.0.0
18  network 192.168.40.0/24 area 0.0.0.0
19  area 0.0.0.0 authentication message-digest

Die Anweisungen unterhalb der Interfaces setzen das Passwort, das die Multicast-Pakete authentisiert. Die Definition des OSPF-Routingprozesses spezifiziert zunächst, welche dem Router bekannten Routen er per OSPF weiterverteilen soll. Die Anweisung »redistribute connected« verteilt alle Routen der Interfaces des Rechners und auch jene, auf denen kein OSPF stattfindet. »redistribute kernel« verteilt Routen, die das Betriebssystem manuell erhalten hat, »redistribute static« solche aus der Datei »zebra.conf« .

Das Zuweisen von Interfaces zu OSPF-Areas muss der Admin selbst erledigen. Dabei reicht es, dass jeweils ein Router eine Zuordnung kennt. Hier unterscheidet sich die Syntax im Vergleich zu der eines IOS-Geräts in der Angabe des Netzblocks: »A.B.C.D/X« statt der Cisco-Syntax mit invertierter Netzmaske, also etwa »192.168.1.0 0.0.0.255« und »0.0.0.0« für die Area statt einfach »« . Die letzte Anweisung definiert noch, dass für Area 0 nur authentisierte Informationen erlaubt sein sollen.

Mit dem Kommando »sh ip route« am Zebra-Prompt lässt sich der Administrator die gelernten und eigenen Routen anzeigen, dabei signalisiert ein »O« am Anfang, dass die Route per OSPF im Router landete. Am Linux-Prompt zeigt »proto zebra« an, dass die Route über Zebra ihren Weg in den Kernel fand. Allerdings erfährt der Administrator hier nicht, welches Routingprotokoll Zebra die Route beigebracht hat.

Bricht jetzt ein Link weg, ohne dass der Router es selbst bemerken kann, zum Beispiel weil der Ethernet-Link weg ist, dann dauert es drei OSPF-Hello-Intervalle, bis die Netze wieder verbunden sind. Die Abbildungen 2 und 3 zeigen ein Ping und die resultierende Ausfallzeit. Anders verhält es sich jedoch, wenn ein Router dem Rest des Verbunds noch mitteilen kann, dass ein Bein nicht mehr funktioniert, weil etwa ein Switch ausgefallen ist oder die legendäre Putzfrau ein Kabel gezogen hat. Weil hier der Router durch den Link-Ausfall mitbekommt, dass ein Fehler vorliegt, ist die Ausfallzeit mit Ping nicht messbar (Abbildung 4).

Abbildung 2: Die Verbindung reisst ab, es dauert ein wenig …

Abbildung 2: Die Verbindung reisst ab, es dauert ein wenig …

Abbildung 3: … bis der Quagga-Router das bemerkt, aber schon nach 36 Paketen hat er die Route umgestellt.

Abbildung 3: … bis der Quagga-Router das bemerkt, aber schon nach 36 Paketen hat er die Route umgestellt.

Abbildung 4: Nicht messbar ist die Ausfallzeit, wenn der Quagga-Router den Link-Ausfall bemerkt und sofort reagieren kann.

Abbildung 4: Nicht messbar ist die Ausfallzeit, wenn der Quagga-Router den Link-Ausfall bemerkt und sofort reagieren kann.

Die Ausfallzeiten lassen sich verringern, indem der Administrator die Frequenz der OSPF-Nachrichten erhöht, dabei muss er jedoch für jedes Szenario das richtige Gleichgewicht suchen.

BGP-Routing für autonome Systeme

BGP steuert die Verbindung zwischen autonomen Systemen, die durch ihre Nummer gekennzeichnet sind. Im Beispiel sind alle Router auf der linken Seite im AS 64515, der Linux-Router im AS 64513. Die unspektakuläre Konfiguration in der Datei »bgpd.conf« zeigt Listing 3. Nach dem Setzen des Hostnamens und der Passwörter zum Anmelden und für den privilegierten Modus definiert »router« den BGP-Router und die Nummer des eigenen AS. Die folgende Router-ID ist eine der Interface-Adressen des Routers. Die »redistribute« -Anweisungen geben an, welche Routen der Server per BGP an die Partner verteilen soll. Dann folgen die Definitionen der beiden Partner, mindestens mit dem AS der anderen Seite sowie dem Passwort zur Authentisierung dieser Verbindung.

Listing 3

bgpd.conf

01 !
02 hostname bgpd
03 password zebra
04 enable password zebra
05 log stdout
06 !
07 router bgp 64513
08  bgp router-id 192.168.1.253
09  redistribute kernel
10  redistribute connected
11  neighbor 192.168.1.200 remote-as 64515
12  neighbor 192.168.1.200 password test123
13  neighbor 192.168.40.253 remote-as 64515
14  neighbor 192.168.40.253 password test123

Der Router versucht sofort, die Verbindungen aufzubauen und die Routen auszutauschen. Auch ein Failover funktioniert jetzt bereits, beim Ausfall eines Routers kann es in dieser einfachen Konfiguration allerdings schon etwas länger dauern (Abbildungen 5 und 6).

Abbildung 5: Im simplen BGP-Beispiel aus <link href="#article_l3" class="listing" srcset=

Listing 3 dauert es …” width=”300″ height=”42″ /> Abbildung 5: Im simplen BGP-Beispiel aus Listing 3 dauert es …

Abbildung 6: … stattliche 145 Sekunden, bis ein Failover gelingt.

Abbildung 6: … stattliche 145 Sekunden, bis ein Failover gelingt.

Karten für den Pfadfinder: Routemaps

Routemaps dienen zur Steuerung, über welches Protokoll der Dienst welche Routinginformationen verteilen soll. Nebenbei darf der Administrator noch Werte wie die Präferenz der Routen manipulieren, zum Beispiel über den Metric-Wert.So kann er mit Routemaps auch Vorgaben umsetzen wie “Exportiere alle Routen, die du per OSPF gelernt hast, nach BGP, außer denen, die auf Netze unterhalb von 172.16.0.0/16 zeigen” oder “Exportiere aller per BGP gelernten Routen nach OSPF, aber mit einer niedrigeren Präferenz”.

So könnten bei Überschneidungen immer die lokalen, im LAN per OSPF gelernten Routen den Vorrang haben. Erst wenn kein anderer Weg mehr möglich ist, würde der Router den langsameren oder teureren externen Pfad verfolgen. Die Modelle sind beliebig erweiterbar, in komplexeren Umgebungen führen Routemaps mit vielen Regeln aber sehr schnell zu so umfangreichen Konstruktionen, dass vorausschauende Admins sie nur mit äußerster Vorsicht anfassen.

Routemaps muss der Admin in die Konfigurationsdatei des Routingprozesses eintragen, auf den sie Einfluss nehmen sollen. Geht es um den Import von BGP nach OSPF, dann wäre das »ospfd.conf« . Wer beispielsweise den Export aller Routen unterhalb von »172.17.1.0/24« von BGP nach OSPF unterdrücken will, greift zu den Zeilen in Listing 4.

Listing 4

ospfd_routemap.conf

01 !
02 router ospf
03  redistribute connected
04  redistribute bgp route-map bgp-to-ospf
05 [...]
06
07 ip prefix-list into-ospf seq 5 permit 172.17.1.0/24 le 32
08 ip prefix-list into-ospf seq 10 deny 0.0.0.0/0 le 32
09 !
10 route-map bgp-to-ospf deny 5
11  match ip address into-ospf
12 !
13 route-map bgp-to-ospf permit 10

Innerhalb der OSPF-Konfiguration stellt die Anweisung zum Weiterverteilen der BGP-Routen in »route-map bgp-to-ospf« den Bezug zur Routemap »bgp-to-ospf« her (sie wird weiter unten in diesem Artikel definiert).

Nicht immer logisch

Da das Beispiel die Routen aufgrund eines IP-Präfixes filtert, muss der Admin dieses zunächst definieren. Das gelingt ihm aber nur, wenn er sein Gespür für Logik hintanstellt. Hilfreich ist es, sich an allen Stellen, an denen »permit« steht, ein »true« und für »deny« ein »false« zu denken. Auch die IP-Präfixlisten haben Namen und eine Reihenfolge, in der das System sie von oben nach unten abarbeitet wie etwa bei Netfilter-Firewallregeln. Die Zeilen 7 und 8 (Listing 4) besagen, dass das IP-Präfix »172.17.1.0/24« zur Liste gehört, alle Adressen von »0.0.0.0« bis »255.255.255.255« dagegen nicht. Die Schreibweise »le 32« nennt ausgehend vom Startwert (hier »0.0.0.0« ) die maximale Bit-Menge für den Bereich.

Nun folgt die Definition der eigentlichen Routemap. Die Zeile 10 verhindert das Verteilen aller nicht genauer spezifizierten Routen (»deny« ). Zeile 11 gibt die Bedingung an, unter der dieser Eintrag Anwendung findet, und bezieht sich auf die IP-Präfixliste. Modellhaft ausgedrückt: Wenn die IP-Adresse auf die Präfixliste mit dem Namen »into-ospf« passt, dann gilt diese Regel! Die letzte Zeile der Konfiguration erlaubt in dieser Routemap alle Routen, da keine Bedingung an sie geknüpft ist.

Schon dieses einfache Beispiel zeigt, wie leicht es mit den vielen Präfixlisten und der doppelten Logik zu Verwirrungen kommt – sich dabei in komplexen Szenarien nicht zu verlaufen erfordert einen richtig guten Pfadfinder.

Die Konfiguration bei IPv6 unterscheidet sich nicht wesentlich von der für IPv4. An den Stellen, an denen in der Konfiguration »ip« eingetragen ist, steht bei Quagga »ipv6« . Hier unterscheidet sich die Konfiguration von Cisco, die »ip6« verwendet. Für OSPFv6 findet die Konfiguration in einer eigenen Datei statt und bedient einen eigenen Daemon. Bei BGP erledigt dies derselbe Daemon wie für IPv4. Es ist sogar möglich, IPv4-Routen an einen IPv6-Peer zu verteilen und umgekehrt. Für den ersten Fall vergibt der Admin einfach bei der »neighbor« -Definition eine IPv6-Adresse.

Den Peer für IPv6 aktiviert das Kommando »address-family ipv6« gefolgt von »neighbor w.x.y.z activate« . Jetzt gelangen alle Routen (IPv4 und IPv6) zum Peer. Wer nur IPv6-Routen verteilen will, muss dafür eine eigene Routemap bauen, deren erster Term ein »permit« für alle IPv6-Adressen erlaubt (»ipv6 accesslist allv6 permit any« ) und deren zweiter Term ein »deny« für alle IPv4-Adressen liefert (»access-list nov4 deny any« ). Das logischer erscheinende »no activate neighbor x.x.x.x« in der IPv4-Konfiguration führte im Test nur dazu, dass Quagga gar keine Routen mehr an seine Partner verteilte.

Fazit

Einen High-End-Router mit mehreren 10-GBit-Interfaces kann ein Linux-Rechner vermutlich nicht ersetzten. Auf der anderen Seite sind die Preise für Router, die genug Speicher haben, um Hunderttausende von Routen für Full BGP zu verarbeiten, so astronomisch hoch, dass PC-Hardware zumindest die preisgünstigere Alternative darstellt.

Wer sich bereits mit der Syntax von Cisco-Systemen auskennt, findet sich auch in Quagga schnell zurecht. Trotzdem ist es im Vergleich ungewohnt, für jedes Routingprotokoll wieder eine neue Session zu starten. Auch gibt es ein paar subtile Unterschiede im Verhalten zu IOS, die sich aber auch zwischen verschiedenen IOS-Versionen finden.

Im Ganzen kommt man mit Quagga relativ weit, es lassen sich Redundanzen schaffen und Linux-Router auch in größerer Anzahl durch den Einsatz dynamischer Routingprotokolle übersichtlich verwalten. Und angesichts dessen, was Quagga noch alles möglich macht, um IP-Pakete von A nach B zu bringen, kratzen die genannten Beispiele nur an der Oberfläche. Erfahrenen Pfadfindern öffnen sich dann so manche noch unbekannten Wege, zum Beispiel Quagga via SNMP-Traps ans Monitoring anzuschließen oder das Zebra-Protokoll im Detail zu analysieren [10].

Der Autor

Konstantin Agouros arbeitet bei der N.runs AG als Berater für Netzwerksicherheit. Dabei liegt sein Schwerpunkt im Bereich Telekommunikationsanbieter. Sein Buch “DNS/DHCP” ist bei Open Source Press erschienen.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 5 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Nach oben