Automatisierung (Der Auto-Wechsler)

Wir können ein kleines, schlankes Bash-Skript schreiben und es als NetworkManager-Dispatcher-Skript hinterlegen. Der Dispatcher führt Skripte aus, sobald sich der Netzwerkstatus ändert.

Zusätzlich lassen wir einen minimalen Cronjob oder Systemd-Timer laufen (oder nutzen ein up-Skript), das pingt. Die eleganteste und zuverlässigste Methode für Hotspots ist jedoch ein kleines Hintergrund-Skript, das alle 30 Sekunden das Internet prüft und bei Bedarf umschaltet.

Erstelle die Skriptdatei mit deinem Standard-Editor micro:

BASH
sudo micro /usr/local/bin/hotspot-watchdog.sh

Füge dort folgenden Code ein (vollständig auf Englisch, wie gewünscht):

BASH
#!/usr/bin/env bash

SSID1="Vodafone Hotspot"
SSID2="Vodafone Homespot"
INTERFACE="wlan0"
CHECK_URL="http://connectivitycheck.gstatic.com/generate_204"

log_msg() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') - [Hotspot-Watchdog] $1"
}

# Helper function to execute the switch
force_switch() {
    local current="$1"
    local target=""

    if [[ "$current" == "$SSID1" ]]; then
        target="$SSID2"
    else
        target="$SSID1"
    fi

    log_msg "Forcing switch from $current to $target..."
    nmcli dev wifi connect "$target" ifname "$INTERFACE"
    sleep 60
}

while true; do
    NM_STATE=$(nmcli -t -f STATE g)
    CURRENT_SSID=$(nmcli -t -f ACTIVE,SSID dev wifi | grep '^yes:' | cut -d: -f2)

    if [[ "$CURRENT_SSID" == "$SSID1" || "$CURRENT_SSID" == "$SSID2" ]]; then

        # CASE 1: NM thinks it's fine, but HTTP traffic is dead or redirected (Captive Portal kickout)
        if [[ "$NM_STATE" == "connected" || "$NM_STATE" == "site" ]]; then
            HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 "$CHECK_URL")
            if [[ "$HTTP_CODE" -ne 204 ]]; then
                log_msg "Internet dead (HTTP $HTTP_CODE) on $CURRENT_SSID."
                force_switch "$CURRENT_SSID"
            fi

        # CASE 2: NM is stuck in a local/connecting loop and can't get an IP (DHCP Lease Failure)
        elif [[ "$NM_STATE" == "local" || "$NM_STATE" == "connecting" ]]; then
            # Check how long it's been struggling. If it takes longer than 20 seconds in this loop, we pull the plug.
            log_msg "NetworkManager is stuck in state ($NM_STATE) on $CURRENT_SSID. Waiting 20s for fallback..."
            sleep 20

            # Re-check after 20 seconds to see if it recovered on its own
            NM_STATE_RECHECK=$(nmcli -t -f STATE g)
            if [[ "$NM_STATE_RECHECK" == "local" || "$NM_STATE_RECHECK" == "connecting" ]]; then
                log_msg "NetworkManager still stuck ($NM_STATE_RECHECK) after timeout. Initiating fallback."
                force_switch "$CURRENT_SSID"
            fi
        fi
    fi
    sleep 30
done

Skript ausführbar machen und als Dienst starten

Damit das Skript permanent im Hintergrund läuft, erstellen wir einen einfachen Systemd-Service:

BASH
sudo chmod +x /usr/local/bin/hotspot-watchdog.sh
sudo micro /etc/systemd/system/hotspot-watchdog.service

Inhalt der Service-Datei:

TXT
[Unit]
Description=Vodafone Hotspot/Homespot Watchdog
After=NetworkManager.service

[Service]
Type=simple
ExecStart=/usr/local/bin/hotspot-watchdog.sh
Restart=on-failure

[Install]
WantedBy=multi-user.target

Jetzt den Dienst aktivieren und starten:

BASH
sudo systemctl daemon-reload
sudo systemctl enable --now hotspot-watchdog.service

Teil 2: Debugging (Warum passiert das?)

Wenn du dem Fehler auf den Grund gehen willst, warum DHCP fehlschlägt (keine gültige IP Konfiguration), sollten wir uns die Logs von NetworkManager und dhcpcd (oder systemd-networkd/internal dhcp, je nach NM-Config) genau ansehen, während der Fehler auftritt.

1. Live-Logs betrachten

Öffne ein Terminal und lass die Logs in Echtzeit laufen, wenn das WLAN das nächste Mal zickt:

BASH
journalctl -u NetworkManager -f

Achte hierbei besonders auf Meldungen wie:

  • dhcp4 (wlan0): request timed out

  • state change: activated -> failed

  • Reason: IP configuration availability expired

2. Mögliche Ursache: MAC-Address Randomization

CachyOS und NetworkManager nutzen oft standardmäßig wechselnde MAC-Adressen aus Datenschutzgründen. Die Vodafone-Hotspots speichern deine Anmeldung (Captive Portal) aber anhand deiner MAC-Adresse. Wenn NetworkManager beim Reconnect die MAC ändert, fliegst du raus oder der DHCP-Server blockiert dich.

Lösung/Test: MAC-Randomization für diese Netzwerke abschalten.

  1. Öffne die Verbindungsdatei (die liegen unter /etc/NetworkManager/system-connections/).

  2. Oder setze es global für WLAN in der /etc/NetworkManager/NetworkManager.conf:

TXT
[device]
wifi.scan-rand-mac-address=no

[connection]
wifi.cloned-mac-address=stable

stable sorgt dafür, dass du pro WLAN-Netzwerk immer dieselbe MAC-Adresse nutzt, was Hotspots deutlich stabiler macht.

Nach Änderungen am NetworkManager diesen neu starten:

BASH
sudo systemctl restart NetworkManager