Mit Dispatcher-Skripten hängen Sie je nach Standort unterschiedliche Netzwerklaufwerke ein oder starten automatisch eine VPN-Verbindung, ohne dass Sie einen Finger krumm machen müssten.
Gestern auf einer Tagung, heute im Büro in der Innenstadt, morgen im Homeoffice, übermorgen in einem Café: Der Arbeitsalltag vieler Menschen beschränkt sich heute nicht mehr auf einen Schreibtisch, sondern verteilt sich auf unterschiedliche Orte. Für viele Arbeitnehmer und Selbstständige gilt daher: Wo es einen verlässlichen und schnellen Zugang zum Internet gibt, kann man seiner Arbeit nachgehen – einfach den Laptop aufklappen und loslegen.
Was sich in der Theorie erst einmal einfach anhört, steckt in der Praxis oft voller Tücken. Im Homeoffice müsste man sich gerade konzentrieren, doch die lieben Kleinen fordern Bespaßung ein; der Tisch im hippen Café im Szeneviertel wackelt zu stark. Aber auch die Technik möchte vorbereitet sein. Hier erfordern besonders die unterschiedlichen Netzwerke Aufmerksamkeit. Im LAN zu Hause möchte man die Dateifreigaben eines NAS mounten, im offenen WLAN eines Cafés sollte die Firewall alle Zugriffe blocken. Im sicheren Büro hingegen dürfen die lokal laufenden Dienste ruhig funken.
Der Dispatcher regelt’s
Die unterschiedlichen Netzwerkzugänge erfordern allerdings ständig Anpassungen am System. Geht ein Rechner nur über einen einzigen kabelgebundenen Ethernet-Anschluss ins Netz, mountet man Netzwerklaufwerke idealerweise über die /etc/fstab oder verwendet AutoFS, falls der gewünschte Server nicht immer am Netz hängt. Um aber Dienste abhängig von der Situation automatisch zu starten und zu stoppen oder um bestimmte Konfigurationen automatisiert vornehmen zu lassen, braucht es einen intelligenten Netzwerkmanager.
Nach einer solchen smarten Netzwerkverwaltung müssen Sie nicht lange suchen: Die meisten Distributionen haben in Form von NetworkManager das nötige Werkzeug von Haus aus an Bord (Abbildung 1). Als Nutzer müssen Sie nur sogenannte Dispatcher-Skripte für den Dienst konfigurieren. Die Automatik erledigt dann abhängig vom gerade aktiven Netzwerkzugang den Rest und führt beim Verbindungsauf- und -abbau beliebige Skripte automatisiert aus. Das Einrichten dieser Funktionen erfordert allerdings ein wenig Know-how, eine grafische Oberfläche dafür fehlt.

Abbildung 1: Der NetworkManager lässt sich auch über das Terminal bedienen. Als zentrales Steuerungswerkzeug dient das Konsolenprogramm nmcli.
Achtung
Je nach eingesetzter Distribution befinden sich im Ordner /etc/NetworkManager/dispatcher.d/ bereits Dispatcher-Skripte. Ubuntu etwa bringt von Haus aus das Skript 01-ifupdown mit. Diese Dateien sollten Sie auf keinen Fall löschen oder verändern, um die Funktionen von NetworkManager nicht zu stören.
Dispatcher-Skripte schreiben
Die Dispatcher-Funktion von NetworkManager sucht im Ordner /etc/NetworkManager/dispatcher.d/ nach Skripten, die sie abarbeiten soll. Sie führt die Skripte dann beim Verbindungsaufbau in alphabetische Reihenfolge aus, beim Abbau einer Netzverbindung in umgekehrter Abfolge. Zur besseren Organisation stellen Sie den Dateinamen für eigene Skripte daher idealerweise eine Nummer voran, in der Art 30-mount-diskstation. Zudem müssen Sie darauf achten, dass die Skripte dem Root-User sowie zur Root-Gruppe gehören und ausführbar sind. Das angesprochene Skript würden Sie beispielsweise wie in Listing 1 gezeigt anlegen.
Listing 1
$ cd /etc/NetworkManager/dispatcher.d $ sudo touch 30-mount-diskstation $ sudo chown root:root 30-mount-diskstation $ sudo chmod 755 30-mount-diskstation
Ein simples Skript wie in Listing 2 bindet dann zum Beispiel beim Anschluss des Rechners an einen kabelgebundenen Ethernet-Anschluss die in der /etc/fstab konfigurierten Netzwerkfreigaben ein. Die dafür nötige CONNECTION_UUID ermitteln Sie beispielsweise über das Konsolen-Frontend von NetworkManager mittels nmcli connection show (Listing 3). Beachten Sie dabei, dass sich die UUID von zuvor konfigurierten WLAN-Netzwerken jeweils unterscheidet. Die Ethernet-Schnittstelle bekommt jedoch immer dieselbe UUID, egal, ob Sie den Rechner im Büro, an der Uni oder zu Hause per Kabel ans Netzwerk hängen.
Listing 2
#!/bin/bash
if [ "$2" = "up" ]; then
if [ "$CONNECTION_UUID" = "2911db45-3eff-3b74-9c87-4c36e0290693" ]; then
mount /mnt/diskstation/music &
mount /mnt/diskstation/daten &
mount /mnt/diskstation/photo &
fi
fi
Listing 3
$ nmcli connection show
NAME UUID TYPE DEVICE
LAN1 2911db45-3eff-3b74-9c87-4c36e0290693 ethernet enp0s31f6
Santa 5e1eb419-9f6a-40e2-ada5-ca6a909bee87 wifi wlp2s0
G6_SMARTPHONE d9d63454-329e-4177-a6ef-c92b39fe26af wifi --
LAN2 f38a99ea-48ea-362b-90d3-62a265930f87 ethernet --
VPN-Netherlands 7b87cee0-3131-4b0c-a659-bb33f4a64dd8 vpn --
PirateBox - Share Freely 46b124c1-0604-4645-99d6-5c73d200a1e6 wifi --
Wichtig ist hier die gewünschte Aktion: In Zeile 2 von Listing 2 definieren Sie, dass der Netzwerkmanager die Aktion nach dem erfolgreichen Verbindungsaufbau ausführen soll. Es gibt zahlreiche weitere Aktionen, wie etwa down, pre-up oder pre-down; die Tabelle “Dispatcher-Aktionen” bietet einen Überblick.
|
Aktion |
Beschreibung |
|---|---|
|
|
Netzwerkgerät mit dem Netz verbunden, aber noch nicht vollständig aktiviert. Skripte müssen entweder nach |
|
|
Aktion wird nach dem vollständigen Verbindungsaufbau ausgeführt. |
|
|
Das Netzwerkgerät soll deaktiviert werden, ist aber noch mit dem Netz verbunden. Skripte müssen entweder nach |
|
|
Aktion wird nach dem Abbau einer Netzverbindung ausgeführt. |
|
|
Identisch zu |
|
|
Aktion wird nach dem Aufbau einer VPN-Verbindung ausgeführt. |
|
|
Identisch zu |
|
|
Aktion wird nach dem Abbau einer VPN-Verbindung ausgeführt. |
|
|
Registriert die Änderung des Hostnamens. |
|
|
System hat via DHCP eine neue IPv4-Konfiguration erhalten. |
|
|
System hat via DHCP eine neue IPv6-Konfiguration erhalten. |
|
|
Netzwerkstatus hat sich verändert (siehe Tabelle “Netzwerkstatus”). |
|
Alle |
|
|
Status |
Beschreibung |
|---|---|
|
|
Netzwerkgerät ist nicht verbunden. |
|
|
Netzwerkgerät ist mit einem “Captive Portal” verbunden (etwa einer Seite zur Authentifizierung in einem Hotel-WLAN) und hat noch keine Verbindung zum Internet. |
|
|
Das Netzwerkgerät ist mit dem LAN verbunden, hat aber keine Verbindung zum Internet. |
|
|
Netzwerkverbindung inklusive Internet-Zugang vollständig eingerichtet. |
|
|
Netzwerkstatus des Geräts kann nicht ermittelt werden. |
Für Verwirrung sorgen dabei allerdings die pre-Aktionen. Für sie gibt es seit einiger Zeit unterhalb von /etc/NetworkManager/dispatcher.d/ die Unterverzeichnisse pre-up.d/ und pre-down.d/. Dort hinterlegte oder verlinkte Skripte führt der Netzwerkmanager ohne Fallunterscheidung im Skript selbst bei der entsprechenden Aktion aus. Listing 4 würde, als [...]/pre-down.d/10-umount-cifs abgespeichert, beispielsweise die zuvor über Listing 2 gemounteten Freigaben vor dem Abbauen der Netzwerkverbindung sicher aushängen.
Listing 4
#!/bin/bash umount -a -l -t cifs
Ungeduldig
Für Dispatcher-Skripte, die NetworkManager unabhängig von der Reihenfolge abarbeiten soll, gibt es unter /etc/NetworkManager/dispatcher.d/ den Ordner no-wait.d/. Die dort abgelegten Skripte führt NetworkManager umgehend nach dem Ändern des Netzwerkstatus aus, egal, welche anderen Skripte gerade noch aktiv sind.
Um nun je nach Arbeitsort unterschiedliche Freigaben zu realisieren, lässt sich das Prinzip von Listing 2 noch etwas erweitern. Bestücken Sie das Skript mit dem Inhalt aus Listing 5, überprüft NetworkManager mithilfe des Netcat-Kommandos nc -z Server 139. ob der in der Variablen SERVERNAME eingetragene Rechner im Netz zu finden ist und ob auf ihm der Samba-Dienst auf Port 139 läuft. Falls ja, mountet das Skript die im Array SHARES aufgeführten Freigaben.
Listing 5
#!/bin/bash
SERVERNAME="diskstation"
FOLDER="/mnt/diskstation"
SHARES=(homes music daten photo ebooks images video web)
if [ "$2" = "up" ]; then
if [ "$CONNECTION_UUID" = "2911db45-3eff-3b74-9c87-4c36e0290693" ]; then
### Prüfen ob $SERVERNAME online ist und Samba-Shares anbietet
if nc -z $SERVERNAME 139 2>/dev/null; then
### Wenn ja, dannn mounte Freigaben aus Array $SHARES
for SHARE in "${SHARES[@]}"
do
### Nur einbinden, wenn Freigabe noch nicht gemountet
if ! $(mountpoint -q "$FOLDER/$SHARE") ; then
mount $FOLDER/$SHARE
fi
done
fi
fi
fi
Damit haben Sie bereits ein Ziel erreicht: Für jeden üblicherweise genutzten Samba-Server erstellen Sie unter /etc/NetworkManager/dispatcher.d ein Skript in der Art 30-mount-Server, das in Zukunft das situative Mounten von Netzwerkfreigaben übernimmt. Sie müssen lediglich die Variablen im Kopf des Skripts anpassen sowie die UUID ändern. Sollte einmal ein Server nicht zu erreichen sein, hält sich das System nicht mit erfolglosen Versuchen auf, den Server im Netz zu finden.
Umgebungsvariablen
NetworkManager befüllt in den Dispatcher-Skripten eine Reihe von Umgebungsvariablen, die sich zum Steuern der gewünschten Aktionen nutzen lassen. So finden Sie in $IP4_DOMAINS den vom DHCP-Server zugewiesenen Domain-Namen, in $IP4_ADDRESS_0 die IP- sowie Gateway-Adresse im Format IP-Adresse/Prefix Gateway. Sämtliche Variablen erklärt die Developer-Seite der Gnome-Foundation zu NetworkManager [1]. Bei Bedarf schreiben Sie den Inhalt dieser Variablen mit dem Kommando printenv >&2 in das Journal des Systems. Dementsprechend lässt sich dann mithilfe von journalctl -f -u NetworkManager der Inhalt der Variablen während der Laufzeit des Dispatcher-Skripts einsehen (Listing 6).
Listing 6
$ journalctl -f -u NetworkManager
[...]
Mai 22 23:44:01 ontario NetworkManager[485]: <info> [1590183841.6878] dhcp4 (enp0s31f6): option domain_name => 'fritz.box'
Mai 22 23:44:01 ontario NetworkManager[485]: <info> [1590183841.6878] dhcp4 (enp0s31f6): option domain_name_servers => '192.168.188.11'
Mai 22 23:44:01 ontario NetworkManager[485]: <info> [1590183841.6878] dhcp4 (enp0s31f6): option ntp_servers => '192.168.188.1'
[...]
Automatisch ins VPN
Ein anderer populärer Anwendungsfall besteht darin, beim Verbindungsaufbau zu einem bestimmten WLAN automatisch eine VPN-Verbindung zu starten. Sichern Sie zum Beispiel Listing 7 als 20-protonvpn in /etc/NetworkManager/dispatcher.d, so ruft der NetworkManager beim Verbindungsaufbau zum WLAN mit der angegebenen UUID über das textbasierte Frontend des Netzwerkmanagers nmcli eine Verbindung zum VPN mit der ID ProtonUS auf. Diesmal sorgt eine Fallunterscheidung mithilfe des case-Kommandos für die unterschiedlichen Kommandos beim Auf- und Abbau der Verbindung (Abbildung 2).

Abbildung 2: Mit dem entsprechenden Dispatcher-Skript startet NetworkManager bei der Einwahl in ein bestimmtes WLAN automatisch eine VPN-Verbindung.
Listing 7
#!/bin/sh
if [ "$CONNECTION_UUID" = "5e1eb419-9f6a-40e2-ada5-ca6a909bee87" ]; then
case "$2" in
up)
nmcli connection up id "ProtonUS" passwd-file /root/protonvpn-passwd-file
;;
pre-down)
nmcli connection down id "ProtonUS"
;;
esac
fi
Dabei müssen Sie beachten, dass Sie beim Konfigurieren der VPN-Verbindung über das grafische Frontend von NetworkManager das Passwort des VPN-Zugangs benutzerspezifisch im Schlüsselbund der Desktop-Umgebung ablegen. Der als Root gestartete NetworkManager-Dienst hat auf diese Inhalte allerdings keinen Zugriff, Sie müssen das Passwort daher noch einmal gesondert im System abspeichern. Das Beispiel aus Listing 7 verwendet die Datei /root/protonvpn-passwd-file. Das Format der Passwortdatei zeigt Ihnen die Ausgabe des zweiten Kommandos in Listing 8.
Listing 8
# nmcli connection show NAME UUID TYPE DEVICE ProtonUS 4610ff84-57d8-4509-a56d-c33a5c7f21c9 vpn -- SantaFAST 5e1eb419-9f6a-40e2-ada5-ca6a909bee87 wifi -- # cat /root/protonvpn-passwd-file vpn.secrets.password:geheimes+passwort
Optional könnten Sie auch unter /etc/NetworkManager/system-connections/ direkt die für das gewünschte Netz verantwortliche Konfigurationsdatei bearbeiten. Im fraglichen File müssten Sie dann im Abschnitt [vpn] in der Option password-flags= eine 0 statt einer 1 setzen und dann unter [vpn-secrets] über die neu hinzuzufügende Zeile password=Passwort das Passwort hinterlegen. So kann der NetworkManager auch ohne Interaktion des Benutzers die gewünschte VPN-Verbindung starten.
Hinweis
Der Aufbau einer VPN-Verbindung genügt alleine noch nicht für sicheres und anonymisiertes Surfen im Netz. Sollte zum Beispiel das VPN aufgrund von Übertragungsfehlern ungewollt zusammenbrechen, würde der NetworkManager das nicht bemerken und die Daten dann unverschlüsselt übertragen. Sie sollten daher zusätzlich mit geeigneten Firewall-Skripten dafür sorgen, dass das System ausschließlich den verschlüsselten Tunnel für Datenübertragungen verwendet.
Debuggen
Da NetworkManager bis auf die Konfiguration im Hintergrund arbeitet, lassen sich eigene Dispatcher-Skripte nicht so ohne Weiteres auf Fehler hin untersuchen. Stimmt etwas nicht, springt nicht einfach ein Fenster mit hilfreichen Fehlermeldungen auf: Bei einem Fehler im Skript passiert schlichtweg gar nichts. Um dennoch Programmierfehlern auf die Schliche zu kommen, muss man in die Logs des Systems schauen.
Zum einen können Sie mit nmcli monitor in Echtzeit verfolgen, was NetworkManager gerade macht. Sie sehen, wie die Netzwerkgeräte heißen und welche Aktionen gerade ablaufen. Um die Logs von NetworkManager einzusehen, müssen Sie mit journalctl das Journal des Systemd-Protokolls auswerten. Mit dem Kommando journalctl -f -u NetworkManager werfen Sie zum anderen in Echtzeit einen Blick auf das Log und filtern dabei gleich die Ausgaben von NetworkManager heraus (Listing 9).
Listing 9
$ journalctl -f -u NetworkManager [...] Mai 22 23:21:45 ontario NetworkManager[485]: <warn> [1590182505.2987] dispatcher: (44) /etc/NetworkManager/dispatcher.d/30-mount-diskstation failed (failed): Script '/etc/NetworkManager/dispatcher.d/30-mount-diskstation' exited with error status 2. $ nmcli monitor enp0s31f6: Verbindung »LAN1« wird verwendet enp0s31f6: wird verbunden (wird vorbereitet) NetworkManager ist jetzt im Zustand »wird verbunden« [...] NetworkManager ist jetzt im Zustand »verbunden« Verbindungszustand ist jetzt »vollständig«
Diese Kommandos liefert Ihnen einen allgemeinen Überblick über die Aktionen des Netzwerkmanagers. Um nun aber gezielt nach einem Fehler zu forschen, empfiehlt es sich, an kritischen Stellen per logger selbst in das Systemd-Log zu schreiben. Ein Beispiel dafür finden Sie in Listing 10. Dabei können Sie auf die von NetworkManager für das Dispatching verwendeten Variablen $0 (Skript-Name), $1 (Netzwerkgerät) und $2 (Aktion) zurückgreifen, aber auch die von der Dispatcher-Funktion bereitgestellten Umgebungsvariablen wie $CONNECTION_UUID oder $IP4_DOMAINS verwenden (Listing 11).
Listing 10
#!/bin/bash logger "LOGGER: Führe Skript $0 aus." if [ "$2" = "up" ]; then logger "LOGGER: Netzwerkgerät: $1, Aktion: $2" logger "LOGGER: Umgebung: CONNECTION_UUID=$CONNECTION_UUID, IP4_DOMAINS=$IP4_DOMAINS" fi
Listing 11
$ journalctl -f | grep LOGGER
[...]
Mai 22 23:36:47 ontario root[16135]: LOGGER: Führe Skript /etc/NetworkManager/dispatcher.d/30-mount-diskstation aus.
Mai 22 23:36:47 ontario root[16136]: LOGGER: Netzwerkgerät: enp0s31f6, Aktion: up
Mai 22 23:50:31 ontario root[18811]: LOGGER: Umgebung: CONNECTION_UUID=2911db45-3eff-3b74-9c87-4c36e0290693, IP4_DOMAINS=fritz.box
Fazit
Die vom Dispatcher zur Verfügung gestellte Bandbreite an Möglichkeiten ist schier unbegrenzt: Alles, was Sie im System auf Dateiebene ändern können, lässt sich mithilfe von Dispatcher-Skripten umsetzen und situationsabhängig automatisieren. Die größte Schwierigkeit besteht darin, an Log-Ausgaben zu kommen oder die beim Dispatching befüllten Umgebungsvariablen einzusehen. Mit den entsprechenden Tricks lassen sich diese Hürden jedoch schnell nehmen.
Ein passendes Dispatcher-Skript schreibt sich allerdings nicht von alleine. Bis alles wie gewünscht funktioniert, braucht es etwas Zeit – besonders, wenn Sie noch nicht viel mit Shell-Skripten gearbeitet haben. Ein Dispatcher-Skript ist jedoch ein ideales Fallbeispiel für die individuelle Gestaltung des eigenen Systems: Schließlich lassen sich mit dem Dispatcher Probleme lösen, für die es keine vorgefertigten Pakete zur Installation gibt.
Wie aber schon der Autor der Xkcd-Webcomics zum Thema Automatisierung festgestellt hat [2], unterscheidet sich die in der Theorie erhoffte Zeitersparnis vom Zeitgewinn in der Realität oft ganz erheblich.
Infos
-
NetworkManager: https://developer.gnome.org/NetworkManager/stable/NetworkManager.html
-
Xkcd über Automatisierung: https://xkcd.com/1319/





