OpenWRT-Gateway Failover per VM

TErxleben

Renowned Member
Oct 20, 2008
593
91
93
Ich wollte eine SIMPLE Möglichkeit um zwischen 2 Gateways schmerzlos umzuschalten
Nachdem ich im OpenWRT-Forum ausgebuht wurde, mein Ansinnen müsste man ja unbedingt mit einem externem Addon namens mwan3 erledigen, stelle ich meine scriptbasierte Lösung auf Virtualisierungsbasis mal hier ein.
Vielleicht hilft es jemandem.

Vorraussetzung:
  • Es gibt zwei Gateways im LAN, die eine WAN-Verbindung haben.
  • Es gibt zwei virtualisierte Minimal-OpenWRTs, die sich lediglich durch unterschiedliche Gateway-Definitionen auf die zwei HW-Gateways unterscheiden. Diese benötigen auch nur eine Netzwerkschnittstelle.
  • Beide OpenWRT-VMs benutzen die gleiche IP, welche als Gateway im Netz propagiert wird und sollten nie parallel laufen.
  • DNS/DHCP laufen nicht auf den Gateways. Selbige fungieren wirklich nur als GW.

Nun muss nur bei Bedarf nur die entprechende OpenWRT-VM gestartet werden.

Das macht folgendes Script:
Code:
#!/bin/bash



# FAILOVER für Gateways openWRT254 und OpenWRT247 auf PVE-osts beide GW unter 192.168.1.1 verfügbar und im Netz propagiert.

# Die Minimal-OpenWRT-VMs unterscheiden sich nur im definierten GW.

# So sind die Open-WRTs einfachste Proxys der physischen Gateways um recht nahtlos Umschalten zu können.

# Vorraussetzung ist ein konfigurierter Postfix, um Benachrichtgungen mit mutt zu versenden.

# Die scripte check254.sh und check247.sh sind im Prinzip identisch und prüfen nur die WAN-Verbindung der entsprechenden Fritzbo

xen

# Andere Router erforden natürlich andere Prüfmechanismen.





MAILTO="evil@umbrella.com"

COMPANY="Umbrella corp."

SLEEPTIME=30                                            # wir prüfen alle 30s.

LINKEDBY="bond0:"                                       # Einzelschnittstelle, vmbr oder bond

MASTERPVE="192.168.1.201"                               # da sollen die OpenWRTs eigentlich rumwerkeln

AMIMASTERPVE=$(ip addr | grep $MASTERPVE | wc -l)       # Bin ich das womöglich selbst?



while true; do

  sleep $SLEEPTIME



  LINKED=$(ip link show | grep $LINKEDBY | grep "state UP" | wc -l)     # Sind wir denn selbst im Netzwerk überhaupt verfügbar?.



  if [ $LINKED == 1 ]; then                                             # LAN connection active

    ACTIVEMASTERPVE=$(nmap -p 22 $MASTERPVE | grep open | wc -l)

    if [ $AMIMASTERPVE == 1 ] || [ $ACTIVEMASTERPVE == 0 ]; then        # oh wir sind selbt Master aber Master-WAN ist platt.

      INTERNET=$(curl -s https://icanhazip.com | wc -l)                 # liefert unsere externe IP, falls online

      MASTERUP=$(/root/check254.sh)                                     # WAN Haupt-GW prüfen

      FAILOVERUP=$(/root/check247.sh)                                   # WAN Failover-GW prüfen

      RUNNINGMASTER=$(qm list | grep 901 | grep running | wc -l)

      if [ $INTERNET == 0 ]; then                                       # inet absent

        if [ $FAILOVERUP == 1 ]; then                                   # failover possible

          if [ $RUNNINGMASTER == 1 ]; then                              # MasterOpenWRT aktiv, Inet sollte eigentlich funktionie

ren tuts aber nicht

            qm start 900

            qm shutdown 901

            echo "Gateway über OpenWRT Master ist ausgefallen FAILOVER wird aktiviert." | mutt -s "Failover $COMPANY Failover-Op

enWRT (VM900) läuft nun auf $HOSTNAME" -- $MAILTO

          fi

        else

          echo "Failover-Gateway nicht verfügbar."

        fi

      else

        if [ $MASTERUP == 1 ]; then             # MasterRoute online

          qm shutdown 900

          if [ $RUNNINGMASTER == 0 ]; then      # MasterOpenWRT nicht aktiv, kann also wieder aktiviert werden

            qm start 901

            echo "Gateway über OpenWRT Master wieder aktiv FAILOVER wurde deaktiviert." | mutt -s "Recover $COMPANY Master-OpenW

RT (VM901) läuft nun wieder auf $HOSTNAME" -- $MAILTO

          fi

        fi

      fi

    else        # unser Master-PVE ist wohl am Start. Alles nicht mehr unser Bier. Wir stoppen hier also alle womöglichen laufen

de OpenWRTs

      if [ $AMIMASTERPVE == 0 ]; then                                           # wir sind also nur failoverhost und wollen kein

esfalls am Master fummeln.

        RUNNING247=$(qm list | grep "openwrt247" | grep "running" | wc -l)      # läuft hier ein Failover-WRT

        RUNNING254=$(qm list | grep "openwrt254" | grep "running" | wc -l)      # oder gar der Master-WRT

        if [ $RUNNING247 == 1 ]; then

          qm shutdown 900

        fi

        if [ $RUNNING254 == 1 ]; then

          qm shutdown 901

        fi

      fi

    fi

  else

   echo "Wir sind offline und damit nutzlos."

  fi

done



Hilfsscript für die WAN-Verfügbarkeit eines Gateways:

Code:
#!/bin/bash



# Prüft, ob die Fritzbox meint, das WAN würde funktionieren



curl -s -X POST -H "Content-Type: text/xml; charset=utf-8" -H "SoapAction: \"urn:schemas-upnp-org:service:WANCommonInterfaceConf

ig:1#GetCommonLinkProperties\"" --data "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope xmlns:s=\"http://schemas.xmlsoap.o

rg/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:GetCommonLinkProperties xmlns:u=\"u

rn:schemas-upnp-org:service:WANCommonInterfaceConfig:1\"/></s:Body></s:Envelope>" "http://192.168.1.247:49000/igdupnp/control/WA

NCommonIFC1" | grep -E "(NewPhysicalLinkStatus|NewWANAccessType|NewLayer1DownstreamMaxBitRate|NewLayer1UpstreamMaxBitRate)" | gr

ep ">Up<" |  wc -l
 
Last edited:
Warum, du kannst doch in OpenWRT MultiWan konfigurieren. So ganz verstehe ich nicht warum du es so machst.
Ich setze eine pfsense ein die auch MultiWan kann. Oder willst du dir ein Failover HA Cluster bauen, keine Ahnung ob das OpenWRT kann
 
  • Like
Reactions: Johannes S
Warum, du kannst doch in OpenWRT MultiWan konfigurieren. So ganz verstehe ich nicht warum du es so machst.
Ich setze eine pfsense ein die auch MultiWan kann. Oder willst du dir ein Failover HA Cluster bauen, keine Ahnung ob das OpenWRT kann
  • Nicht ohne Addon. Ganz trivial ist die Einrichtung auch nicht. Könnte man einfach eine Liste von Gateways, ähnlich die der DNS-Server, angeben hätte mir das am besten gefallen. Geht aber leider nicht. So muss ich die Wahl einer WAN-Route eben mit zwei OpenWRT-VMs steuern.
  • So habe ich zwei 4GB Mini-VMs mit nahezu 0 Administrationsaufwand. Die eine arbeitet mit GW-A, die andere mit GW-B, welche automatisch passend aktiviert werden müssen.
  • Die Proxmoxstruktur mit scriptbasierten Failovermechanismen auf beliebige PVEs bzgl. beider OpenWRTs ist ja eh vorhanden.
  • 50 Zeilen Script, müssen nur einmal konfiguriert werden und können dann vergessen werden.
  • Multiwan-Router sind dünn gesät.
  • will man Router unterschiedlicher Hersteller mischen, wird es noch finsterer.
  • Eine olle FB mit ausrangiertem Handy kann mit meiner Methode einen zweiten Frühling erleben und sogar als zusätzlicher WLAN-AP sogar das WLAN ausfallsicherer machen .
  • welches physische Gerät auch immer als Gateway dient ist völlig irrelevant
  • OpenWRT könnte ich problemlos gegen z.B. pfsense o.ä tauschen.
  • Vodafone lieferte mir sogar eine Ausfall-SIM, die mtl. automatisch mit 500MB aufgeladen wird, aber per Telefonanruf auf 500GB aufgepustet werden kann.
Es geht um schnödes aber robustes Failover von innen nach außen. Da ist MultiWAN mit VRRP, Keepalived, Loadbalancing und Konsorten in meinen Augen einfach Overkill. Zumal Portfreigaben über Mobilfunkbetreiber eher Kategrorie PITA sind. Sogar nahtloses Streaming funktioniert reibungslos. Ich will nur keine zusätzliche Komplexität, von der ich 99% eh nicht brauche.

Wer sich den Aufwand eines "echten" MultiWANs ans Bein nageln möchte: Gerne, dann ist das hier natürlich eine Holzhammermethode.
Wer aber zwei potentielle GWs im Netz hat und mindestens einen PVE betreibt, kann so ein GW-Failover stinkend einfach realisieren.
 
Last edited:
Ich habe bei mir eine Netgate 6100 und dort habe ich 2 x WAN, 1 x GLAS & 1 x 5G/LTE keine Traffic Begrenzung im Failover. Ich brauche keine 2 Firewalls wenn es mir nur um Failover geht, das macht die pfsense ohne extra Software zu installieren
 
Netter Ansatz, schön pragmatisch. Zwei Sachen die mir auffallen:

Beim Umschalten der VMs mit gleicher IP werden die ARP-Caches der Clients zum Problem, weil sich die MAC-Adresse ändert. Je nach Client/Switch kann das ein paar Minuten dauern bis der Traffic wieder sauber läuft. Ein arping -U -I <interface> 192.168.1.1 aus der neu gestarteten VM raus würde das beschleunigen (Gratuitous ARP), das würd ich auf jeden Fall noch einbauen.

Und icanhazip.com als einziger Internet-Check ist halt ne Single-Point-of-Failure für die Prüfung selbst. Wenn die Seite mal hängt oder DNS spinnt, denkt das Script es gibt kein Internet und flippt unnötig um. Lieber 2-3 Ziele checken und per Mehrheit entscheiden.
 
Netter Ansatz, schön pragmatisch. Zwei Sachen die mir auffallen:

Beim Umschalten der VMs mit gleicher IP werden die ARP-Caches der Clients zum Problem, weil sich die MAC-Adresse ändert. Je nach Client/Switch kann das ein paar Minuten dauern bis der Traffic wieder sauber läuft. Ein arping -U -I <interface> 192.168.1.1 aus der neu gestarteten VM raus würde das beschleunigen (Gratuitous ARP), das würd ich auf jeden Fall noch einbauen.

Und icanhazip.com als einziger Internet-Check ist halt ne Single-Point-of-Failure für die Prüfung selbst. Wenn die Seite mal hängt oder DNS spinnt, denkt das Script es gibt kein Internet und flippt unnötig um. Lieber 2-3 Ziele checken und per Mehrheit entscheiden.
Den beiden VMs habe ich von Anfang an identische MACs verpasst. Sollte doch reichen oder?

Nerviges flapping hatte ich bei Prüfung mittels nmap -p 53 8.8.8.8 ungefähr fünfmal täglich. Mit der jetzigen Lösung ist das verschwunden. Du hast aber Recht. Eine Check gegen mehre Internetziele tut nicht weh und geistert mir noch im Kopf rum.
 
Last edited:
Ich habe bei mir eine Netgate 6100 und dort habe ich 2 x WAN, 1 x GLAS & 1 x 5G/LTE keine Traffic Begrenzung im Failover. Ich brauche keine 2 Firewalls wenn es mir nur um Failover geht, das macht die pfsense ohne extra Software zu installieren
Dann hast du erstmal schon ca. 1.000€ in einen SPOF investiert. Was machst du, wenn das Teil komplett ausfällt? Hast du am Gerätestandort auch ordentlichen Mobilfunkempfang? Wie funktioniert das, wenn du gezwungenermaßen weitere 1.000€ für ein parallel laufendes nötiges Zweitgerät in die Hand nimmst?
Ich kenne leider den einen oder anderen Fall, in dem die Telekom zwei teuer vermietete Lancom-Geräte in 8J nicht zufriedenstellend für Failover konfigurieren konnte, aber selbstverständlich kassiert hat.
 
Last edited:
Stimmt, wenn beide VMs die gleiche MAC haben fällt das ARP-Thema komplett weg, guter Move. Dann vergiss den arping-Tipp.

Einzige Sache: falls durch nen Bug oder Race Condition doch mal beide VMs kurz gleichzeitig laufen (start/shutdown ist ja nicht atomar), hast du zwei VMs mit identischer MAC auf der gleichen Bridge. Das kann je nach Switch/Bridge zu MAC-Flapping führen. Würd ich im Script absichern, also vor dem qm start explizit prüfen ob die andere VM wirklich schon down ist, z.B.:
Code:
qm shutdown 901 && qm wait 901 --timeout 30 && qm start 900
Dann bist du auf der sicheren Seite.
 
  • Like
Reactions: Johannes S
So wie mir die pfsense Hardware um die Ohren fliegen kann, kann dir die proxmox Hardware abrauchen. Da ich das zuhause für mich alleine betreibe habe Ich natürlich keine 2. Netgate 6100 stehen. Aber ich bin mit dem Setup so zufrieden, ich könnte auch ein failover Setup auch mit weiteren anderen Internet Zugängen machen. Ich habe nicht geschrieben HA setup sondern nur Failover und das in Sekunden da nichts extra hochgefahren werden muss. Bei mir habe ich 5G mit ca. 300mbit/s down
 
  • Like
Reactions: Johannes S
So wie mir die pfsense Hardware um die Ohren fliegen kann, kann dir die proxmox Hardware abrauchen. Da ich das zuhause für mich alleine betreibe habe Ich natürlich keine 2. Netgate 6100 stehen. Aber ich bin mit dem Setup so zufrieden, ich könnte auch ein failover Setup auch mit weiteren anderen Internet Zugängen machen. Ich habe nicht geschrieben HA setup sondern nur Failover und das in Sekunden da nichts extra hochgefahren werden muss. Bei mir habe ich 5G mit ca. 300mbit/s down
Falls mir ein PVE abraucht, übernimmt automatisch ein anderer.
Wenn du mit deinem Setup zufrieden bist, passt das natürlich. Ich war genervt über die Zuverlässigkeit meines VF-Kabelanschluss und wollte das Problem hemdsärmlig lösen.
 
Einzige Sache: falls durch nen Bug oder Race Condition doch mal beide VMs kurz gleichzeitig laufen (start/shutdown ist ja nicht atomar), hast du zwei VMs mit identischer MAC auf der gleichen Bridge. Das kann je nach Switch/Bridge zu MAC-Flapping führen. Würd ich im Script absichern, also vor dem qm start explizit prüfen ob die andere VM wirklich schon down ist, z.B.:
Code:
qm shutdown 901 && qm wait 901 --timeout 30 && qm start 900
Dann bist du auf der sicheren Seite.
Gute Idee. Werde ich so machen.
 
Hier nochmal mein Script im Feinschliff.

Ein Hilfsscript checkwan.sh ist dazugekommen, in dem ich die hops zu Googles 8.8.8.8 zähle. Sind das weniger als 6, stimmt im WAN irgendwas nicht oder die Welt ist explodiert.

Code:
#!/bin/bash

# FAILOVER für Gateways openWRT254 und OpenWRT247 auf PVE-osts beide GW unter 192.168.1.1 verfügbar und im Netz propagiert.
# Die Minimal-OpenWRT-VMs unterscheiden sich nur im definierten GW.
# So sind die Open-WRTs einfachste Proxys der physischen Gateways um recht nahtlos Umschalten zu können.
# Vorraussetzung ist ein konfigurierter Postfix, um Benachrichtgungen mit mutt zu versenden.
# Die scripte check254.sh und check247.sh sind im Prinzip identisch und prüfen nur die WAN-Verbindung der entsprechenden Fritzboxen
# Andere Router erforden natürlich andere Prüfmechanismen.

MAILTO="evil@umbrella.com"
COMPANY="Umbrella corp"
SLEEPTIME=30                                            # wir prüfen alle 30s.
LINKEDBY="bond0:"                                       # Einzelschnittstelle, vmbr oder bond
MASTERPVE="192.168.1.201"                               # da sollen die OpenWRTs eigentlich rumwerkeln
AMIMASTERPVE=$(ip addr | grep $MASTERPVE | wc -l)       # Bin ich das womöglich selbst?

while true; do
  sleep $SLEEPTIME

  LINKED=$(ip link show | grep $LINKEDBY | grep "state UP" | wc -l)     # Sind wir denn selbst im Netzwerk überhaupt verfügbar?.

  if [ $LINKED == 1 ]; then                                             # LAN connection active
    ACTIVEMASTERPVE=$(nmap -p 22 $MASTERPVE | grep open | wc -l)
    if [ $AMIMASTERPVE == 1 ] || [ $ACTIVEMASTERPVE == 0 ]; then        # oh wir sind selbt PVE-Master oder PVE-Master ist platt.
      INTERNET=$(/root/checkwan.sh)                                     # WAN Haupt-GW prüfen
      MASTERUP=$(/root/check254.sh)                                     # WAN Haupt-GW prüfen
      FAILOVERUP=$(/root/check247.sh)                                   # WAN Failover-GW prüfen
      RUNNINGMASTER=$(qm list | grep 901 | grep running | wc -l)
      RUNNINGFAILOVER=$(qm list | grep 900 | grep running | wc -l)
      if [ $RUNNINGMASTER == 0 ]; then                                  # MasterOpenWRT aus
        if [ $RUNNINGFAILOVER == 0 ]; then                              # FailoverOpenWRT aus
          qm start 901                                                  # wir aktivieren also den Master
          echo "Keine OpenWRT-VM lief. Master wurde nun aber aktiviert." | mutt -s "Aktivierung $COMPANY von Master-OpenWRT (VM901) läuft nun auf $HOSTNAME" -- $MAILTO
        fi
      fi
      if [ $RUNNINGMASTER == 1 ]; then                                  # MasterOpenWRT aktiv, Inet sollte eigentlich funktionieren tuts aber nicht
        if [ $FAILOVERUP == 1 ]; then                                   # failover möglich
          if [ $INTERNET == 0 ]; then                                   # inet absent
            qm shutdown 901 && qm wait 901 --timeout 30 && qm start 900 # wir schalten also um
            echo "Gateway über OpenWRT Master ist ausgefallen FAILOVER wird aktiviert." | mutt -s "Failover $COMPANY Failover-OpenWRT (VM900) läuft nun auf $HOSTNAME" -- $MAILTO
          fi
        fi
      fi
      if [ $RUNNINGFAILOVER == 1 ]; then                                # FailoverOpenWRT aktiv, Inet sollte eigentlich funktionieren tuts aber nicht
        if [ $MASTERUP == 1 ]; then                                     # Aber MasterRoute scheint online
          qm shutdown 900 && qm wait 900 --timeout 30 && qm start 901   # wir schalten also zurück zum Master
          echo "Gateway über OpenWRT Master wieder aktiv FAILOVER wurde deaktiviert." | mutt -s "Recover $COMPANY Master-OpenWRT (VM901) läuft nun wieder auf $HOSTNAME" -- $MAILTO
        fi
      fi
    else                                # unser Master-PVE ist wohl am Start. Alles nicht mehr unser Bier. Wir stoppen hier also alle womöglichen laufende OpenWRTs
      if [ $AMIMASTERPVE == 0 ]; then   # wir sind also nur failoverhost und wollen keinesfalls am Master fummeln.
        if [ $(qm list | grep "openwrt247" | grep "running" | wc -l) == 1 ]; then qm shutdown 900; fi
        if [ $(qm list | grep "openwrt254" | grep "running" | wc -l) == 1 ]; then qm shutdown 901; fi
      fi
    fi
  else
    echo "Wir sind offline und damit nutzlos."
  fi
done

checkwan.sh

Code:
#!/bin/bash

# echo 0
#curl -s https://icanhazip.com | wc -l
HOPS=$(traceroute -4 8.8.8.8 | wc -l)
if [ $HOPS -gt 5 ]; then
  echo 1
else
  echo 0
fi
 
Last edited: