mountctl: Eine Alternative zur fstab, wenn mount-Versuche ins Netzwerk aus den unterschiedlichsten Gründen fehlschlagen oder zu nervenden Störungen führen
Inhaltsübersicht über die Kapitel dieses Artikels:
|
...*hmmm*.... fast eine gute Frage. Auf die ich allerdings keine bessere Antwort habe als "Weil es funktioniert!". Dabei ist mir natürlich bewusst, dass nicht alles was funktioniert auch wirklich sinnvoll und gut ist. Die bessere Frage wäre vielleicht "Muss eine Lösung wirklich so kompliziert sein?" Aber auch auf die Frage habe ich keine gescheite Antwort, außer vielleicht weil es zum jetzigen Zeitpunkt im aktuellen Debian 9 für eine tatsächlich komplizierte Anforderung noch keine einfache und wirklich funktionierende Lösung gibt. Fakt ist, das Mounten von Netzwerkplatten auf einem (mobilen?) Enduser-Desktop-PC oder mit wechselnden Anwendern ist meiner Meinung nach unter Linux bei solcherart flexiblen Anforderungen absolut unbefriedigend gelöst und von haufenweise unschönen oder sogar problematischen Nebeneffekten begleitet. Fakt ist, die fstab entstammt einer Zeit, zu der vermutlich noch niemand das willkürliche Ein- und Ausschalten eines (mobilen?) Desktop-PCs und das dynamische Mounten und Umounten von Netzwerkplatten an wechselnden Standorten im Sinne hatte, wozu auch noch die User selber berechtigt sein sollen. Die damalige Zielsetzung war vermutlich viel mehr auf klassische Server in Rechenzentren gerichtet. Die Stärken der fstab liegen auch heute noch ganz sicher im statischen System, einschalten, mounten und dauerhaft laufen lassen. Dieser grundsätzliche Gedanke ist aber völlig inkompatibel zu einem Laptop, der sich mal hier, mal dort mit irgendwelchen Netzen verbindet, und mal die Netzwerkplatten mountet und beim nächsten Einschalten eben nicht. Also scheint die Sachlage doch etwas komplizierter zu sein, als anfangs angenommen.
Und weil das meiner Meinung nach so eine komplizierte Angelegenheit ist, welche die fstab tatsächlich nicht akzeptabel handhaben kann, ist meine Lösung auch dementsprechend (vermeintlich) kompliziert ausgefallen. Ich habe zuvor vieles getestet, um vielleicht mit dem einen oder anderen Verfahren eine vernünftige Lösung einzustellen. Ich habe versuchsweise mit PAM-Mounts experimentiert, mit automounts, traditionell mit der fstab sowieso, mit systemd - irgendwie war nichts dabei, was meinen Anspruch an 'reproduzierbar und stabil' auch wirklich zufriedenstellend erfüllt hat. Irgendein ungelöstes Problem bestand immer. Um die Zusammenhänge und Probleme besser zu verstehen, sind jetzt jedoch ein paar weitergehende Erläuterungen und Betrachtungen notwendig.
Dabei hilft ein kurzer Blick auf einen Musterausschnitt einer meiner frühen fstab's, der neben weiteren Einträgen prinzipiell genau so und identisch auf all unseren Systemen eingerichtet werden sollte. Das ist übrigens eine unverzichtbare und alternativlose Prämisse: Ich will keinesfalls geräte-individuelle Einstellungen einrichten müssen... der Aufwand wäre mir viel zu hoch. Eine Lösung muss für alle Systeme anwendbar sein, idealerweise durch einfaches Kopieren von einigen wenigen immer gleichen Dateien an immer die gleichen Zielorte. So sahen also früher beispielhaft unsere Remote-Mounts aus, die unabhängig von der Anmeldung eines Users bei jedem Rechnerstart gemountet wurden:
# Admin-Shares //172.1.1.2/HD1 /media/HD1 cifs credentials=/home/thomas/.smbcred,uid=thomas,gid=thomas,rw,auto,nosuid,nodev,noexec,nouser,async //172.1.1.2/HD2 /media/HD2 cifs credentials=/home/thomas/.smbcred,uid=thomas,gid=thomas,rw,auto,nosuid,nodev,noexec,nouser,async //172.1.1.2/SSD /media/SSD cifs credentials=/home/thomas/.smbcred,uid=thomas,gid=thomas,rw,auto,nosuid,nodev,noexec,nouser,async //172.1.1.2/Install /media/Install cifs credentials=/home/thomas/.smbcred,uid=thomas,gid=thomas,rw,auto,nosuid,nodev,noexec,nouser,async
# Public Shares //172.1.1.2/Film /media/Film cifs credentials=/home/thomas/.smbcred,uid=thomas,gid=sambauser,rw,auto,nosuid,nodev,noexec,nouser,async //172.1.1.2/Musik /media/Musik cifs credentials=/home/thomas/.smbcred,uid=thomas,gid=sambauser,rw,auto,nosuid,nodev,noexec,nouser,async //172.1.1.2/Buch /media/Buch cifs credentials=/home/thomas/.smbcred,uid=thomas,gid=sambauser,rw,auto,nosuid,nodev,noexec,nouser,async //172.1.1.2/Foto /media/Foto cifs credentials=/home/thomas/.smbcred,uid=thomas,gid=sambauser,rw,auto,nosuid,nodev,noexec,nouser,async //172.1.1.2/Downloads /media/Downloads cifs credentials=/home/thomas/.smbcred,uid=thomas,gid=sambauser,rw,auto,nosuid,nodev,noexec,nouser,async //172.1.1.2/DatenAlle /media/DatenAlle cifs credentials=/home/thomas/.smbcred,uid=thomas,gid=sambauser,rw,auto,nosuid,nodev,noexec,nouser,async
# Private Shares //172.1.1.2/homes/SHome /home/thomas/SHome cifs credentials=/home/thomas/.smbcred,uid=thomas,gid=thomas,rw,auto,nosuid,nodev,nouser,async //172.1.1.2/homes/SHome /home/silvia/SHome cifs credentials=/home/thomas/.smbcred,uid=silvia,gid=silvia,rw,auto,nosuid,nodev,nouser,async //172.1.1.2/homes/SHome /home/manuel/SHome cifs credentials=/home/thomas/.smbcred,uid=manuel,gid=manuel,rw,auto,nosuid,nodev,nouser,async //172.1.1.2/homes/SHome /home/steffi/SHome cifs credentials=/home/thomas/.smbcred,uid=steffi,gid=steffi,rw,auto,nosuid,nodev,nouser,async //172.1.1.2/homes/SHome /home/bibi/SHome cifs credentials=/home/thomas/.smbcred,uid=bibi,gid=bibi,rw,auto,nosuid,nodev,nouser,async //172.1.1.2/homes/SHome /home/marco/SHome cifs credentials=/home/thomas/.smbcred,uid=marco,gid=marco,rw,auto,nosuid,nodev,nouser,async |
Der obenstehende fstab-Beispielabschnitt sieht eigentlich völlig normal und unspektakulär aus - Admin-Shares, auf die nur ich zugreifen darf, Public-Shares, die von allen verwendet werden und persönliche Verzeichnisse, auf die nur der User selber Zugriff hat. Aber alle Mounts wurden mit meinen Samba-Rechten eingerichtet. Für den Samba-Server gab es also nur einen einzigen Anwender, und zwar immer nur mich. Es blieb dabei völlig unberücksichtigt, wer sich tatsächlich am PC angemeldet hat, was zu Folge hatte, dass individuelle Samba-Berechtigungen damit quasi komplett ausgehebelt sind. Die Besonderheit an dieser fstab ist also der Umstand, dass sie einfach nicht zufriedenstellend funktioniert. Aber diese Besonderheit ist gleichzeitig nach meinen Erfahrungen auch Linux-Normalität. Wenn man eine Zeitlang regelmäßig diverse Linux-Foren besucht, erkennt man, dass das ein oft wiederkehrendes Problem ist, an dem unzählige private Heimnetz-Admins scheitern. Und welche Probleme genau gibt es damit...?... einige! Um einmal die bei uns vorhandenen Probleme zu verstehen, muss man allerdings vorher noch einige Rahmenbedingungen unseres Netzwerkes und der Art und Weise unserer Hardware-Nutzung kennen:
Alle unsere Rechner sind so eingestellt, dass typische Anwender-Daten zentral auf dem Server gespeichert werden. Dateien wie Office-Dokumente, Mails, Kontakte und Termindaten, etc. landen alle auf dem Server. Alle PCs haben aber trotzdem noch für jeden User ein lokales Homedir auf dem jeweiligen PC eingerichtet. | |
Es gibt bei uns Multiuser-PC/Laptops, an denen sich je nach Bedarf verschiedene Personen anmelden, die natürlich an jedem PC jeweils ihre eigenen Daten sehen wollen. Wer sich wann und wo anmeldet, ist willkürlich. | |
Es gibt Laptops, die sich via WLAN anmelden und die von Fall zu Fall ebenfalls von verschiedenen Personen jeweils mit ihrem eigenen Account und ihren eigenen Daten genutzt werden wollen. | |
Unsere Laptops melden sich zum Teil auch an wechselnden WLAN-Netzen an. Zum Beispiel meldet sich der Laptop meines Sohns Zuhause an, in der Uni und bei der Freundin. Ich wechsel den WLAN-Anbieter mit meinem Laptop auf Reise täglich. Das heißt, die fstab soll die Mounts durchführen, wenn wir uns zuhause verbinden, sie darf aber nicht blockieren, wenn wir uns in fremden Netzen anmelden. |
Aus diesem Umfeld und diesen speziellen Anforderungen resultieren in der Folge einige Probleme, für die eine Lösung notwendig ist.
Die fstab wird beim Systemstart abgearbeitet wird, also ein Zeitpunkt, an dem nicht bekannt ist, wer sich auf einem Multiuser-PC irgendwann anmelden wird und ob sich vielleicht sogar nacheinander verschiedene User anmelden. Also müssen immer alle Mounts auf allen Clients quasi vorauseilend mit einer umfassenden Berechtigung hergestellt werden, eine Berechtigung, die tatsächlich alle Fälle umfasst. Die Folge ist, auf dem Server ist nicht transparent ersichtlich, welcher User letztendlich die Mounts verwendet hat. User- oder Gruppenbezogene Samba-Berechtigungen werden damit quasi außer Kraft gesetzt. | |
Weil beim Systemstart unbekannt ist, ob und wer sich anmeldet, müssen also immer (quasi vorauseilend) alle Mounts hergestellt werden, auch die, die für diese Anmeldung gar nicht gebraucht werden oder wenn spezielle Ressourcen an 'andere‘ User gebunden sind. | |
Wenn die Laptops sich via WLAN verbinden, schlägt der Mount beim Systemstart immer fehl, weil die fstab vom System abgearbeitet wird, bevor das Netzwerk gestartet und verbunden ist und die gewünschte Ressource noch nicht erreichbar ist. | |
Bei einem an verschiedenen Standorten eingesetzten mobilen Laptop sollen die Freigaben des Heimservers nur verbunden werden, wenn der Heimserver entweder im eigenen Netz oder unterwegs via OpenVPN überhaupt erreichbar ist. | |
Bei Einsatz eines Network-Managers (NWM) und einer WLAN-Verbindung passiert es oft oder regelmäßig, dass der NMW beim Shutdown des Rechners die WLAN-Netzwerkverbindung trennt, bevor die Mounts getrennt sind. Daraus resultieren dann beim Runterfahren des Rechners diese 90-Sekunden-Stopjobs beim Versuch des Umounts, was ja jetzt gar nicht mehr möglich ist und in Folge dessen wird der Shutdown-Prozess blockiert. |
Kurz zusammengefasst bestehen also diese Probleme:
Die fstab unterscheidet nicht nach User und wartet nicht aufs Netzwerk. Die Credentials zum Mount und somit auch die benutzerbezogenen Samba-Berechtigungen sind nicht an den User gebunden, der letztlich die Netzwerk-Ressourcen nutzt. | |
PAM-Mount unterscheidet zwar nach User, wartet aber auch nicht aufs Netzwerk oder prüft die Verfügbarkeit des Netzes. | |
Systemd-Mounts können zwar auf eine Netzwerkverbindung warten, aber nicht erkennen, ob es das richtige Netzwerk mit Samba-Server ist, und sie unterscheiden ebenfalls keine User. Die Mounts erfolgen im Boot-Prozess, wo wiederum nicht bekannt ist, welcher User sich später überhaupt anmelden wird. | |
In der Bootphase verbundene Mounts sind aktiv, obwohl sich noch gar kein User angemeldet hat und sie bleiben weiter geöffnet, nachdem sich der User abgemeldet hat | |
Warten bis das Netzwerk bereit ist, bedeutet nicht auf irgendein Netz zu warten, sondern auch festzustellen, ob der Samba-Server in diesem Netz überhaupt erreichbar ist. | |
Automounts warten weder aufs Netzwerk, noch unterscheiden sie nach User… der User bekommt, was er öffnet (sofern er berechtigt ist, das Netzwerk verbunden ist und die Ressource verfügbar ist). Wie bei der fstab sind User-Bezogene Samba-Berechtigungen nicht verfügbar. | |
Es gibt so gut wie keine Unterstützung bzw. Abstimmung zwischen Mount und Netzwerkverbindung für On-the-fly-Mounts via OpenVPN, wenn unterwegs fremde Netze via WLAN verbunden sind. |
In den folgenden Kapiteln versuche ich jetzt nach und nach die hier zuvor beschriebenen Probleme zu lösen. Aber die hier gefundenen Problemlösungen sind viel mehr als nur starr fokussierte Lösungen, es sind teilweise auch 'integrierte' Problemlösungen. Das bedeutet, sie funktionieren zwar an sich und natürlich auch ohne sich um anderes zu kümmern, aber zusätzlich eben auch im Zusammenspiel mit anderen Komponenten auf höherer und integrativer Ebene. Ein hochgradig relevanter Aspekt ist hier z.B. meine Backup-Strategie, die ich mit dem Programm xtbak realisiert habe. Das bezieht sich auf die Organisation der Speicherorte im Netzwerk Und ich hatte hier bereits mehrfach die auf Reise oder unterwegs bestehenden Probleme erwähnt, wenn der eigene Samba-Server auch unterwegs via OpenVPN erreicht werden soll. Genau vor diesem Hintergrund war ein abgestimmtes Zusammenwirken zwischen den Komponenten (selnic, meiner Firewall und der OpenVPN-Installation) das höhere Ziel.
|
Problem 1: Ist unser Server über das verbundene Netzwerk überhaupt erreichbar, um erfolgreich mounten zu können?
Die Frage mag auf den ersten Blick merkwürdig klingen, wenn wir doch eigentlich erwarten, dass er mit dem Einschalten selbstverständlich sofort erreichbar ist... das ist sie aber nicht. Wir müssen nur einmal daran denken, dass wir mit unserem Laptop auch mal nicht zu Hause am Schreibtisch oder auf der Couch sitzen, sondern mit einem fremden Netzwerk verbunden sind, z.B. bei Mc Cafe oder irgendwo auf Reise über einen offenen Hotspot in der City. Eine Netzwerkverbindung ist erfolgreich hergestellt, wir können im Internet surfen, aber von dort sind unsere heimischen Netzwerkfreigaben trotzdem ganz bestimmt nicht erreichbar. Der Mount-Versuch durch die fstab-Bearbeitung wird in jedem Fall fehlschlagen.
Darüber hinaus sollten wir uns bewusst machen, dass auch zuhause eine erfolgreich hergestellte Netzwerkverbindung nicht sofort mit dem Betätigen des Einschaltknopfes verfügbar ist. Wenn das Betriebssystem gestartet ist, muss vom Kernel erstmal das Netzwerkinterface (die Hardware) identifiziert und initialisiert werden, die passenden Kernel-Module zur Hardware-Unterstützung müssen geladen werden, die Netzwerksoftware muss geladen und gestartet werden, der Network-Stack versucht dann eine Verbindung zu einem Netzwerk herzustellen und muss bei Erfolg darauf warten eine IP-Adresse vom DHCP-Server zu bekommen. Und irgendwann mit Zuweisen der erhaltenen IP-Adresse an das eigene Netzwerkinterface steht der Kommunikation mit anderen Geräten im Netzwerk oder dem Zugang zum Internet schließlich nichts mehr im Wege. Problematisch wird es nur, wenn die fstab-Bearbeitung schon vorher versucht hat, die Netzwerkfreigaben zu verbinden, was ja in dem Fall, wenn das Netzwerk selber noch gar nicht vollständig verbunden ist, vorhersagbar gar nicht gelingen kann
Also ist das hier bei allen in dieser Dokumentation noch folgenden Lösungsschritten sogar die zentrale Frage. Oder anders gesagt, für die im Netzwerk liegenden Speicher die wichtigste Frage überhaupt, ganz besonders dann, wenn es sich um mobile Geräte mit wechselnden Einsatzorten handelt. Denn wenn der Mountversuch stattfinden würde, bevor z.B. das Netzwerk im Betriebssystem gestartet und auch vollständig verbunden ist oder bevor eine Verbindung zu einem bestimmten entfernten NAS oder zum Samba-Server hergestellt wurde, werden die Mounts immer fehlschlagen - was bei alleiniger Verwendung der fstab fast nichts ungewöhnliches ist... aber gerade deswegen ist es auch einigermaßen unerfreulich. Allerdings darf man jetzt hierbei nicht den Fehler begehen und dem Betriebssystem einen Fehler oder Versagen unterstellen.... nein, beides trifft nicht zu. Dieses Problem ist schlicht und einfach ein Effekt von parallel durchgeführten Starts und Services, was prinzipiell sogar eine wünschenswerte Eigenschaft eines Init-Systems ist.
Unter systemd, dem aktuellen und modernen Init-System der meisten Linux-Distributionen gehören solche Fehlversuche meiner Meinung nach fast sogar zur Normalität, dann besonders forciert auftretend, wenn ein Verbindungsaufbau durch mangelhafte Verbindungsqualität schleppend oder verzögert abläuft oder gar vollständig fehlschlägt. Dabei ist das hier tatsächlich nur ein zeitliches Abstimmungsproblem der Prozesse. Sehr oft wird dann von hilfsbereiten und erfahreneren Anwendern zu Autofs oder entsprechenden Automount-Service-Units geraten, die das Problem über einen Workaround quasi umschiffen, so das der Zeitpunkt des Mounts von der Bootphase losgelöst wird und erst zu einem Zeitpunkt stattfindet, wenn sich der User angemeldet hat. Im Regelfall kann man dann davon ausgehen, dass das Netzwerk erfolgreich verbunden ist. Allerdings bedeutet das noch lange nicht, dass der entsprechende Server auch wirklich erreichbar ist. Denn, wenn ich mit meinem Laptop irgendwo auf der Welt unterwegs bin, ist von meinem NAS zuhause weit und breit nichts zu sehen, und genau das wird natürlich wieder nicht geprüft. Ein solche spezielle Situation ist auch mit systemd-automounts kaum zu lösen. Diese Umstände oder auch Mankos kann man allerdings nicht systemd anlasten, es ist einfach ein Effekt von parallel erfolgten Starts von Diensten und Services und der Unkenntnis von systemd, welche Absichten ich im Moment mit meinem Laptop gerade habe. Eins ist allerdings gewiss ... mein Wissen darum, was ich ganz bestimmt nicht will: und zwar das eine mangelhafte Abstimmung der Komponenten untereinander auf meinem System zu nervenden Wartezeiten oder Störungen führt.
Darüber hinaus ist festzustellen, dass netzwerkabhängige Fremdressourcen wie ein NAS oder der Samba-Server immer nachträglich vom User oder Admin des Rechners einem installierten Betriebssystem manuell hinzugefügt wurden. Also hat man als Admin und verantwortlicher Customizer des Systems auch die Aufgabe dafür zu sorgen, dass die für die eigenen Änderungen erforderlichen Abhängigkeiten tatsächlich erfüllt sind. Oder man plant seine Änderungen so in den Systemstart ein (die zuvor erwähnten Automounts), dass das System die Abhängigkeiten erfüllt hat. Allerdings ist das bei einer entfernten Ressource leider nicht ganz so einfach, weil eben der aktuelle Zustand dieser entfernten Ressource (das NAS einer anderen Hardware) eben nicht selbstverständlich im startenden eigenen Rechner resp. Betriebssystem bekannt ist.
Für die Prüfung, ob mein Samba-Server überhaupt verfügbar ist, verwende ich das folgende Script, welches über eine Service-Unit bei Systemstart gestartet wird. Zur Anpassung auf die eigenen Gegebenheiten ist nur die in der Service-Unit rot markierte IP-Adresse auf die Adresse des eigenen Servers oder NAS zu ändern. Das Script überpüft mit Pings etwa anderthalb Minuten lang, ob der Server antwortet. Antwortet er, können die Mounts durchgeführt werden. Antwortet er nicht, wird der Versuch abgebrochen und die Service-Unit endet mit einem failed-state. Alle Mount-Service-Units sind vom Ergebnis dieses Scripts abhängig und mounten 'ihre' Freigabe nur, wenn der Server erreichbar ist. |
/usr/local/bin/serverctl | Rechte-Einstellung: root:root 755 |
#!/bin/bash #============================================================================================= # Description : Check if given server is reachable # # Script-Name : serverctl # Version : 2.0 # Date : 02.12.2018 # Written by : TomL*thlu.de # Licence : GNU GPL3 #=============================================================================================
[ -z "$1" ] && Server="8.8.8.8" || Server=$1 echo "active/running Server=$Server" | systemd-cat -t "thlu:$(basename $0)" -p "info"
timeout=85 Diff=0 HomeNetIsConnect=-1
Start=$(date +%s);
while [ true ]; do /bin/ping -c1 -W1 -q $Server &>/dev/null HomeNetIsConnect=$?
[ $HomeNetIsConnect -eq 0 ] && break /bin/sleep 0.5
End=$(date +%s); Diff=$((End-Start)) [[ Diff -gt timeout ]] && break done
rc=0 if [[ $HomeNetIsConnect -eq 0 ]]; then echo "Host $Server is reachable! (RC:$HomeNetIsConnect, after $Diff Seconds wait)" | systemd-cat -t "thlu:$(basename $0)" -p "info" else echo "Host $Server is not reachable! (RC:$HomeNetIsConnect, after $Diff Seconds wait)" | systemd-cat -t "thlu:$(basename $0)" -p "err" rc=1 fi
echo "Successful terminated with exitcode=$rc" | systemd-cat -t "thlu:$(basename $0)" -p "info" exit $rc #============================================================================================= #EOF | |
/etc/systemd/system/serverctl.service | Rechte-Einstellung: root:root 644 |
[Unit] Description=thlu:serverctl.service: Waiting for Network or Server to be up After=network.target
[Service] Type=oneshot RemainAfterExit=yes TimeoutStartSec=95 ExecStartPre=/usr/local/bin/serverctl 172.1.1.2 ExecStart=/bin/systemctl start network-is-connect.service ExecStop=/bin/systemctl stop network-is-connect.service
[Install] WantedBy=multi-user.target | |
/etc/systemd/system/network-is-connect.service | Rechte-Einstellung: root:root 644 |
[Unit] Description=thlu:network-is-connect.service: Starts after Network is connected or before disconnected
[Service] Type=oneshot RemainAfterExit=yes
ExecStart=/bin/true ExecStop=/bin/true |
Für den erwünschten automatischen Start des Scripts beim Hochfahren des Rechners ist die Service-Unit einmalig zu aktivieren. Wie in meinen anderen Artikeln ebenfalls üblich, wenn es sich um echte administrative Arbeiten am System handelt, sind diese Arbeiten nicht mit root-Rechten, sondern durch root selber durchzuführen. Und wie üblich gehe ich deshalb nicht auf 'sudo' ein oder beziehe das in mein Vorgehensweise ein.... 'sudo' auf einem Enduser-Desktop-PC ist für mich zweifelsfrei ein die System-Sicherheit gefährdendes NoGo.
$ su -
# cd /etc/systemd/system
# systemctl start serverctl.service
Wir warten ein paar Sekunden und kontrollieren sofort, ob das Script erfolgreich seinen Job verrichtet hat:
# journalctl -b | grep serverctl
Nov 28 15:08:48 thomaspc systemd[1]: Starting thlu:serverctl.service: Waiting for Network or Server to be up...
Nov 28 15:08:48 thomaspc thlu:serverctl[2116]: active/running Server=172.1.1.2
Nov 28 15:08:53 thomaspc thlu:serverctl[2447]: Host 172.1.1.2 is reachable! (RC:0, after 5 Seconds wait)
Nov 28 15:08:53 thomaspc thlu:serverctl[2450]: Successful terminated with exitcode=0
Nov 28 15:08:53 thomaspc systemd[1]: Started thlu:serverctl.service: Waiting for Network or Server to be up.
# systemctl status serverctl.service
● serverctl.service - thlu:serverctl.service: Waiting for Network or Server to be up
Loaded: loaded (/etc/systemd/system/serverctl.service; enabled; vendor preset: enabled)
Active: active (exited) since Wed 2018-11-28 15:08:53 CET; 1h 24min ago
::::
# systemctl status network-is-connect.service
● network-is-connect.service - thlu:network-is-connect.service: Starts after Network is connected or before disconnected
Loaded: loaded (/etc/systemd/system/network-is-connect.service; static; vendor preset: enabled)
Active: active (exited) since Wed 2018-11-28 15:08:53 CET; 1h 24min ago
::::
Wofür ist die network-is-connect.service? Am besten ist diese Serve-Unit im übertragenen Sinne mit Signal-Fahne beschrieben, also so etwas wie eine Flagge ... die allerdings ansonsten keine besondere Aufgabe hat. Ist die Flagge gehisst (Unit=active), ist das vorgegebene Netzwerk verbunden, sonst nicht. Man kann diese Unit auch nicht als Dependency-Unit verwenden, weil sie systemisch eigentlich nicht bekannt ist. Ich verwende diese Unit an besonderen Stellen mit dem Befehl systemctl is-active network-is-connect.service zur Status-Abfrage für meine Netzwerk-Verbindung. Na ja, ist eine einfache Spielerei, nichts wirklich wichtiges.
Als letztes und nur dann, wenn beim Testen keine Fehler aufgetreten sind, ist die Service-Unit jetzt noch einmalig zu aktivieren:
# systemctl enable serverctl.service
Alle hier in dieser Beschreibung angelegten bzw. anzulegenden Dateien können mit dem dieser Beschreibung entsprechenden Inhalt unter der folgenden Adresse runtergeladen werden. Wenn die im Tar-File enthaltenen Dateien in die späteren Original-Verzeichnisse kopiert werden, um sie dort manuell anzupassen, müssen unbedingt auch die Rechte-Einstellungen gemäß dieser Anleitung kontrolliert und ggf. nachbearbeitet werden! Im Übrigen ist es nicht unmöglich, dass die Beispiele hier in der Anleitung weniger aktuell sind, als die im Tar-File enthaltenen Dateien. Deswegen empfehle ich unbedingt, nur die Beispieldateien aus dem Tar-File zu verwenden. |
|
Problem 2: Mount-Units mit Abhängigkeit zur Server-Verfügbarkeit als Ersatz für unpräzise fstab-Einstellungen
Mit der Verfügbarkeits-Prüfung des Remote-Servers durch das zuvor beschriebene serverctl ist eine entscheidende Grundlage zur Lösung des Problems erstellt, dass Mounts in der Bootphase ewig (bis zum systemd-Timeout) hängen bleiben und schlimmstenfalls sogar den Start von Diensten und Services in der Bootphase blockieren, weil der Server nicht verfügbar ist. Hier schließt sich nun der nächste Schritt mit der Entscheidung an, für die Remote-Mounts gar nicht mehr die fstab zu nutzen, sondern direkt mount-Units einzurichten. Der Hintergrund dafür, warum das sinnvoll ist, ist einfach erklärt: systemd erzeugt aus den fstab-Einträgen sowieso virtuelle Mount-Units. Was spricht also dagegen, gleich eigene Mount-Units zu erstellen, die zudem auch noch optimiert eigene Anforderungen erfüllen, anstatt das Geschäft einem Unit-Generator zu überlassen, der das nach Schema-F tut? Gar nichts spricht dagegen, das ist sogar auf jeden Fall die bessere Alternative.
Hier folgend ist eine Beispiel-Mount-Unit beschrieben, die in Abhängigkeit von der Verfügbarkeit des Servers die Netzwerk-Ressource //172.1.1.2/SSD in das lokale Verzeichnis /media/SSD mountet:
/etc/systemd/system/media-SSD.mount | Rechte-Einstellung: root:root 644 |
[Unit]
Description=thlu:Mount Network-Drives
ConditionPathExists=/media/SSD
Options=username=thomas,password=meinpassword,rw,nosuid,nodev,noexec,async
Welche Besonderheiten hat diese Unit?
Requires=serverctl.service Conflicts=shutdown.target | 1. Verlangt, dass serverctl.service ohne Fehler aktiviert wurde (Server ist also verfügbar) 2. Wird in der Bootphase NACH serverctl.service aktiviert und dadurch im Poweroff VOR serverctl.service 3. Sobald shutdown.target angezogen wird, wird diese mount.unit beendet |
Mountpoint muss vorhanden sein, fehlender MP führt zum Abbruch | |
media-SSD.mount <> Where=/media/SSD | Achtung: Durch systemd vorgegebene Namenskonvention! Der Name dieser Mount-Unit steht in unmittelbarer Verbindung zum Mountpoint. Das heisst, aus dem Namen einer Mount-Unit kann immer der dazugehörige Moint-Point abgeleitet werden. Nach dem gleichem Prinzip dieser Namenskonvention werden auch die Namen für die autogenerated Units aus den fstab-Einträgen maschinell generiert. Damit ist es bei Wartungsarbeiten deutlich einfacher, einem Moint-Point einer Mount-Unit zuzuordnen. Ansonsten sieht man vielleicht den Mount-Point und muss sich dann für den Stop-Befehl der Unit fragen "Wie heisst denn nun das 'Dingen', was diesen Mount durchgeführt hat?" Wegen dieser Regel besteht nun die elegante Möglichkeit einfach die Mounts über /proc/mounts auswerten und darüber automatisch immer die jeweils passende namensgleiche Mount-Unit zu finden, ohne vorher wissen zu müssen, welche Units es überhaupt gibt, ob die aktiv sind oder nicht, und wie die Unit für einen bestimmten Mount-Point heisst. Gäbe es da nicht diese Restriktion, wüsstest man nicht, mit welcher Unit dieser Mount-Point erstellt wurde und müsste für jeden Mount-Point manuell suchen. Aber gerade wegen dieser Regel kann man alles auch generisch abhandeln, ohne sich eigene Tabellen zum Nachlesen anlegen zu müssen und ohne sich zu merken, welche Mounts habe ich bei systemstart überhaupt geöffnet. Das ist beispielsweise dann wichtig, wenn man userbezogene Mounts hat, die je nach Anmeldung wechseln. |
nosuid,nodev,noexec | Aus Sicherheitsgründen sind diese Verbote natürlich immer gesetzt. Ausführbare Programme befinden sich nur auf dem lokalen Rechner, aber nicht auf irgendwelchen Netzwerksressourcen. |
username=thomas,password=meinpassword | Kann natürlich auch in der üblichen Credentials-Datei hinterlegt werden. |
Nach gleichem Schema dieser Beispiel-Mount-Unit kann man nun für seine anderen Netzwerk-Freigaben eigene passende Mount-Units erstellen. Mit solchen Service-Units für die eigenen Remote-Mounts ist das große Problem beseitigt, dass auf einem mobilen Rechner, der sich mal in Reichweite des eigenen Servers befindet und mal nicht, der Start durch unmögliche Mount-Versuche blockiert wird, weil das Netzwerk gar nicht aktiviert ist oder wenn man in einem fremden Netz verbunden ist, in dem der Server zuhause nicht erreichbar ist. Die Kombination aus serverctl.service und Mount-Units sorgt meiner Meinung nach in den meisten Fällen für einen fehlerfreien Ablauf bei Boot und Poweroff des Rechners im Zusammenhang mit Mounts.
Natürlich sind eigene Mount-Units nicht nur auf mobilen Rechnern sinnvoll, man kann sie genauso gut auch auf den stationären Desktop-PCs zuhause einrichten. Selbst wenn es sich auf den Rechnern weitestgehend um statisch eingerichtete Mounts handelt, die immer gleichbleibend bei jedem Systemstart durchgeführt werden sollen, halte ich das dennoch für eine ausgesprochen gute Alternative zur traditionellen (um nicht zu sagen "alten") fstab. Timing-Konflikte zwischen fstab-Verarbeitung und Netzverfügbarkeit sind damit auf jeden Fall Vergangenheit.
Wenn schließlich für jede weitere Samba-Freigabe eine eigene Mount-Unit erstellt ist, wird ganz am Ende jede neue Unit einmalig direkt im Terminal sichtbar im Vordergrund gestartet, um sie auf Fehler zu prüfen. Erfolgt keine weitere Ausgabe, ist das ein gutes Zeichen. Und wenn der Blick auf das Ergebnis der Status-Abfrage auch noch zeigt, dass die Unit erfolgreich gestartet ist, kann sie anschließend für alle weiteren künftigen Systemstarts enable'd werden, um bei jedem Einschalten des Rechners die Freigaben automatisch zu verbinden. Aber Achtung, enable'd wird die Unit nur dann, wenn die Statusabfrage keine Fehler angezeigt hat und die Freigabe tatsächlich fehlerlos auf den Mount-Point gemountet wurde. Es ist nicht möglich einen Fehler zu beheben, in dem die Unit einfach aktiviert wird... vor der Aktivierung müssen vorhandene Fehler immer beseitigt werden. Das gilt nicht nur für diese Mount-Unit, sondern für jede Art von systemd-Service-Units.
$ su -
# cd /etc/systemd/system
# systemctl start media-SSD.mount
# systemctl status media-SSD.mount
● media-SSD.mount - /media/SSD
Loaded: loaded (/proc/self/mountinfo)
Active: active (mounted) since Sat 2018-12-08 19:48:38 CET; 2min 50s ago
Where: /media/SSD
What: //172.1.1.2/SSD
# ls /media/SSD
"enable" nur dann, wenn bei den vorherigen Aktionen keine Fehler aufgetreten sind:
# systemctl enable media-SSD.mount
| Zusammenfassung und Zwischenstand: So, an diesem Punkt angekommen gehe ich davon aus, dass mit der Kombination aus Serverctl und Mount-Units vermutlich (ich behaupte das einfach mal) 99 von 100 privaten Samba-, NFS- oder NAS-Anwendern ihre durch mangelnde Abstimmung bei der fstab-Bearbeitung in der Boot-Phase des Rechners wiederholt verursachten Schwierigkeiten lösen konnten. Probleme, weil z.B. auf Reise unser Heimnetzwerk gar nicht erreichbar ist. Weil ein Rechner (vielleicht ein Raspberry PI) etwas länger für die LAN-Verbindung braucht. Oder weil das WLAN durch Betonwände hakelt. Also einfach nur deshalb, weil der Mount-Versuch durch die fstab-Bearbeitung stattfindet, obwohl das Netzwerk noch gar nicht bereit war, was dann zwangsläufig fehlgeschlagene Mount-Versuche zur Folge hatte. Man liest das immer wieder in den Foren, wenn Leute ihre Probleme schildern "...manuell im Terminal klappt es perfekt, automatisch beim Start dann nicht.... wo ist der Fehler?". Hier haben wir nun eine Lösung. Was auch immer der Grund für Mount-Probleme durch die Reihenfolge bei der Serialisierung von Diensten oder Programmen eines regulären Starts unter eigentlich immer den selben Bedingungen war... das sollte eigentlich hiermit gelöst sein. | |
| Hier ist jetzt mit einem kleinen Script (serverctl) und Mount-Units für die Remote-Mounts eine funktionierende Lösung erstellt, die zusammen die mangelhafte zeitliche Abstimung bei der fstab-Bearbeitung für statische und quasi-persistente Netzwerk-Mount beseitigen - eine passable und ausreichende Lösung für die meisten Linux-Heimnetzwerk-Anwender. |
Aber es gibt noch weitere ungelöste Probleme, die uns durchaus auch mal stören oder nerven könnten, und zwar nicht beim Start, sondern beim Runterfahren des Rechners. Wenn z.B. der Shutdown unseres Rechners wiederholt in 90-Sec-Stop-Jobs hängt und der Shutdown einfach nicht durchgeführt wird oder scheinbar ewig lange benötigt. Das ist sogar ein recht einfach reproduzierbares und ziemlich oft auftretendes Problem, welches aber dennoch nicht alle Debian-Anwender betrifft. Hierbei geht es um die Kombination von Remote-Mounts über reine WLAN-Verbindungen. Wer über eine kabelgebundene Verbindung am Netzwerk angeschlossen ist, wird dieses Problem möglicherweise nicht kennen, WLAN-Benutzer aber leider gar nicht mal so selten. Mit diesem Problem befasst sich das nächste Kapitel.
|
Problem 3: Vermeiden von 90-Sec-Stop-Jobs beim Shutdown des Computers
Das ist ein mir seit Jahren bekanntes ständiges Problem im Zusammenhang mit dem Network-Manager (NWM) und WLAN-Verbindungen. Aber was passiert da überhaupt...?...tja, das ist einfach erklärt: Der problemrelevante Zusammenhang entsteht bei über eine WLAN-Verbindung hergestellte Netzwerk-Mounts. Sobald der Anwender nun den Shutdown (bei weiterhin offenen Mounts) seines Systems veranlasst, wird von systemd das shutdown.target angezogen. Dieses Target veranlasst alle weiteren notwendigen Arbeiten, um das System ordnungsgemäß und möglichst ohne Datenverlust herunterzufahren. Unter anderem werden dabei alle laufenden Dienste aufgefordert, sich ordentlich zu beenden - so auch der NWM. Mit anderem Worten, das komplette System sollte eigentlich auf geordnete Art und Weise terminiert, beendet, abgebrochen werden. Sogar eigenen von mir selbst erstellten Service-Units wird die Möglichkeit eingeräumt, unmittelbar auf das gestartete shutdown.target zu reagieren. Man sieht das in der Mount-Unit aus dem vorherigen Kapitel, welche das Statement Conflicts=shutdown.target enthält. Dieses Statement führt dazu, dass sich eine laufende Service-Unit, sofern sie dieses Statement enthält, als Konfliktreaktion auf den beginnenden Shutdown-Prozess sofort selber ordentlich beendet. Das bedeutet, ein vergessener umount, der dadurch den shutdown möglicherweise bis zum Timeout (90 Sekunden) blockiert, könnte damit eigentlich gar nicht mehr passieren.
Soweit sind das eigentlich die Spielregeln und soweit sollten diese auch allen bekannt sein... Spielregeln, an die sich auch eigentlich alle Komponenten halten müssten... 'eigentlich'.... denn leider werden diese Spielregeln im Zusammenwirken des Networkmanagers (NWM) mit dem für WLAN-Verbindungen verantwortlichen Tool wpasupplicant leider überhaupt nicht zuverlässig beachtet. Bisher konnte ich das Problem fast beliebig auf meinem Laptop mit offenen WLAN-Mounts reproduzieren. Sobald der Shutdown-Prozess über das Start-Menü des Desktop-Environments initiiert wurde, beendet der NWM eine laufende WLAN-Verbindung, in dem einfach das WLAN-Interface resp. wpasupplicant geschlossen wird. Dabei wird nicht beachtet, ob über dieses WLAN-NIC vielleicht noch laufende Prozesse aktiv sind, wie zum Beispiel ein via WLAN verbundenes NAS mit offenen Mounts. Die Verbindung wird einfach gekappt, ohne den betroffenen Prozessen die Möglichkeit zu geben, sich ordnungsgemäß zu beenden und ohne darauf zu warten, dass diese Prozesse im Shutdown-Verlauf sowieso beendet werden. Aber genau dieses harte Kappen der Verbindung führt folgerichtig dann dazu, dass der Linuxinterne mount-helper bis zum Erreichen des Timeouts hartnäckig versucht, seine offenen Mounts ordentlich zu schließen - denn auch dieser wird ja von systemd aufgefordert, sich und seine Ressourcen zu beenden. Irgendwann ist systemd es dann leid und terminiert nach diesen Stop-Jobs mit einem harten Kill, um den Shutdown nach nervenden 90 Sekunden dann noch abschließen und den Rechner ausschalten zu können. Dieses Problem kann also theoretisch auf jedem Laptop auftreten, der via WLAN mit dem Netzwerk verbunden ist und über diese Verbindung durch mounts auf Netzwerkressourcen zugreift.
Solange es sich also um einen regulär durchzuführenden Shutdown handelt, kann man diesen unschönen Effekt mit dem folgenden Script vollständig eliminieren. Das Script umountet einfach alle gefundenen Netzwerk-Ressourcen und initiiert erst dann den shutdown, der danach konfliktfrei durchlaufen kann und sehr schnell abgeschlossen ist. Zum Starten des Scripts habe ich mir einen Desktop-Starter mit dem hier nebenstehenden Icon angelegt. |
/usr/local/bin/mountctl | Rechte-Einstellung: root:root 755 |
#!/bin/bash
while read line
do
/bin/umount $line -f 2>&1
done < <(/bin/cat /proc/mounts | grep // | awk -F ' ' '{ print $1 }')
/bin/systemctl poweroff -i >/dev/null 2>&1
exit 0
~/Schreibtisch/mountctl_poweroff_helper.desktop | Rechte-Einstellung: $user:$user 644 |
[Desktop Entry]
Type=Application
Exec=/usr/bin/pkexec /usr/local/bin/mountctl poweroff
Icon=/usr/local/share/Icons/poweroff.png
Terminal=true
Categories=Utility;
Name=Mountctl-Helper
Comment=Helper for Umount remote-shares before lan is disconnect
Name[de_DE]=Poweroff
Und weil dieser Job natürlich root-Rechte erfordert, ist dafür auch die entsprechende Berechtigung über eine Policy-Regel zu erstellen. Damit sind alle User berechtigt, vor dem Shutdown einen umount für verbundene Netzwerk-Laufwerke ohne weitere Password-Abfrage durchzuführen:
/usr/share/polkit-1/actions/LocalExtPermissions.policy | Rechte-Einstellung: root:root 644 |
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
"http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
<policyconfig>
<action id="LocalExtPerms.mountctl">
<defaults>
<allow_any>yes</allow_any>
<allow_inactive>yes</allow_inactive>
<allow_active>yes</allow_active>
</defaults>
<annotate key="org.freedesktop.policykit.exec.path">/usr/local/bin/mountctl</annotate>
</action>
</policyconfig>
Man muss hier zweifelsfrei zugeben, dass das nicht mehr als nur ein Workaround ist, nicht um ein bestehendes Problem zu lösen, sondern um es einfach zu umgehen. Etwas boshaft ausgedrückt kann man es fast auch als Dirty Hack bezeichnen, den man nicht brauchen würde, wenn die Interprozess-Kommunikation resp. die Abstimmung untereinander passen würde. Und mit diesem Script bzw. mit dieser Vorgehensweise ist auch nicht das Problem gelöst, dass der User selber immer noch über die grafischen Menü-Dialoge des NWM die WLAN-Verbindung trotz offener Netzwerk-Mounts ganz einfach manuell trennen kann. In dem Fall entsteht eine vorhersehbare Baustelle, denn der mount-helper ist jetzt nicht mehr imstande, die offenen Mounts zu schließen, zumal er gar keine Kenntnis davon hat, dass er sie überhaupt schließen soll. Ihm sind im wahrsten Sinne des Wortes mitten im Sprint die Beine weggezogen worden. Also, im Gegensatz zum ordentlichen Beenden wird er sogar ständig weiter versuchen, die Mounts wieder zurück ins Leben zu bringen. Das kann bei Aufruf eines Dateimanagers oder des Shutdowns sofort zu einem vorübergehenden Stillstand des Systems führen. Tja, an der Stelle muss man also resümieren: Selbstverursachte Probleme.... und die bestehenden Werkzeuge können das meiner Meinung nach derzeit nicht zufriedenstellend handhaben. Wenn man selber Hand anlegen will und bewusst manuell die WLAN-Verbindung trennen möchte, so müssen auch vorher bewusst manuell die Remote-Mounts getrennt werden, um Probleme zu vermeiden.
Es ist, wie es ist... aber wenn man die Probleme einmal verstanden hat, kann man auch damit umgehen.
|
Problem 4: Einrichten von benutzer-bezogenen Mounts, damit user-individuelle Samba-Berechtigungen auch wirksam sind
In diesem Teil meiner Beschreibung erwartet uns die anspruchsvollste Problemstellung. Aber am Ende erwartet uns auch eine wirklich anspruchsvolle Lösung, die uns mehr Schutz, mehr Sicherheit, mehr Transparenz, mehr Stabilität in unser Netzwerk bringt. Es ist eine Lösung, die ich für meinen Samba-Server konzipiert habe. Bis auf den Teil der [homes]-Sektion (s.u.) wird das auch auf NFS-Servern oder anderen NAS-Geräten funktionieren.
Für die Lösung sind die folgenden Dateien notwendig, von denen die meisten nur kopiert oder repliziert werden müssen. Anzupassen sind lediglich spezielle Mount-Parameter in den Units sowie an 2 Stellen die Server-IP-Adresse
/usr/local/bin/serverctl | Programm zur Prüfung, ob der Server verfügbar ist. Durch Service-Unit gestartet. | - |
/usr/local/bin/mountctl | Programm zur Prozess-Steuerung bei user- individuellen Mount und Umount. Durch Service-Unit gestartet. | - |
/usr/local/bin/sessionctl | Programm zum User-Login-Logout-Handling. Durch PAM-Services gestartet | - |
/etc/systemd/system/serverctl.service | Service-Unit zum Start des Programms serverctl | Enabled = ja |
/etc/systemd/system/suspend-resume.service | Wiederherstellung der Mounts nach Suspend | Enabled = ja |
/etc/systemd/system/mountctl@.service | Service-Unit zum Start des Programms mountctl | Enabled = nein |
/etc/systemd/system/network-is-connect.service | View-Flag, Unit is-active = Server ist verfügbar | Enabled = nein |
/etc/systemd/system/media-SSD@.service /etc/systemd/system/media-???@.service | n instantiierte Service-Units zum Mounten der Freigaben. Je 1 Unit für 1 Mountpoint. | Enabled = nein |
/etc/systemd/system/SHome@.service | 1 instantiierte Service-Unit zum individuellen Mounten des persönlichen servergespeicherten Daten-Verzeichnisses eines Anwenders in sein lokales Client-PC-Homedir | Enabled = nein |
/etc/pam.d/common-session | Startet das Programm sessionctl nach erfolgter Anmeldung eines Users | - |
/usr/share/polkit-1/actions/LocalExtPermissions.policy | Berechtigung für User, das Programm mountctl mit erweiterten Rechten auszuführen | - |
/home/?/.bash_aliases | Alias-Befehle für CLI.... sofern einzelne User das überhaupt benötigen (*) | - |
/home/?/Schreibtisch/mountctl_poweroff_helper.desktop /home/?/Schreibtisch/mountctl_reboot_helper.desktop /home/?/Schreibtisch/mountctl_suspend_helper.desktop | Desktop-Starter für Poweroff, Suspend und Reboot (**) | - |
Anmerkungen:
*) Normale User benötigen das normalerweise nicht
**) Bei kabelverbundenen PCs sollten für Poweroff und Reboot auch die normalen Menü-Aktionen des Desktop-Environments problemlos funktionieren. Bei Suspend wird gleichzeitig jedoch auch das Netzwerk getrennt, vermutlich wird dafür aber vorher kein geregelter umount durchgeführt, insofern ist das Verhalten nach dem Restart nicht genau vorhersagbar. Es handelt sich hier durch die Einbindung von mountctl also um eine vorbeugend konfliktvermeidende Aktion. Das gilt gleichermaßen für alle 3 mountctl-helper.
Auf gehts.....
In diesem Kapitel soll das Problem gelöst werden, dass nicht umfassend und vorauseilend beim Systemstart unter Verwendung einer einzigen Admin-Berechtigung alle möglichen Mounts durchgeführt werden müssen, ohne zu wissen, ob sich die für einen Mountpoint bestimmten oder berechtigten Benutzer an diesem System in dieser Rechner-Laufzeit überhaupt anmelden. Üblicherweise und allgemeine Praxis ist, dass alle Mounts bei Systemstart über die Admin-Credentials des Systemadministrators erfolgen, auf unseren Rechnern wären das meine Credentials. Im Gegensatz zu individuellen User-Rechten würde der Samba-Server dabei niemals den tatsächlich am Client-PC angemeldeten User sehen, sondern immer nur mich. Denn bei Verwendung meiner Credentials wird Samba immer glauben, ich wäre auch der aktuelle Benutzer, ohne für den tatsächlichen arbeitenden User individuelle Berechtigungen anwenden zu können. Der negative Begleiteffekt ist, es werden auf dem Server Samba-Seitig zwangsläufig immer meine höheren Admin-Rechte beim Speichern/Ändern/Löschen von Dateien angewendet.
Mit anderen Worten, das Ziel dieses Kapitels ist, dass nach der Anmeldung eines Users nur die Mounts geöffnet werden, für die der Benutzer entsprechende Rechte hat. Und das infolgedessen die Verwendung dieses Mountpoints auch wirklich unter den Beschränkungen seiner persönlichen Samba-Berechtigungen erfolgt.
Aus dieser Vorgabe resultiert also eine ganz einfache Forderung: Der Mount von möglichen Netzwerks-Ressourcen z.B. eines Samba-Servers darf nicht automatisch beim Hochfahren des Rechners erfolgen, sondern erst dann, wenn sich ein User namentlich und mit Password im Desktop-Environment angemeldet hat. Und natürlich nur dann, wenn der Server zur Verfügung steht. Außerdem sollen auch nur die Ressourcen gemountet werden, die der User auch wirklich verwenden darf und soll. Letztlich ist das auch ein Sicherheitsfeature... oder ein Aspekt, der zumindest einen positiven Einfluss auf die Daten-Sicherheit hat, denn in Zeiten von Ransomware sollte es wirklich nicht sein, dass dem User immer alles von allen/allem zur Verfügung steht. Das wäre im Fall der Fälle die Garantie für den größtmöglichen Schaden bezogen auf Datenverlust. Speziell für die Anforderung "nur was der User darf und können soll" ist nun eine besondere Vorgehensweise notwendig. Mein eigentlicher Lösungsansatz basiert hierbei auf instantiierte Service-Units. Das bedeutet, für einen bestimmten User werden speziell für seine UID eigene Mount-Instanzen erzeugt, bei denen dann die tatsächlichen Rechte dieses Users zugrunde gelegt werden.
Warum sind es hier Service-Units und weiter oben sind es Mount-Units? Tja, hier besteht aufgrund anderer Anforderungen ein gravierender Unterschied zwischen diesen zwei Problemlösungen. Die Mount-Units oben sind quasi statisch und explizit gültig, die Service-Units hingegen sind variabel einsetzbare Templates, die tatsächlich eine personifizierte Instanz für die Mountpoints darstellen. Bedauerlicherweise sind in der aktuellen Debian-Stable-Implementierung von systemd keine instantiierten Mount-Units möglich, deswegen verwende ich hier normale Service-Units. Ich halte das aber nicht für ein Problem oder für nachteilig, im Gegenteil... es ist ein vollständig systemd-Konformer Lösungsansatz.
Eine Besonderheit in den folgenden Mount-Service-Units ist der in Zeile 1 stehende Kommentar: #mountctlgroup=thomas. Dieser Eintrag hat eine dreifache Bedeutung:
1. Für den systemd-Controller ist es wegen dem Zeichen "#" eine Kommentarzeile, die nicht beachtet wird. 2. Für das Programm mountctl ist der Text mountctlgroup ein Identifikations-Kennzeichen, um die betroffenen Service-Units zu identifizieren. Nur Service-Units mit diesem Kennzeichen werden ausgewertet. 3. Im Programm wird der Eintrag hinter mountctlgroup= zur Prüfung verwendet, ob der sich jetzt anmeldende User in einer der hier angegebenen Gruppe befindet. Nur wenn er in der Gruppe enthalten ist, wird diese Freigabe gemountet. Hier in diesem Beispiel muss sich der anmeldende User in der Gruppe "thomas" befinden, damit der Mount durchgeführt wird. Es sind auch solche Einträge möglich, die mehr als eine Gruppe zugrunde zulegen: #mountctlgroup=thomas sambauser mp3user |
Der Eintrag mountctlgroup hat eine andere Zielsetzung und eine andere Auswirkung als beispielsweise die für systemd-Service-Units vorgesehenen Parameter ConditionUser und ConditionGroup. Mit diesen Parametern wird beschränkt, dass die Service-Unit nur unter der UID und GID der hier eingetragenen Parameter aktiviert werden kann. Die hier in diesem Artikel beschriebenen Service-Units werden aber immer durch root und unter der UID 0 gestartet. Hier geht es also nicht darum, unter welcher UID/GID laufen die Prozesse der Service-Units, sondern um die Frage, ob der User berechtigt ist, diesen Mount durchzuführen.
4.1 Service-Units für allgemeine Mounts
Schauen wir nun ein wenig genauer auf die Units und betrachten jeweils die Zielsetzung. Die SSD-Unit und auch die Multimedia-Unit betrachte ich beide als Admin-Shares. Das bedeutet, damit ist ein Zugriff außerhalb der anderen beschränkenden Freigaben direkt auf die SSD oder ein höheres Verzeichnis möglich. Mit solchen administrativen Zugängen haben die normalen Anwender im Regelfall nichts zu tun, also wird der Mount auch nur durchgeführt, wenn der sich anmeldende User in der Linux-Gruppe thomas enthalten ist ... und das kann natürlich immer nur ich selber sein. Die weiteren Units sind allgemeine Freigaben für mehrere Anwender, der Zugriff ist hierbei auf die Mitglieder die Linux-Gruppe sambauser beschränkt. In dieser Gruppe sind die Familienmitglieder enthalten. Ansonsten ist der ablaufende Vorgang identisch. Alle rot markierten Einträge können geändert werden bzw. müssen zur Anpassung an die lokalen Gegebenheit geändert werden.
Hier darf man allerdings auf keinen Fall vergessen, dass für diesen personalisierten Ablauf unbedingt in den Homedirs der Benutzer jeweils das persönliche Credentialsfile angelegt sein muss, denn mit genau diesen Zugangsdaten identifiziert sich ja der Anwender gegenüber Samba.... und nur damit kann Samba anschließend individualisierte Benutzer-Rechte anwenden. | |
Für die folgenden Service-Units hier ein kurzer redaktioneller Hinweis: Aufgrund der Länge des Exec-Start-Statements in den folgenden Service-Units musste ich mich entscheiden, einen möglicherweise falsch zu deutenden Zeilenumbruch hinzunehmen, oder mit einer kleineren Schriftart die Eindeutigkeit einer zusammenhängenden Zeile unzweifelhaft herzustellen. Ich habe mich für die kleinere Schriftart entschieden, die in der endgültigen Unit als Textdatei sowieso egalisiert wird. Die Eindeutigkeit der Code-Zeilen war mir hier wichtiger. |
/etc/systemd/system/media-SSD@.service | Rechte-Einstellung: root:root 644 |
#mountctlgroup=thomas
[Unit] Description=thlu:Mount Network-Drives for specified user: %n Requires=serverctl.service After=serverctl.service Conflicts=shutdown.target ConditionPathExists=/media/SSD
[Service] Type=simple RemainAfterExit=yes ExecStart=/bin/mount //172.1.1.2/SSD /media/SSD -t cifs -o credentials=/home/%I/.smbcredentials,vers=3.0,uid=%I,gid=%I,dir_mode=0770,file_mode=0644,rw,noauto,nosuid,nodev,noexec,nouser,async ExecStop=/bin/umount /media/SSD
[Install] WantedBy=multi-user.target | |
/etc/systemd/system/media-Multimedia@.service | Rechte-Einstellung: root:root 644 |
#mountctlgroup=thomas
[Unit] Description=thlu:Mount Network-Drives for specified user: %n Requires=serverctl.service After=serverctl.service Conflicts=shutdown.target ConditionPathExists=/media/Multimedia
[Service] Type=simple RemainAfterExit=yes ExecStart=/bin/mount //172.1.1.2/Multimedia /media/Multimedia -t cifs -o credentials=/home/%I/.smbcredentials,vers=3.0,uid=%I,gid=%I,dir_mode=0770,file_mode=0644,rw,noauto,nosuid,nodev,noexec,nouser,async ExecStop=/bin/umount /media/Multimedia
[Install] WantedBy=multi-user.target | |
/etc/systemd/system/media-Film@.service | |
#mountctlgroup=sambauser
[Unit] Description=thlu:Mount Network-Drives for specified user: %n Requires=serverctl.service After=serverctl.service Conflicts=shutdown.target ConditionPathExists=/media/Film
[Service] Type=simple RemainAfterExit=yes ExecStart=/bin/mount //172.1.1.2/Film /media/Film -t cifs -o credentials=/home/%I/.smbcredentials,vers=3.0,uid=%I,gid=%I,dir_mode=0770,file_mode=0644,rw,noauto,nosuid,nodev,noexec,nouser,async ExecStop=/bin/umount /media/Film
[Install] WantedBy=multi-user.target | |
/etc/systemd/system/media-Musik@.service | |
#mountctlgroup=sambauser
[Unit] Description=thlu:Mount Network-Drives for specified user: %n Requires=serverctl.service After=serverctl.service Conflicts=shutdown.target ConditionPathExists=/media/Musik
[Service] Type=simple RemainAfterExit=yes ExecStart=/bin/mount //172.1.1.2/Musik /media/Musik -t cifs -o credentials=/home/%I/.smbcredentials,vers=3.0,uid=%I,gid=%I,dir_mode=0770,file_mode=0644,rw,noauto,nosuid,nodev,noexec,nouser,async ExecStop=/bin/umount /media/Musik
[Install] WantedBy=multi-user.target | |
usw. für die anderen Shares. |
4.2 Service-Unit für den Mount eines persönlichen Datenverzeichnisses
Die Verwendung eines Samba-Servers und die Anwender-Individuelle Anmeldung an diesen Server eröffnet uns noch eine weitere tolle Möglichkeit, und zwar die Einrichtung eines persönlichen nur dem Anwender gehörenden Datenverzeichnisses. Ein für die Backup-Strategie signifikanter Vorteil liegt darin, dass diese persönlichen Verzeichnisse aber dennoch für alle Anwender an einem zentralen Ort auf dem Samba-Server liegen. Der sofort erkennbare Vorteil ist offensichtlich, weil von diesem zentralen Ort dann mit geringstmöglichen Aufwand ein Backup aller persönlichen Anwender-Daten erstellt werden kann. Klingt kompliziert, ist es aber nicht. Der Schlüssel für diese Funktionalität ist die anwenderbezogene Anmeldung auf dem Samba-Server, wie sie bisher hier realisiert wurde.
Am einfachsten kann man es sich vorstellen, wenn man auf das nebenstehende Bild schaut. Die gezeigte Festplatte ist entweder die interne Festplatte des Samba-Servers oder eine externe Platte, bei mir ist es die interne SSD des Servers, die nach /media/SSD gemountet ist. Eine starre Festlegung gibt es hier nicht, es ist immer die gleiche Funktionalität möglich. In der fstab des Samba-Servers sind u.a. die folgenden Einträge enthalten: UUID=abcxyz /media/SSD ext4 rw,noexec,auto,nouser,async,noatime 0 0
/media/SSD/Multimedia /media/Multimedia none bind /media/SSD/MultiMedia/Film /media/Film none bind /media/SSD/MultiMedia/Musik /media/Musik none bind /media/SSD/MultiMedia/Foto /media/Foto none bind /media/SSD/MultiMedia/Buch /media/Buch none bind
/media/SSD/SHome/thomas /home/thomas/SHome none bind /media/SSD/SHome/silvia /home/silvia/SHome none bind /media/SSD/SHome/manuel /home/manuel/SHome none bind usw. |