GRE Tunnel Keepalives

Ich durfte mich jetzt etwas mit GRE Tunneln beschäftigen und mit dem Keepalive Mechanismus der darin steckt.

GRE Tunnel sind erstmal nichts besonderes, sie tunneln in IP durch ein Netz in dem sich Quelle und Ziel erreichen können, ohne Verschlüsselung. Wenn man sie verschlüsseln möchte muss man zusätzlich IPSec machen, war bei mir aber nicht so.

GRE Tunnel funktionieren so, dass sie das Datenpaket mit einem GRE Header versehen und diese beiden dann in ein IP Unicast Packet einpacken, also einen IP Header voran stellen. Dieser wird am Ziel wieder entfernt, der GRE Header entfernt und das innere Paket wieder normal weiter versendet. Nix besonderes erstmal.

Das besondere ist, dass GRE Tunnel Interfaces immer in Status Up/Up sind wenn man sie einschaltet. Egal ob sie ihr Gegenüber, den anderen Tunnelendpunkt, erreichen können oder nicht. Das führt natürlich dazu, dass Blackholes entstehen sobald der Tunnelendpunkt nicht erreicht werden kann. Denn das Routing am Tunnelanfang läuft weiterhin in den Tunnel der ja Up/Up ist.

Was tut man dagegen? Man nutzt die Keepalives. Keine Frage, oder?

Naja doch, die haben so ihre eigenheiten. Wie funktionieren GRE Keepalives?

Zuerst, was bewirken Keepalives? Das Problem das Keepalives lösen ist, dass der Tunnel immer Up/Up ist. Wenn man Keepalives einsetzt, wird das Link Protocol nur auf Up gesetzt, wenn der Keepalive funktioniert! Also wenn der Keepalive nicht klappt, ist der Tunnel Up/Down. Was wir ja auch erreichen wollen, wenn der Tunnel nicht funktionert soll er Down gehen.

GRE Keepalives erzeugen ein Paket mit der Quell IP des gegenüberliegenden Tunnelendpunkts und der Ziel IP der eigenen Tunnel Quell-IP. Quasi die Pakete die vom Gegenüber zu einem selbst geschickt werden. Diese Pakete werden in GRE eingepackt und durch den Tunnel versendet. Der Tunnelendpunkt, packt sie aus und routet sie normal weiter. Das heißt, er schickt das Keepalive Paket, dieses Mal nicht in GRE eingepackt, zum ursprünglichen Router zurück. Sobald der das Paket erhält, weiß er dass die Tunnel kommunikation funktioniert, da das Paket im Tunnel beim Gegenüber ankam und der es außerhalb des Tunnels wieder zu ihm geschickt hat. Somit ist sichergestellt, dass das Gegenüber seinen Tunnel auch zu ihm schicken kann, da er ja das Paket bekommen hat.

Also sagen wir, Tunnel Endpunkt 1 hat die externe IP 1.1.1.1 und im Tunnel die IP 10.10.10.1 und Endpunkt 2 hat die externe IP 2.2.2.2 und im Tunnel die IP 10.10.10.2.

Wenn Endpunkt 1 nun ein Keepalive schickt, erzeugt er ein Paket mit Quelle 2.2.2.2 an Ziel 1.1.1.1, packet es in GRE ein und schickt es durch den Tunnel an 10.10.10.2. Das heißt also, im äußeren Header steht die Quell IP 1.1.1.1 und die Ziel IP 2.2.2.2. Endpunkt 2 packt das Paket aus GRE aus, schaut sich das Ziel an und sendet das Paket zurück zu Endpunkt 1. Warum? Weil das innere Paket als Ziel die 1.1.1.1 hat. Die IP von der der GRE Tunnel terminiert.

Cisco hat extra Seiten die GRE Keepalives erklären:

Allgemeine Seite zu GRE Keepalives: https://www.cisco.com/c/en/us/support/docs/ip/generic-routing-encapsulation-gre/118370-technote-gre-00.html

How GRE Keepalives work: https://www.cisco.com/c/en/us/support/docs/ip/generic-routing-encapsulation-gre/63760-gre-keepalives-63760.html

Ich hatte jetzt aber leider noch NAT vor einem der Endpunkte des GRE Tunnels, das heißt der äußere Header des GRE Tunnels wird geNATet. In diesem Fall ist die IP des Endpunkts 1 die 172.16.0.1, die wird dann auf eine externe IP geNATet, 1.2.3.4, und weitergeleitet. Warum is das nun ein Problem? Das NAT sorgt doch dafür, dass alles so ankommt wie es soll, oder?

Ja und Nein. Für den GRE Tunnel ist alles Ok, die einzige Änderung ist auf Endpunkt 2. Dort muss man als Tunnel Destination die Public IP, 1.2.3.4, nehmen statt der internen IP 172.16.0.1. Die IPs des Tunnels bleiben gleich, 10.10.10.1 und 10.10.10.2.

Der Tunnel funktioniet und alles ist gut, bis auf die Keepalives.

Die Keepalives des Routers dessen Adresse geNATet wird, in diesem Fall Endpunkt 1, werden nicht mehr funktionieren. Da Endpunkt 1, im Keepalive Paket die eigene Quell IP, 172.16.0.1, einträgt, kann Endpunkt 2, der sich z.B. irgendwo im Internet befindet, die Keepalive Pakete nicht mehr an ihn zurückschicken. Er hat keine Route zu 172.16.0.1. Er müsste die Pakete an 1.2.3.4 senden, die Public IP von Endpunkt 1. Warum macht er das nicht, wir haben doch NAT?

Bei NAT wird die Adresse im äußeren Header ersetzt, deswegen funktioniert der Tunnel. Aber die Adresse im inneren Header, der Header des Keepalives, wird nicht ersetzt. Somit bleibt dort die private IP erhalten und der Keepalive funktioniert nicht mehr.

Ich habe bis jetzt keine Lösung um den Keepalive wieder ins Leben zurufen gefunden. Endpunkt 1 müsste eigentlich nur die public IP einsetzen statt der privaten IP, das scheint aber nicht möglich zu sein. Daher muss man sich anders behelfen.

Aktuell nutze ich jetzt einen IP SLA der die Erreichbarkeit von Zielen testet die nur durch den Tunnel erreichbar sind, wenn dieser IP SLA Ok ist, werden die Routen durch den Tunnel gesetzt, ansonsten nicht. Somit ist sichergestellt, dass der Tunnel nur in Verwendung ist, wenn er funktioniert. Wenn nicht, haben wir noch Backup Tunnel und Wege die ebenfalls dorthin gehen. Somit funktioniert alles inkl. redundanter Wege und automatischem Failover.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.