OpenWRT-Gateway Failover per VM

Ich weiss nicht, wo du guckst. Ein FAILOVER == 0 finde ich im Script nur in Verbindung mit deinem erwähnten Einwand &&, das in einem Vorscript mit || tatsächlich falsch war.

Vielleicht bin ich auch ich im eigenen Script auch betriebsblind
Aber ich finde nur ein
Code:
if [ $FORCEFAILOVER == 1 ] || [ $MASTERGWUP == 0 ]

Darum poste ich das Script vorsichtshalber nochmal:
Code:
#!/bin/bash

# FAILOVER für Gateway-VMs openWRT254 und OpenWRT247 auf PVE-Hosts sind 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.
# Andere Router erforden natürlich andere Prüfmechanismen.
# checkwan.sh prüft die Internetverfügbarkeit
# forcefailover.sh kan man zu testen verwenden

MAILTO="edv@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, sonst hat das alles eh keinen Zweck
    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.
      FORCEFAILOVER=$(/root/forcefailover.sh)                           # Failover erzwingen?
      MASTERGWUP=$(/root/checkwan.sh 192.168.1.254 FB)                  # WAN Haupt-GW prüfen
      FAILOVERGWUP=$(/root/checkwan.sh 192.168.1.247 FB)                # 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 [ $FAILOVERGWUP == 1 ]; then                                 # failover wäre möglich
          if [ $FORCEFAILOVER == 1 ] || [ $MASTERGWUP == 0 ]; then      # Aber MasterRoute scheint offline
            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.
        if [ $FORCEFAILOVER == 0 ] && [ $MASTERGWUP == 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
  fi
done
 
Last edited:
Ich war genervt über die Zuverlässigkeit meines VF-Kabelanschluss und wollte das Problem hemdsärmlig aber automatisch lösen.
Da würde ich lieber schauen, dass ich von VF-Kabel wegkomme, anstatt erstmal viel Zeit in ein Script zu investieren - obwohl ich die Idee dahinter ja nicht schlecht finde;)

Die Fritzbox stellt noch die WAN-Verbindung am Kabelanschluss her?
 
  • Like
Reactions: Johannes S
Da würde ich lieber schauen, dass ich von VF-Kabel wegkomme, anstatt erstmal viel Zeit in ein Script zu investieren - obwohl ich die Idee dahinter ja nicht schlecht finde;)

Die Fritzbox stellt noch die WAN-Verbindung am Kabelanschluss her?
Leider ist VF ziemlich alternativlos.
Es sind ja sogar zwei Fritzen. FB6690 für Kabel und FB7530 für DSL/LTE
 
Ich habe nun die statischen Parameter in eine gwfailover.conf ausgelagert.
Die zwei Hilfsscripte heißen nun gwcheckwan.sh und gwcheckvm.sh
Das erlaubt Änderungen, ohne irgendwas neu starten zu müssen.
Aufgeräumt habe ich auch.

gwfailover.sh:
Code:
#!/bin/bash
set -euov pipefail

# FAILOVER für Gateway-VMs.
# Diese sind auf den Hosts PVE und auf PVE1 (VM900 und VM901) unter 192.168.1.1 verfügbar.
# Es sollte also immer nur einer von vieren aktiv sein.
# Die Minimal-OpenWRT-VMs unterscheiden sich nur im definierten Gateway.
# 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.
# gwcheckwan.sh [IP] [TYPE] prüft die Internetverfügbarkeit des jeweiligen Gateways
# gwcheckvm.sh [ID] prüft ob eine Gateway-VM aktiv ist
# Andere Router erforden natürlich andere Prüfmechanismen, deshalb der [TYPE]-Parameter bei gwcheckwan.sh.
# gwfailover.conf, gwcheckwan.sh und gwcheckvm.sh ermöglichen es, die Parameter ohne Neustart des Services zu testen

MYIP=$(hostname -i)
while true; do
  source "/root/gwfailover.conf"
  if [ $DEBUG == 1 ]; then
    set -euovx pipefail         # Debug-Ausgabe ein
  else
    set +vx                     # Fresse halten
  fi
  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, sonst hat das alles eh keinen Zweck
    ACTIVEMASTERPVE=$(nmap -p 22 "$MASTERPVE" | grep open | wc -l)
    if [ $NOPVE == 1 ]; then ACTIVEMASTERPVE=0; fi                      # oh wir simulieren einen Ausfall
    if [[ $MASTERPVE == $MYIP ]] || [ "$ACTIVEMASTERPVE" == "0" ]; then
      MASTERGWUP=$(/root/gwcheckwan.sh $MASTERGW FB)                    # läuft WAN des Haupt-GWs
      FAILOVERGWUP=$(/root/gwcheckwan.sh $FAILOVERGW FB)                        # läuft WAN des Failover-GWs
      MASTERVM=$(/root/gwcheckvm.sh $MASTERVMID)                                # läuft die Master-VM
      FAILOVERVM=$(/root/gwcheckvm.sh $FAILOVERVMID)                    # läuft die Failover-VM
      if [ $NOISP == 1 ]; then MASTERGWUP=0; fi                         # oh wir simulieren einen Ausfall
      if [ $MASTERVM == 0 ]; then                                       # MASTERVM also aus
        if [ $FAILOVERVM == 0 ]; then                                   # FAILOVERVM also aus
          qm start $MASTERVMID                                          # 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 [ $MASTERVM == 1 ]; then                               # MASTERVM aktiv, Inet sollte eigentlich funktionieren tuts aber nicht
        if [ $FAILOVERGWUP == 1 ]; then                         # failover wäre möglich
          if [ $MASTERGWUP == 0 ]; then                         # Aber MasterRoute scheint offline
            qm shutdown $MASTERVMID && qm wait $MASTERVMID --timeout 30 && qm start $FAILOVERVMID       # wir schalten also um
            echo "Gateway von OpenWRT Master ist ausgefallen FAILOVER über ($FAILOVERGW) wurde aktiviert." | mutt -s "Failover $COMPANY Failover-OpenWRT (VM900) läuft nun auf $HOSTNAME" -- $MAILTO
          fi
        fi
      fi
      if [ $FAILOVERVM == 1 ]; then             # FAILOVERVM aktiv.
        if [ $MASTERGWUP == 1 ]; then           # Aber MasterRoute scheint online
          qm shutdown $FAILOVERVMID && qm wait $FAILOVERVMID --timeout 30 && qm start $MASTERVMID       # wir schalten also zurück zum Master
          echo "Gateway über OpenWRT Master mit Gateway ($MASTERGW) 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 könnte aber am Start sein.
       if [[ "$MASTERPVE" != "$MYIP" ]] && [ "$ACTIVEMASTERPVE" == 1 ]; then    # oh wir sind tatsächlich nur PVE-Failover und der Master ist am Start. Aalso alles nicht mehr unser Bier.
        if [ $(qm status $FAILOVERVMID | grep "running" | wc -l) == 1 ]; then qm shutdown $FAILOVERVMID; fi
        if [ $(qm status $MASTERVMID | grep "running" | wc -l) == 1 ]; then qm shutdown $MASTERVMID; fi
      fi
    fi
  fi
done

gwfailover.conf:
Code:
MAILTO="info@umbrella.com"
COMPANY="Umbrella corp."

LINKEDBY="bond0:"                   # Einzelschnittstelle, vmbr oder bond
MASTERPVE="192.168.1.201"           # auf dem Host sollen die OpenWRTs eigentlich rumwerkeln

MASTERVMID="901"                    # unser Haupt-Openwrt
MASTERGW="192.168.1.254"            # welches GW nutzt die MasterVM

FAILOVERVMID="900"                  # Das Failover-Openwrt
FAILOVERGW="192.168.1.247"          # Das Gateway der Failover VM

# 1=teste Failover
# 0=Normalbetrieb

NOPVE=0                             # 1=Simulation Host-Ausfall
NOISP=0                             # 1=Simulation Provider-Ausfall
DEBUG=0                             # 1=Einschalten von Debuginformationen
SLEEPTIME=30                        # Alle 30s Zustand prüfen

gwcheckvm.sh:
Code:
#!/bin/bash

qm status $1 | grep running | wc -l

gwcheckwan.sh:
Code:
#!/bin/bash

TOCHECK=$1

if [ $2 == FB ]; then                               # also eine Fritzbox prüfen
  curl -s -X POST -H "Content-Type: text/xml; charset=utf-8"      -H "SoapAction: \"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1#GetCommonLinkProperties\""      --data "<?xml version=\"1.0\" encoding=\"utf-8\"?><s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\"><s:Body><u:GetCommonLinkProperties xmlns:u=\"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1\"/></s:Body></s:Envelope>"      "http://$TOCHECK:49000/igdupnp/control/WANCommonIFC1" | grep -E "(NewPhysicalLinkStatus|NewWANAccessType|NewLayer1DownstreamMaxBitRate|NewLayer1UpstreamMaxBitRate)" | grep ">Up<" |  wc -l
fi
 
Last edited: