IP default route bei Verbindungsproblemen automatisch ändern

Andy_m4

Well-Known Member
Problem:
Deine Internetverbindung die manchmal etwas wackelig ist und dann auch mal längere Zeit (Stunden) nicht da ist. Als "Backup" gibts dann eine Mobilfunkverbindung die aber bandbreitenmäßig nicht ganz so gut ist.
Wenn jetzt die Hauptinternet-Verbindung ausfällt, dann ändere ich halt einfach die Default-Route auf die Backup-Verbindung und damit tut es dann auch erst mal wieder.

Der Wunsch ist, das ein bisschen zu automatisieren. Also wenn die Haupt-Internetverbindung weg ist die default-route auf die Backup-Verbindung zu legen und sobald die Haupt-Internetverbindung wieder da ist, halt wieder dahin zurückzuswitchen.
Also quasi so ein bisschen das was Link Aggregation/Failover bietet, aber halt nicht auf Network-Interface-Ebene sondern quasi auf IP-Ebene.

Evtl. hätte jemand eine Idee dazu, wie man das angehen könnte. Meine spontane Idee war einfach ein Skript zu schreiben, was ein ping (z.B. nach 8.8.8.8) absetzt und wenn das fehlschlägt dann hat mit route die default route zu ändern.
Das Problem ist, wenn die Backup-Route aktiv ist kann ich ja mit einem ping nicht mehr so ohne Weiteres die Hauptinternetverbindung testen.
Das Problem könnte man damit lösen, das man für die "Prüf-IP" (also hier im Beispiel halt die 8.8.8.8) halt das Gateway der Hauptinternetverbindung fest einträgt.

Aber vielleicht hat jemand von euch noch eine andere/bessere Idee.

Mir ist bewusst, das die Art der Problemlösung (also einfach default-route ändern) etwas "hacky" ist, aber ich denke für den Anwendungsfall den ich hier hab reicht das völlig aus.
 
Das Problem könnte man damit lösen, das man für die "Prüf-IP" (also hier im Beispiel halt die 8.8.8.8) halt das Gateway der Hauptinternetverbindung fest einträgt.
Das wäre nutzlos, denn ich erreiche im W/LAN das Gateway (d. h. den Router) meiner Hauptinternetverbindung immer, d. h. auch dann wenn dieser mal keine Internetverbindung hat.
 
Das wäre nutzlos, denn ich erreiche im W/LAN das Gateway (d. h. den Router) meiner Hauptinternetverbindung immer,
Genau deshalb will ich ja sowas wie 8.8.8.8 anpingen.

Die Struktur ist so:
Es gibt ein Router/Modem mit der IP-Adresse 192.168.0.1 welches quasi das Gateway für die Haupt-Internetverbindung ist.
Es gibt ein Router/Modem mit der IP-Adresse 192.168.0.2 welches das Gateway für die Backup-Internetverbindung ist.
Es gibt ein Router mit der Adresse 192.168.0.3 welcher normalerweise als default route den 192.168.0.1 eingetragen hat.
Alle Clients im LAN haben als default gateway 192.168.0.3

Wenn jetzt die Haupt-Internetverbindung weg geht, dann soll beim 192.168.0.3er Router als default gateway 192.168.0.2
Wenn der 192.168.0.1er-Router wieder Internet hat, dann soll beim 192.168.0.3er Router als default gateway wieder 192.168.0.1 stehen.

Die Idee war im 192.168.0.3er Router ne statische Route für die Prüf-IP-Adresse anzulegen so a-la:
route add -host 8.8.8.8 192.168.0.1
Wenn ich jetzt also 8.8.8.8 anpinge, geht das immer über Gateway 192.168.0.1
Schlägt das fehl und das default gateway ist 192.168.0.1, dann -> route change default 192.168.0.2
Schlägt das nicht fehl und das default gateway ist ungleich 192.168.0.1, dann -> route change default 192.168.0.1
 
Die Idee war im 192.168.0.3er Router ne statische Route für die Prüf-IP-Adresse anzulegen so a-la:
route add -host 8.8.8.8 192.168.0.1
Wenn ich jetzt also 8.8.8.8 anpinge, geht das immer über Gateway 192.168.0.1
Schlägt das fehl und das default gateway ist 192.168.0.1, dann -> route change default 192.168.0.2
Schlägt das nicht fehl und das default gateway ist ungleich 192.168.0.1, dann -> route change default 192.168.0.1
Ja, das könne man machen. In welchem Zeitabstand willst Du die Pings (icmp) machen? Evtl. wäre ein tcp-ping zuverlässiger als ein icmp-ping.
 
In welchem Zeitabstand willst Du die Pings (icmp) machen?
Nicht zu kurz hintereinander. Im Prinzip reicht sowas wie alle 10 Sekunden oder von mir aus alle halbe Minute. Die Verbindungsabbrüche sind ja eher sporadisch. Und wenn dann mal "das Internet hängt" ist das auch nicht dramatisch.

Evtl. wäre ein tcp-ping zuverlässiger als ein icmp-ping.
Ja. Könnte man drüber nachdenken.
 
Spontan würde ich sagen, mach 2 default routes mit unterschiedlichen metrics. Allerdings konnte das FreeBSD zumindest früher nicht, wie der stand heute ist weiß ich nicht, schon seit 2 Releases nicht mehr damit beschäftigt. Vielleicht weiß da jemand was dazu?

Falls das immer noch nicht möglich ist: Du kannst mehrere Routingtables definieren (fib / setfib). Z.b. könntest du dann dein Ping Script immer in einem Routingtable ausführen der deine Kabelverbindung nutzt und könntest auf dem default routingtable dann die default route switchen.

Das aber nur als Denkrichtung, ich hab damit selbst noch nichts gemacht.
 
hi

unter OpenBSD gibt es ifstated , mit dem sollteste so ein scenario
umsetzen koennen.


Holger
Unter FreeBSD gibt es ifstated in den ports.

 
Aber vielleicht hat jemand von euch noch eine andere/bessere Idee.
OPNsense dazwischenschalten, das hat das onboard mit dpinger bzw. davon abkupfern:
https://github.com/opnsense/core/bl...mvc/app/library/OPNsense/Routing/Gateways.php

Als Pingziel (10sec-Intervall ist prima) eignet sich auch der GW/DNS vom jeweiligen ISP der Leitung. (Ein Client könnte nicht zum Ziel kommen, wenn der auch zuf. auf 8.8.8.8 will und die damit überwachte Strecke gerade tot ist)
 
Ich steh momentan auch vor dem Problem (Allerdings mit OpenBSD) - momentan schalte ich manuell um da ich noch keine Zeit hatte da etwas zu basteln. Es geht hier um unseren reinen privaten 3-personen-wg-anschluss.

(Mainweg ist bei mir ein Glasfaser-Medienconverter, Backupweg ein DSL-Anschluss an einer Fritzbox)

Grundsätzlich ist das Problem, das man halt maximal "ziele" in lokalen Netzwerken oder auf der default-route prüfen kann. Möchte man wie von dir geschildert ausgefallene Leitungen hinter einem Router oder auch Szenarien in denen das Gateway des ISP noch erreichbar ist aber nichts dahinter abdecken, wird die sache komplexer.

Ich hatte mir folgende 3 Lösungen bislang überlegt aber noch keine ausprobiert:

1. Ping, bei ausfall auf den Backupweg schwenken und danach testweise rückschwenken "bis es geht"

-> Wenn der Mainlink ausfällt (prüfen durch ping auf 2 unterschiedliche externe ip-addressen, gehen beide nicht -> schwenk auf das Backup-DSL, eintrag mit date in einer Datei
-> Danach zb stündlich (evtl. nur nachts?) schwenk wieder auf den Mainlink, danach testen per ping obs wieder geht. Wenns nicht geht -> Schwenk zurück auf den Backupweg
-> Solange bis es wieder geht.

Vorteil: Technisch sehr einfach, nen paar zeilen shell-script
Nachteil: Kurzer Ausfall beim "prüfen" der Leitung

2) Ping, bei Ausfall auf den Backupweg schwenken und danach den Mainweg weiter prüfen

-> Hier muss ich eine Lösung finden wie ich den Mainweg prüfen kann obwohl die default-route auf die Fritzbox des Backupweges läuft.

Idee 1: Mit rdomains / routing domains hier arbeiten - hab ich mich noch nicht mit beschäftigt

Idee 2: Mit ner vm arbeiten. Diese "übernimmt" bei Ausfall das Interface des Mainwegs, prüft permanent ob es wieder funktioniert und gibt dann an den host ne Info zurückzuschwenken.

(In allen 3 Szenarien würde auch noch ein Test laufen ob der Backupweg evtl. auch ausgefallen ist und bei ausfall Backup auch nen rückschwenk auf main erfolgen)
 
Ich steh momentan auch vor dem Problem (Allerdings mit OpenBSD) - momentan schalte ich manuell um da ich noch keine Zeit hatte da etwas zu basteln. Es geht hier um unseren reinen privaten 3-personen-wg-anschluss.

(Mainweg ist bei mir ein Glasfaser-Medienconverter, Backupweg ein DSL-Anschluss an einer Fritzbox)

Grundsätzlich ist das Problem, das man halt maximal "ziele" in lokalen Netzwerken oder auf der default-route prüfen kann. Möchte man wie von dir geschildert ausgefallene Leitungen hinter einem Router oder auch Szenarien in denen das Gateway des ISP noch erreichbar ist aber nichts dahinter abdecken, wird die sache komplexer.

Ich hatte mir folgende 3 Lösungen bislang überlegt aber noch keine ausprobiert:

1. Ping, bei ausfall auf den Backupweg schwenken und danach testweise rückschwenken "bis es geht"

-> Wenn der Mainlink ausfällt (prüfen durch ping auf 2 unterschiedliche externe ip-addressen, gehen beide nicht -> schwenk auf das Backup-DSL, eintrag mit date in einer Datei
-> Danach zb stündlich (evtl. nur nachts?) schwenk wieder auf den Mainlink, danach testen per ping obs wieder geht. Wenns nicht geht -> Schwenk zurück auf den Backupweg
-> Solange bis es wieder geht.

Vorteil: Technisch sehr einfach, nen paar zeilen shell-script
Nachteil: Kurzer Ausfall beim "prüfen" der Leitung

2) Ping, bei Ausfall auf den Backupweg schwenken und danach den Mainweg weiter prüfen

-> Hier muss ich eine Lösung finden wie ich den Mainweg prüfen kann obwohl die default-route auf die Fritzbox des Backupweges läuft.

Idee 1: Mit rdomains / routing domains hier arbeiten - hab ich mich noch nicht mit beschäftigt

Idee 2: Mit ner vm arbeiten. Diese "übernimmt" bei Ausfall das Interface des Mainwegs, prüft permanent ob es wieder funktioniert und gibt dann an den host ne Info zurückzuschwenken.

(In allen 3 Szenarien würde auch noch ein Test laufen ob der Backupweg evtl. auch ausgefallen ist und bei ausfall Backup auch nen rückschwenk auf main erfolgen)
Unter OpenBSD koennte auch Multipath funktionieren.

 
Das Problem ist, wenn die Backup-Route aktiv ist kann ich ja mit einem ping nicht mehr so ohne Weiteres die Hauptinternetverbindung testen.
Mit Policy Routing lässt sich diese Problematik elegant lösen.

Einstieg ins Policy Routing generell bietet (=> Routing-Tag-Angaben beachten!!):

Einstieg zum Policy Routing unter Linux bietet:


Linux unterstützt sogar für jede Anwendung/Programm eine unterschiedliche Routingtabelle. Linux namespaces sei Dank (siehe # man namespaces(7) ). Siehe dazu:

Wie Policy Routing unter FreeBSD konfiguriert wird, ist mir nicht bekannt. Anwendungsbasierte Routingtabellen wird wahrscheinlich von FreeBSD nicht unterstützt. Für Policy Routing unter FreeBSD ist der Hinweis von medV2 zu beachten.
 
hi

wie schon gesagt ifstated ist hier eine gute option da man sich das ding so configurieren kannt wie man es
haben möchte , incl ping überwachung etc.

mpath , funktioniert ja , jedoch sollte man hier auf jedenfall ein monitoring einbauen ,da der kernel nicht erkennt
ob die leitung auch funktioniert , und schon sind wir wieder bei ifstated


Holger
 
Unter OpenBSD koennte auch Multipath funktionieren.


Ich glaube nicht dort steht das exakt gleiche Problem geschildert:

It's worth noting that if an interface used by a multipath route goes down (i.e., loses carrier), the kernel will still try to forward packets using the route that points to that interface. This traffic will of course be blackholed and end up going nowhere. It's highly recommended to use ifstated(8) to check for unavailable interfaces and adjust the routing table accordingly.

hi

wie schon gesagt ifstated ist hier eine gute option da man sich das ding so configurieren kannt wie man es
haben möchte , incl ping überwachung etc.

mpath , funktioniert ja , jedoch sollte man hier auf jedenfall ein monitoring einbauen ,da der kernel nicht erkennt
ob die leitung auch funktioniert , und schon sind wir wieder bei ifstated


Holger


Bei ifstated steht garnichts davon das es irgendetwas macht von dem was wir brauchen, sondern maximal ne vorhandene Verbindung prüfen kann oder ob nen if up/down ist.

Mit Policy Routing lässt sich diese Problematik elegant lösen.

Alles was du da aufzählst ist sehr interessant hat aber mit der Problematik wenn man auf der Backupleitung ist zu erkennen das die Verbindung wieder da ist und man die default-route ändern müsste um eben dieses festzustellen unter *BSD nur wenig zu tun.

Linux Namespaces bietet so grob das was unter OpenBSD die von mir erwähnten Routing Domains ermöglichen.
 
DESCRIPTION
The ifstated daemon runs commands in response to network state changes,
which it determines by monitoring interface link state or running
external tests. For example, it can be used with carp(4) to change
running services or to ensure that carp(4) interfaces stay in sync, or
with pf(4) to test server or link availability and modify translation or
routing rules. The options are as follows:
aus man 8 ifstated ( OpenBSD )

in kombination mit mpath , den befehlren ping und route kann man mit ifstated genau
die situation herstellen , ein automatisch umschalten der default route bei
ausfall oder störung einer netzwerk / internet verbindung.

siehe auch
man ifstated.conf

Holger
 
aus man 8 ifstated ( OpenBSD )

in kombination mit mpath , den befehlren ping und route kann man mit ifstated genau
die situation herstellen , ein automatisch umschalten der default route bei
ausfall oder störung einer netzwerk / internet verbindung.

siehe auch
man ifstated.conf

Holger

ja aber genau das suchen wir ja gerade NICHT - das haben wir doch nun alle schon 4x geschrieben.

Der Schwenk der default-route auf dem Backupweg ist kein Problem.

Wir wollen herausfinden OHNE die default-route zu ändern ob der Primärweg wieder funktioniert bevor wir wieder zurück schwenken.

Und das ohne zu schauen ob das Interface up/down ist oder ne IP-Addresse hat.

Sondern tatsächlich ein ICMP-Paket über die Leitung schicken die NICHT in der Default-Route ist, schauen ob da etwas zurück kommt und DANN auf die Leitung schwenken.

Und das ist wenn man nicht irgend nen HA-Protokoll auf der "beiden" Seiten fährt (zb weils wie bei mir Consumer-Grade Leitungen sind von verschiedenen anbietern) garnicht so super einfach.

(Hat man zugriff würde man CARP zb verwenden oder hsrp bei Cisco)
 
Mit Policy-Routing respektive "Anwendungsbedingte Routingtabellen" drei Routingtabellen erstellen:

  • Standard-Routingtabelle für alle üblichen Anwendungen und Netzwerkteilnehmern.
  • Hauptleitungs-Routingtabelle nur für das ICMP-Polling der Hauptleitung (Leitungskontrolle mit Ping)
  • Backupleitungs-Routingtabelle nur für das ICMP-Polling der Backupleitung (Leitungskontrolle mit Ping)

Defaultroute der Standard-Routingtabelle: Gateway der Hauptleitung oder Gateway der Backupleitung => Umschaltbar durch Leitungskontrolle!
Defaultroute der Hauptleitungs-Routingtabelle: IMMER Gateway der Hauptleitung
Defaultroute der Backupleitung-Routingtabelle: IMMER Gateway der Backupleitung
 
Mit Policy-Routing respektive "Anwendungsbedingte Routingtabellen" drei Routingtabellen erstellen:

  • Standard-Routingtabelle für alle üblichen Anwendungen und Netzwerkteilnehmern.
  • Hauptleitungs-Routingtabelle nur für das ICMP-Polling der Hauptleitung (Leitungskontrolle mit Ping)
  • Backupleitungs-Routingtabelle nur für das ICMP-Polling der Backupleitung (Leitungskontrolle mit Ping)

Defaultroute der Standard-Routingtabelle: Gateway der Hauptleitung oder Gateway der Backupleitung => Umschaltbar durch Leitungskontrolle!
Defaultroute der Hauptleitungs-Routingtabelle: IMMER Gateway der Hauptleitung
Defaultroute der Backupleitung-Routingtabelle: IMMER Gateway der Backupleitung
So ähnlich stell ich mir das auch mit openbsds rdomains vor.

Villeicht frag ich auch einfach mal ganz neutral auf @misc
 
Ich habe eine ähnliche Problematik nur eben nicht mit der Internet- sondern mit einigen VPN-Verbindungen, die zwar auf beiden Seiten "offiziell" noch bestehen, aber keine Pakete mehr darüber laufen. Behelfsweise habe ich das erstmal über dpinger gelöst, was ein Script dann entweder mit Parameter 1 oder 0 ausführt...
 
Für ordentliche VPN-Tunneln verwendet man nach Möglichkeit IKEv2/IPSec. IKEv2 unterstützt "Dead Peer Detection" (DPD).

Jeder korrekt konfigurierte VPN-Endpunkt kontrolliert die Erreichbarkeit des anderen VPN-Endpunktes selbstständig und regelmässig mit DPD. Antwortet der andere VPN-Endpunkt nicht auf die DPD-Anfragen, gilt der VPN-Tunnel als "tot". Darauf trennt der VPN-Endpunkt vollautomatisch den VPN-Tunnel und versucht den VPN-Tunnel neu aufzubauen.
 
RTFM-artige Erwiderungen erachte ich in den meisten Fällen als überflüssig und wenig hilfreich, zudem muten sie immer etwas oberlehrerhaft an, insbesondere wenn die Implikations-Richtung des hervorgehobenen Textes eindeutig ist, ohne die näheren Umstände zu kennen. Die heilige Schrift trifft nämlich dann mal gern auf den Kobold der Realität, der mit Murphy wetteifert, wer irgendwem zuerst ein Bein stellen kann. Wenn DPD nicht derart zuverlässig funktioniert, wie es gewünscht ist, bleibt nur ein workaround...
 
zwar auf beiden Seiten "offiziell" noch bestehen, aber keine Pakete mehr darüber laufen.
Ist da denn die route ganz sicher das Problem? UDP im Tunnel geht auf einmal nicht mehr, TCP aber schon habe ich selbst schon erlebt.
Ggf. geht das Problem ja auch in ne ganz andere Richtung, da wäre ein eigener Thread möglicherweise besser.
 
Wenn DPD nicht derart zuverlässig funktioniert, wie es gewünscht ist, bleibt nur ein workaround...
Zumindest meine Fritzbox 7530 ist seit einiger Zeit - wahrscheinlich nach einem automatischen Firmwareupdate - sehr gut darin VPN-Tunnel und auch unverschlüsselte Tunnel wie gre und gif, die nicht auf ihr selbst terminiert sind, in halbtoten Zustand zu versetzen. Der Tunnel steht, lässt aber nach einiger keine Pakete mehr durch und erkannt wird es durch DPD und ähnlicher Magie nicht. Selbst, wenn permanent Daten durch den Tunnel übertragen werden, passiert es. Ich hatte leider noch keinen Nerv mir das näher anzuschauen.
 
Der Tunnel steht, lässt aber nach einiger keine Pakete mehr durch und erkannt wird es durch DPD und ähnlicher Magie nicht. Selbst, wenn permanent Daten durch den Tunnel übertragen werden, passiert es. Ich hatte leider noch keinen Nerv mir das näher anzuschauen.
Ungefähr so ist es bei mir auch; zwischenzeitlich konnte ich es sogar durch den Neustart einer beliebigen Jail auf einem von zwei Servern provozieren, und die Verbindungen zu beiden Servern war weg, die Server untereinander aber noch iO (also 2x VPN aus dem heimischen Netz und VPN bei den Servern untereinander). Da DPD vorher aber auch nur zu 90% funktionierte, wollte ich eh für die restlichen 10% was basteln und spontan dachte ich da eben an dpinger und das funktioniert erstmal zufriedenstellend.
 
Zurück
Oben