Ihr kennt das vielleicht: Zu Hause läuft ein NAS oder ein Cloud-Speicher, den ihr per Samba oder WebDAV einbindet. Aber nur, wenn ihr auch wirklich im Heimnetz seid – niemand will im Café warten, weil der Laptop verzweifelt versucht, eine Freigabe zu mounten, die gerade schlicht nicht erreichbar ist.
Die naheliegende Lösung: /etc/fstab plus ein Dispatcher-Skript für NetworkManager, das anhand von SSID oder Server-Erreichbarkeit automatisch mountet. Klingt nach einer Feierabend-Sache. Ist es aber nicht ganz – ich bin dabei über drei Stolperfallen gestolpert, die einem erst auffallen, wenn der Rechner runterfährt, aufwacht oder in den Standby soll. Genau die drei nehme ich hier mit euch durch.
Getestet habe ich das Ganze auf Arch Linux, aber das Setup ist nicht Arch-spezifisch: Solange eure Distribution systemd und NetworkManager mitbringt – also etwa auch Fedora, Ubuntu, Debian oder openSUSE –, funktioniert alles hier eins zu eins.
Der Grundaufbau
Netzwerkfreigaben bekommen in der fstab klassischerweise noauto, damit sie beim Boot nicht sofort, sondern erst bei Bedarf eingehängt werden:
//server/home /mnt/server/home cifs credentials=/etc/samba/server.credentials,rw,uid=1000,gid=100,noauto,_netdev 0 0
//server/data /mnt/server/data cifs credentials=/etc/samba/server.credentials,rw,uid=1000,gid=100,noauto,_netdev 0 0
Für den Mount-Typ selbst gibt’s je nach Protokoll gute Anleitungen im Arch Wiki, etwa zu Samba/CIFS und zu davfs2 für WebDAV – beide funktionieren unabhängig von der Distribution, solange cifs-utils beziehungsweise davfs2 installiert sind.
Das eigentliche Mounten übernimmt dann ein Skript unter /etc/NetworkManager/dispatcher.d/. NetworkManager ruft solche Skripte bei jeder Verbindungsänderung auf und übergibt Interface und Status (up, down, pre-down und ein paar weitere) mit – alle Details dazu stehen in der NetworkManager-dispatcher-Manpage. Ein simples Skript prüft die aktive WLAN-SSID und mountet, wenn’s passt:
#!/bin/bash
IFACE="$1"
STATUS="$2"
case "$STATUS" in
up)
SSID=$(nmcli -t -f active,ssid dev wifi | awk -F: '$1 == "yes" {print $2; exit}')
if [[ "$SSID" == "MeinHeimnetz" ]]; then
mount /mnt/server/home
mount /mnt/server/data
fi
;;
down)
umount /mnt/server/home
umount /mnt/server/data
;;
esac
Fertig, oder? Nicht ganz. Sobald ihr das System runterfahrt, aus dem Standby weckt oder in den Standby schickt, zeigt sich, dass die Sache Tücken hat.
Warum nicht einfach GVfs?
Ihr fragt euch jetzt vielleicht, wieso ich mir das mit fstab und Dispatcher-Skripten überhaupt antue – GNOME bietet über „Mit Server verbinden“ im Dateimanager doch einen viel einfacheren Weg, Netzwerkfreigaben per SMB oder WebDAV einzubinden. Genau da liegt für mich das Problem.
Solche Mounts laufen nicht über den Kernel, sondern über GVfs, GNOMEs virtuelles Dateisystem. Programme, die die GIO-Bibliothek nutzen – fast alle GTK-Anwendungen, allen voran der Dateimanager selbst –, sprechen Freigaben direkt über eigene URIs wie smb:// oder dav:// an und zeigen entsprechend auch Vorschaubilder und Metadaten korrekt an. Für Programme, die das nicht können, blendet GVfs die Freigabe zusätzlich unter /run/user/<uid>/gvfs als ganz normalen Pfad ein. Diese Brücke läuft tatsächlich über FUSE – GVfs selbst ist zwar kein klassisches FUSE-Dateisystem, sondern eine eigene Architektur mit Daemon-Prozessen pro Protokoll, stellt aber genau für diesen Fall über gvfsd-fuse einen POSIX-kompatiblen Pfad bereit.
Genau diese Brücke ist bei mir der Knackpunkt: Nicht jedes Programm kommt damit zuverlässig klar. Konkret zeigt sich das bei mir in einem Markdown-Editor, in den ich auch Bilder für Artikel einbinde. Der Dateimanager zeigt die Bilder auf dem Netzlaufwerk ganz normal an, weil er GVfs nativ spricht. Der Markdown-Editor dagegen zeigt für dasselbe Bild nur einen Platzhalter – die Einbindung über den FUSE-Pfad funktioniert schlicht nicht zuverlässig, obwohl die Datei nachweislich da ist.

Ein klassischer Kernel-Mount über CIFS oder davfs2, wie im Rest dieses Artikels beschrieben, taucht dagegen als ganz normaler, stabiler POSIX-Pfad im Dateisystem auf – ohne Sonderbehandlung, für jedes Programm gleich. Der Mehraufwand mit fstab und Dispatcher-Skripten zahlt sich also gerade dann aus, wenn ihr Freigaben nicht nur im Dateimanager, sondern in ganz unterschiedlichen Anwendungen zuverlässig nutzen wollt.
Problem 1: Der Rechner fährt nicht mehr sauber runter
Fehlt in der fstab die Option _netdev, weiß systemd nicht, dass es sich hier um eine Netzwerkfreigabe handelt. Beim Shutdown kann es dann passieren, dass systemd versucht auszuhängen, nachdem das Netzwerk schon weg ist – der umount blockiert, bis der Job-Timeout greift, und euer System hängt beim Herunterfahren fest.
_netdev behebt das, weil systemd damit die richtige Reihenfolge kennt: erst aushängen, dann Netzwerk kappen. Wichtig ist außerdem, dass ein Dispatcher-Skript nicht nur auf down, sondern auf pre-down reagiert – der Status feuert, bevor die Verbindung wirklich fällt, während down schon danach kommt und für ein sauberes Aushängen zu spät ist. Damit das klappt, braucht es zusätzlich einen Symlink im Unterordner pre-down.d/.
Problem 2: Nach dem Aufwachen hängt sich der Dateimanager auf
Ein mount-Aufruf für CIFS oder WebDAV läuft im Kernel und kann bei nicht erreichbarem Server ziemlich lange blockieren – gerade kurz nach dem Aufwachen, wenn DNS oder Routing noch nicht ganz da sind. NetworkManager wartet standardmäßig synchron, bis so ein Dispatcher-Skript fertig ist, bevor es weitermacht. Hängt der mount-Aufruf, hängt bei euch plötzlich auch der Dateimanager oder die Netzwerkanzeige, weil die vom Verbindungsstatus abhängen.
Die Lösung: Mount-Versuche einfach im Hintergrund laufen lassen, damit das Dispatcher-Skript selbst sofort zurückkehrt, egal wie lange der eigentliche Mount braucht.
run_async() {
( "$@" ) &>/dev/null &
disown
}
Problem 3: Der Standby funktioniert plötzlich nicht mehr
Und hier wird’s spannend. Mit der Lösung aus Problem 2 stolpert ihr in ein neues, deutlich fieseres Problem, das sich in meinem Fall so äußerte: Der Bildschirm geht aus, aber Tastaturbeleuchtung und LEDs bleiben an – ihr müsst hart abschalten. Was war passiert?
Der mount-Syscall für CIFS oder davfs blockiert bei nicht erreichbarem Server im sogenannten D-Zustand (uninterruptible sleep) – einem Zustand, den kein Signal unterbricht, auch SIGKILL nicht. Bevor der Kernel tatsächlich schlafen legt, versucht er, alle Prozesse einzufrieren. Ein Prozess im D-Zustand lässt sich aber nicht einfrieren, und der ganze Standby hängt fest, bis die Netzwerkoperation im Kernel von selbst aufgibt – das kann durchaus ein paar Minuten dauern.
Weil die Mount-Versuche aus Problem 2 jetzt länger im Hintergrund weiterlaufen, steigt eben auch die Chance, dass genau in dem Moment, in dem ihr in Standby gehen wollt, so ein blockierender Verbindungsversuch gerade aktiv ist.
Der zuverlässige Ausweg: Vor jedem mount erst mit einem echten Userspace-Verbindungstest prüfen, ob der Server überhaupt erreichbar ist – so einer lässt sich per Timeout wirklich abbrechen, zum Beispiel über Bashs eingebautes /dev/tcp:
tcp_reachable() {
local HOST="$1"
local PORT="$2"
local TIMEOUT_SECONDS="${3:-2}"
timeout "${TIMEOUT_SECONDS}s" bash -c "echo >/dev/tcp/${HOST}/${PORT}" &>/dev/null
}
Nur wenn der Test klappt, folgt der eigentliche mount. Damit landet ihr so gut wie nie mehr im riskanten, blockierenden Kernel-Connect, weil ihr zu dem Zeitpunkt schon wisst, dass der Server da ist.
Die Kombination, die bei mir funktioniert
Am Ende braucht ein robustes Setup vier Zutaten:
- _netdev in der fstab, damit systemd Netzwerkfreigaben beim Herunterfahren richtig einordnet.
- pre-down-Handling samt Symlink in pre-down.d/, damit das Aushängen garantiert vor dem Verbindungsabbau passiert – mit Timeout und Lazy-Unmount als Backup, falls der normale umount mal zickt.
- Asynchrone Mounts im up-Fall, damit NetworkManager und alles, was davon abhängt, nicht blockiert.
- Ein Erreichbarkeitstest vor jedem mount, damit der eigentliche, potenziell blockierende Kernel-Connect gar nicht erst passiert.
Dazu noch ein kleiner Healthcheck per systemd-Timer, der ein paar Minuten nach dem Boot und danach regelmäßig nachschaut, ob die Freigaben wirklich da sind, und notfalls nachhilft. Praktisch, falls der auslösende Netzwerk-Event mal zu früh oder zu spät kommt.
Alle Dateien im Überblick

Damit ihr das Ganze direkt nachbauen könnt, hier der komplette Satz an Dateien. Ich habe die Beispielnamen aus meinem eigenen Setup (ein Samba-Server namens bender, WebDAV via tuxedo) durch generische Platzhalter ersetzt – die müsst ihr natürlich an eure eigene Umgebung anpassen.
/etc/fstab – die beiden Freigaben, einmal Samba, einmal WebDAV:
//server/home /mnt/server/home cifs credentials=/etc/samba/server.credentials,rw,uid=1000,gid=100,noauto,_netdev,x-systemd.mount-timeout=15s,soft 0 0
//server/data /mnt/server/data cifs credentials=/etc/samba/server.credentials,rw,uid=1000,gid=100,noauto,_netdev,x-systemd.mount-timeout=15s,soft 0 0
https://cloud.example.com/remote.php/dav/files/user /mnt/webdav davfs noauto,_netdev,uid=1000,gid=100,x-systemd.automount,x-systemd.idle-timeout=300,x-systemd.mount-timeout=15s 0 0
Die fstab referenziert die Zugangsdaten nur, gespeichert werden sie in eigenen Dateien – schon damit das Passwort nicht im Klartext in einer Datei steht, die jeder lesen kann.
/etc/samba/server.credentials – Zugangsdaten für die Samba-Freigabe:
username=maxmuster
password=GeheimesPasswort123
/etc/davfs2/secrets – Zugangsdaten für die WebDAV-Freigabe, referenziert wird hier der Mountpunkt statt einer Option in der fstab:
/mnt/webdav maxmuster GeheimesPasswort123
Beide Dateien gehören root und dürfen für niemand sonst lesbar sein:
$ sudo chmod 600 /etc/samba/server.credentials /etc/davfs2/secrets
$ sudo chown root:root /etc/samba/server.credentials /etc/davfs2/secrets
/etc/NetworkManager/dispatcher.d/lib/mount-helpers.sh – die gemeinsame Bibliothek, die alle anderen Skripte einbinden:
#!/bin/bash
log() {
[[ "$DEBUG" == "1" ]] && logger -t "$LOG_TAG" -- "$1"
}
run_async() {
( "$@" ) &>/dev/null &
disown
}
tcp_reachable() {
local HOST="$1"
local PORT="$2"
local TIMEOUT_SECONDS="${3:-2}"
timeout "${TIMEOUT_SECONDS}s" bash -c "echo >/dev/tcp/${HOST}/${PORT}" &>/dev/null
}
mount_with_retry() {
local MOUNT="$1"
local MAX_ATTEMPTS="${2:-3}"
local SLEEP_SECONDS="${3:-2}"
local MOUNT_TIMEOUT="${4:-10}"
if mountpoint -q "$MOUNT"; then
log "$MOUNT ist bereits eingehängt"
return 0
fi
log "Hänge $MOUNT ein"
local OUT ATTEMPT
for ((ATTEMPT = 1; ATTEMPT <= MAX_ATTEMPTS; ATTEMPT++)); do
if OUT=$(timeout "${MOUNT_TIMEOUT}s" mount "$MOUNT" 2>&1); then
log "$MOUNT erfolgreich eingehängt"
return 0
fi
log "Versuch $ATTEMPT/$MAX_ATTEMPTS für $MOUNT fehlgeschlagen (evtl. Timeout nach ${MOUNT_TIMEOUT}s): $OUT"
[[ "$ATTEMPT" -lt "$MAX_ATTEMPTS" ]] && sleep "$SLEEP_SECONDS"
done
log "Alle Versuche für $MOUNT fehlgeschlagen"
return 1
}
umount_with_fallback() {
local MOUNT="$1"
local TIMEOUT_SECONDS="${2:-5}"
if ! mountpoint -q "$MOUNT"; then
log "$MOUNT ist nicht eingehängt"
return 0
fi
log "Hänge $MOUNT aus"
if timeout "${TIMEOUT_SECONDS}s" umount "$MOUNT"; then
log "$MOUNT erfolgreich ausgehängt"
return 0
fi
log "Normaler Unmount von $MOUNT fehlgeschlagen, versuche Lazy Unmount"
if umount -l "$MOUNT"; then
log "$MOUNT per Lazy Unmount ausgehängt"
return 0
fi
log "$MOUNT konnte nicht ausgehängt werden"
return 1
}
/etc/NetworkManager/dispatcher.d/90-server-mount – Samba-Freigabe, gebunden an eine bestimmte WLAN-SSID oder ans Kabelnetz:
#!/bin/bash
DEBUG=1
LOG_TAG="server-mount"
LIB="/etc/NetworkManager/dispatcher.d/lib/mount-helpers.sh"
if [[ -r "$LIB" ]]; then
source "$LIB"
else
logger -t "$LOG_TAG" -- "Bibliothek $LIB nicht gefunden, breche ab"
exit 1
fi
IFACE="$1"
STATUS="$2"
MOUNTS=(
"/mnt/server/home"
"/mnt/server/data"
)
mount_server() {
if ! tcp_reachable server 445 2; then
log "server auf Port 445 nicht erreichbar, überspringe Mount-Versuch"
return 1
fi
for MOUNT in "${MOUNTS[@]}"; do
mount_with_retry "$MOUNT" 3 2 10
done
}
umount_server() {
for MOUNT in "${MOUNTS[@]}"; do
umount_with_fallback "$MOUNT" 5
done
}
log "Dispatcher gestartet: Interface=$IFACE, Status=$STATUS"
case "$STATUS" in
up)
if [[ "$IFACE" == wl* ]]; then
SSID=$(nmcli -t -f active,ssid dev wifi |
awk -F: '$1 == "yes" {print $2; exit}')
log "Aktive WLAN-SSID: $SSID"
if [[ "$SSID" == "MeinHeimnetz" ]]; then
run_async mount_server
fi
elif [[ "$IFACE" == enp* || "$IFACE" == eth* ]]; then
run_async mount_server
fi
;;
pre-down|vpn-pre-down)
log "Netzwerkverbindung wird beendet – Mounts aushängen"
umount_server
;;
esac
log "Dispatcher beendet"
exit 0
/etc/NetworkManager/dispatcher.d/90-webdav-mount – WebDAV-Freigabe, die einfach nur einen erreichbaren Cloud-Server voraussetzt:
#!/bin/bash
DEBUG=1
LOG_TAG="webdav-mount"
LIB="/etc/NetworkManager/dispatcher.d/lib/mount-helpers.sh"
if [[ -r "$LIB" ]]; then
source "$LIB"
else
logger -t "$LOG_TAG" -- "Bibliothek $LIB nicht gefunden, breche ab"
exit 1
fi
IFACE="$1"
STATUS="$2"
MOUNTPOINT="/mnt/webdav"
HOST="cloud.example.com"
mount_webdav() {
if ! tcp_reachable "$HOST" 443 3; then
log "$HOST auf Port 443 nicht erreichbar, überspringe Mount-Versuch"
return 1
fi
mount_with_retry "$MOUNTPOINT" 3 2 10
}
log "Dispatcher gestartet: Interface=$IFACE, Status=$STATUS"
case "$STATUS" in
up)
run_async mount_webdav
;;
pre-down|vpn-pre-down)
log "Netzwerkverbindung wird beendet – Mount aushängen"
umount_with_fallback "$MOUNTPOINT" 5
;;
esac
log "Dispatcher beendet"
exit 0
Für beide Skripte braucht ihr zusätzlich noch die passenden Symlinks, damit pre-down garantiert vor dem Verbindungsabbau feuert:
$ sudo ln -s /etc/NetworkManager/dispatcher.d/90-server-mount \
/etc/NetworkManager/dispatcher.d/pre-down.d/90-server-mount
$ sudo ln -s /etc/NetworkManager/dispatcher.d/90-webdav-mount \
/etc/NetworkManager/dispatcher.d/pre-down.d/90-webdav-mount
/usr/local/bin/mount-healthcheck.sh – das Sicherheitsnetz, das regelmäßig nachschaut:
#!/bin/bash
DEBUG=1
LOG_TAG="mount-healthcheck"
LIB="/etc/NetworkManager/dispatcher.d/lib/mount-helpers.sh"
if [[ -r "$LIB" ]]; then
source "$LIB"
else
logger -t "$LOG_TAG" -- "Bibliothek $LIB nicht gefunden, breche ab"
exit 1
fi
log "Healthcheck gestartet"
SSID=$(nmcli -t -f active,ssid dev wifi 2>/dev/null |
awk -F: '$1 == "yes" {print $2; exit}')
if [[ "$SSID" == "MeinHeimnetz" ]] || ping -c 1 -W 1 server >/dev/null 2>&1; then
mount_with_retry "/mnt/server/home" 2 3
mount_with_retry "/mnt/server/data" 2 3
else
log "server im aktuellen Netz nicht erreichbar, überspringe"
fi
mount_with_retry "/mnt/webdav" 2 3
log "Healthcheck beendet"
exit 0
/etc/systemd/system/mount-healthcheck.service und mount-healthcheck.timer – Systemd-Einheiten, die das Healthcheck-Skript 60 Sekunden nach dem Boot und danach alle 10 Minuten anstoßen:
[Unit]
Description=Prueft und stellt Netzwerk-Mounts sicher
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
TimeoutStartSec=120
ExecStart=/usr/local/bin/mount-healthcheck.sh
[Unit]
Description=Fuehrt den Mount-Healthcheck 60s nach Boot und danach alle 10 Minuten aus
[Timer]
OnBootSec=60s
OnUnitActiveSec=10min
AccuracySec=30s
[Install]
WantedBy=timers.target
Aktivieren nicht vergessen:
$ sudo systemctl daemon-reload
$ sudo systemctl enable --now mount-healthcheck.timer
/usr/lib/systemd/system-sleep/90-cancel-network-mounts – optionales Sicherheitsnetz vor dem Suspend:
#!/bin/bash
case "$1/$2" in
pre/*)
logger -t sleep-mount-guard "Breche evtl. laufende Netzwerk-Mount-Versuche vor Suspend ab"
pkill -9 -f 'mount\.cifs' 2>/dev/null
pkill -9 -f 'mount\.davfs' 2>/dev/null
;;
esac
exit 0
Alle Skripte müssen ausführbar sein:
$ sudo chmod +x /etc/NetworkManager/dispatcher.d/lib/mount-helpers.sh \
/etc/NetworkManager/dispatcher.d/90-server-mount \
/etc/NetworkManager/dispatcher.d/90-webdav-mount \
/usr/local/bin/mount-healthcheck.sh \
/usr/lib/systemd/system-sleep/90-cancel-network-mounts
Lange Reder, kurzer Sinn
Automatisches Einhängen von Netzwerkfreigaben über NetworkManager funktioniert gut, ist aber kein Fünf-Minuten-Job, wie es die Doku vermuten lässt. Wenn ihr nur den mount-Befehl in ein up-Skript packt, holt euch früher oder später eines der drei Probleme ein – meistens genau dann, wenn ihr unterwegs seid und kein Log zur Hand habt.
Mit _netdev, korrektem pre-down-Timing, asynchroner Ausführung und einem echten Erreichbarkeitstest vor jedem Mount seid ihr auf der sicheren Seite. Und das Muster lässt sich eins zu eins auf andere netzwerkabhängige Automatisierungen übertragen, etwa VPN-Verbindungen oder Backup-Jobs, die nur im richtigen Netz laufen sollen.










